timbal 2.2.7__tar.gz → 2.2.8__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 (224) hide show
  1. {timbal-2.2.7 → timbal-2.2.8}/PKG-INFO +1 -1
  2. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/_version.py +2 -2
  3. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/cli_utils.py +17 -0
  4. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/cst_utils.py +71 -0
  5. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/add_edge.py +11 -3
  6. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/add_step.py +24 -7
  7. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/add_tool.py +2 -3
  8. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/remove_edge.py +11 -2
  9. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/set_config.py +2 -3
  10. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/set_param.py +37 -11
  11. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/set_position.py +11 -1
  12. {timbal-2.2.7 → timbal-2.2.8}/.gitignore +0 -0
  13. {timbal-2.2.7 → timbal-2.2.8}/LICENSE +0 -0
  14. {timbal-2.2.7 → timbal-2.2.8}/README.md +0 -0
  15. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/chat-completions.mdx +0 -0
  16. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/create-from-workforce.mdx +0 -0
  17. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/jobs/cancel.mdx +0 -0
  18. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/jobs/get.mdx +0 -0
  19. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/jobs/list.mdx +0 -0
  20. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/jobs/retry.mdx +0 -0
  21. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/link.mdx +0 -0
  22. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/list-context-vars.mdx +0 -0
  23. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/list-policies.mdx +0 -0
  24. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/messages.mdx +0 -0
  25. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/responses.mdx +0 -0
  26. {timbal-2.2.7 → timbal-2.2.8}/docs/api-reference/ace/unlink.mdx +0 -0
  27. {timbal-2.2.7 → timbal-2.2.8}/pyproject.toml +0 -0
  28. {timbal-2.2.7 → timbal-2.2.8}/pyrightconfig.json +0 -0
  29. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/__init__.py +0 -0
  30. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/__init__.py +0 -0
  31. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/__main__.py +0 -0
  32. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/flow.py +0 -0
  33. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/format.py +0 -0
  34. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/model_discovery.py +0 -0
  35. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/test.py +0 -0
  36. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/tool_discovery.py +0 -0
  37. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/__init__.py +0 -0
  38. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/remove_step.py +0 -0
  39. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/codegen/transformers/remove_tool.py +0 -0
  40. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/__init__.py +0 -0
  41. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/base.py +0 -0
  42. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/impl/__init__.py +0 -0
  43. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/impl/anthropic.py +0 -0
  44. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/impl/default.py +0 -0
  45. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/impl/message.py +0 -0
  46. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/impl/openai.py +0 -0
  47. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/impl/string.py +0 -0
  48. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/impl/timbal.py +0 -0
  49. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/collectors/registry.py +0 -0
  50. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/__init__.py +0 -0
  51. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/agent.py +0 -0
  52. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/fallback_model.py +0 -0
  53. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/llm_router.py +0 -0
  54. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/mcp.py +0 -0
  55. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/memory_compaction.py +0 -0
  56. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/models.py +0 -0
  57. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/runnable.py +0 -0
  58. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/skill.py +0 -0
  59. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/test_model.py +0 -0
  60. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/tool.py +0 -0
  61. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/tool_set.py +0 -0
  62. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/core/workflow.py +0 -0
  63. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/errors.py +0 -0
  64. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/__init__.py +0 -0
  65. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/cli.py +0 -0
  66. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/display.py +0 -0
  67. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/fixtures/agent.py +0 -0
  68. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/fixtures/eval_examples.yaml +0 -0
  69. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/fixtures/eval_flow_validators.yaml +0 -0
  70. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/fixtures/eval_negations.yaml +0 -0
  71. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/fixtures/eval_parallel.yaml +0 -0
  72. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/fixtures/eval_subagent.yaml +0 -0
  73. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/fixtures/eval_transforms.yaml +0 -0
  74. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/fixtures/test_invalid_validator.yaml +0 -0
  75. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/models.py +0 -0
  76. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/runner.py +0 -0
  77. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/utils.py +0 -0
  78. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/__init__.py +0 -0
  79. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/base.py +0 -0
  80. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/comparison_base.py +0 -0
  81. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/contains.py +0 -0
  82. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/contains_all.py +0 -0
  83. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/contains_any.py +0 -0
  84. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/context.py +0 -0
  85. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/email.py +0 -0
  86. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/ends_with.py +0 -0
  87. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/eq.py +0 -0
  88. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/gt.py +0 -0
  89. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/gte.py +0 -0
  90. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/json.py +0 -0
  91. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/language.py +0 -0
  92. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/length.py +0 -0
  93. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/llm_base.py +0 -0
  94. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/lt.py +0 -0
  95. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/lte.py +0 -0
  96. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/max_length.py +0 -0
  97. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/min_length.py +0 -0
  98. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/not_null.py +0 -0
  99. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/parallel.py +0 -0
  100. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/pattern.py +0 -0
  101. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/prompt.py +0 -0
  102. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/semantic.py +0 -0
  103. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/seq.py +0 -0
  104. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/starts_with.py +0 -0
  105. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/evals/validators/type.py +0 -0
  106. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/logs.py +0 -0
  107. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/models.yaml +0 -0
  108. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/platform/__init__.py +0 -0
  109. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/platform/integrations.py +0 -0
  110. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/platform/knowledge_bases/__init__.py +0 -0
  111. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/platform/knowledge_bases/query.py +0 -0
  112. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/platform/tool_proxy.py +0 -0
  113. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/platform/types.py +0 -0
  114. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/platform/utils.py +0 -0
  115. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/server/__init__.py +0 -0
  116. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/server/__main__.py +0 -0
  117. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/server/http.py +0 -0
  118. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/server/jobs.py +0 -0
  119. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/server/voice.html +0 -0
  120. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/server/voice.py +0 -0
  121. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/__init__.py +0 -0
  122. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/config.py +0 -0
  123. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/config_loader.py +0 -0
  124. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/context.py +0 -0
  125. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/dependency_analyzer.py +0 -0
  126. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/__init__.py +0 -0
  127. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/exporters/__init__.py +0 -0
  128. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/exporters/otel.py +0 -0
  129. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/providers/__init__.py +0 -0
  130. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/providers/base.py +0 -0
  131. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/providers/in_memory.py +0 -0
  132. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/providers/jsonl.py +0 -0
  133. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/providers/platform.py +0 -0
  134. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/providers/sqlite.py +0 -0
  135. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/span.py +0 -0
  136. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/state/tracing/trace.py +0 -0
  137. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/__init__.py +0 -0
  138. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/_creds.py +0 -0
  139. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/asana.py +0 -0
  140. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/bash.py +0 -0
  141. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/cala.py +0 -0
  142. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/cloudflare.py +0 -0
  143. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/dynamics_business_central.py +0 -0
  144. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/dynamics_sales.py +0 -0
  145. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/edit.py +0 -0
  146. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/elasticsearch.py +0 -0
  147. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/elevenlabs.py +0 -0
  148. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/excel.py +0 -0
  149. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/fal.py +0 -0
  150. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/fathom.py +0 -0
  151. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/firecrawl.py +0 -0
  152. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/gemini_images.py +0 -0
  153. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/gmail.py +0 -0
  154. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_analytics.py +0 -0
  155. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_business.py +0 -0
  156. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_calendar.py +0 -0
  157. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_docs.py +0 -0
  158. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_drive.py +0 -0
  159. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_maps.py +0 -0
  160. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_merchant_center.py +0 -0
  161. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_search_console.py +0 -0
  162. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/google_sheets.py +0 -0
  163. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/happy_scribe.py +0 -0
  164. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/higgsfield.py +0 -0
  165. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/hubspot.py +0 -0
  166. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/interaction.py +0 -0
  167. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/jira.py +0 -0
  168. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/klaviyo.py +0 -0
  169. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/knowledge_base.py +0 -0
  170. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/krea.py +0 -0
  171. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/lancedb.py +0 -0
  172. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/linkedin.py +0 -0
  173. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/mongodb.py +0 -0
  174. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/netsuite.py +0 -0
  175. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/onedrive.py +0 -0
  176. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/outlook.py +0 -0
  177. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/parallel.py +0 -0
  178. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/pinecone.py +0 -0
  179. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/powerbi.py +0 -0
  180. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/quiver_ai.py +0 -0
  181. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/read.py +0 -0
  182. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/replicate.py +0 -0
  183. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/resend.py +0 -0
  184. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/salesforce.py +0 -0
  185. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/scraperapi.py +0 -0
  186. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/sharepoint.py +0 -0
  187. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/shopify.py +0 -0
  188. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/slack.py +0 -0
  189. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/stripe.py +0 -0
  190. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/tavily.py +0 -0
  191. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/web_search.py +0 -0
  192. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/write.py +0 -0
  193. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/xai.py +0 -0
  194. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/zendesk.py +0 -0
  195. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/tools/zoho_crm.py +0 -0
  196. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/__init__.py +0 -0
  197. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/approval.py +0 -0
  198. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/content/__init__.py +0 -0
  199. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/content/base.py +0 -0
  200. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/content/custom.py +0 -0
  201. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/content/file.py +0 -0
  202. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/content/text.py +0 -0
  203. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/content/thinking.py +0 -0
  204. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/content/tool_result.py +0 -0
  205. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/content/tool_use.py +0 -0
  206. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/events/__init__.py +0 -0
  207. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/events/approval.py +0 -0
  208. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/events/base.py +0 -0
  209. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/events/delta.py +0 -0
  210. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/events/interaction.py +0 -0
  211. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/events/output.py +0 -0
  212. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/events/start.py +0 -0
  213. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/file.py +0 -0
  214. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/message.py +0 -0
  215. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/types/run_status.py +0 -0
  216. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/utils/__init__.py +0 -0
  217. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/utils/import_spec.py +0 -0
  218. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/utils/model.py +0 -0
  219. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/utils/net.py +0 -0
  220. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/utils/schema.py +0 -0
  221. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/utils/serialization.py +0 -0
  222. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/voice/__init__.py +0 -0
  223. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/voice/elevenlabs.py +0 -0
  224. {timbal-2.2.7 → timbal-2.2.8}/python/timbal/voice/session.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: timbal
3
- Version: 2.2.7
3
+ Version: 2.2.8
4
4
  Summary: Simple, performant, battle-tested framework for building reliable AI applications
5
5
  Project-URL: Source, https://github.com/timbal-ai/timbal
6
6
  Author-email: Timbal <team@timbal.ai>
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '2.2.7'
22
- __version_tuple__ = version_tuple = (2, 2, 7)
21
+ __version__ = version = '2.2.8'
22
+ __version_tuple__ = version_tuple = (2, 2, 8)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -3,10 +3,27 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import argparse
6
+ import json
6
7
  import sys
7
8
  from pathlib import Path
8
9
 
9
10
 
11
+ def parse_json_arg(raw: str, flag: str, *, hint: str = "") -> object:
12
+ """Parse a CLI argument as JSON, raising a clear ``ValueError`` on failure.
13
+
14
+ ``json.JSONDecodeError`` messages like ``Expecting value: line 1 column 1``
15
+ give no clue that the fix is quoting; this wraps them with the flag name,
16
+ the offending input, and an optional usage hint.
17
+ """
18
+ try:
19
+ return json.loads(raw)
20
+ except json.JSONDecodeError as e:
21
+ message = f"{flag} must be a valid JSON literal (got {raw!r}): {e}."
22
+ if hint:
23
+ message = f"{message} {hint}"
24
+ raise ValueError(message) from e
25
+
26
+
10
27
  def arg_input(value: str) -> str:
11
28
  """argparse ``type`` callable supporting file and stdin redirection.
12
29
 
@@ -190,6 +190,77 @@ def collect_step_names(
190
190
  return var_to_name
191
191
 
192
192
 
193
+ def collect_chained_step_names(
194
+ tree: cst.Module,
195
+ entry_point: str,
196
+ assignments: dict[str, cst.Call],
197
+ ) -> dict[str, str]:
198
+ """Build a step variable → runtime name mapping for chained ``.step()`` calls.
199
+
200
+ Covers steps added in the entry point assignment itself, e.g.
201
+ ``workflow = Workflow(...).step(a).step(b)``. These steps exist in the
202
+ graph but cannot be modified by the standalone-statement transformers
203
+ (set-param, add-edge, remove-edge).
204
+ """
205
+ var_to_name: dict[str, str] = {}
206
+ for stmt in tree.body:
207
+ if not isinstance(stmt, cst.SimpleStatementLine):
208
+ continue
209
+ for item in stmt.body:
210
+ if not isinstance(item, cst.Assign):
211
+ continue
212
+ if not any(
213
+ isinstance(t.target, cst.Name) and t.target.value == entry_point
214
+ for t in item.targets
215
+ ):
216
+ continue
217
+ node = item.value
218
+ while isinstance(node, cst.Call) and isinstance(node.func, cst.Attribute):
219
+ if node.func.attr.value == "step" and node.args:
220
+ first_arg = node.args[0].value
221
+ resolved = resolve_runnable_name(first_arg, assignments)
222
+ if isinstance(first_arg, cst.Name):
223
+ var_to_name[first_arg.value] = resolved if resolved is not None else first_arg.value
224
+ elif resolved is not None:
225
+ var_to_name[resolved] = resolved
226
+ node = node.func.value
227
+ return var_to_name
228
+
229
+
230
+ def require_step(
231
+ ref: str,
232
+ step_names: dict[str, str],
233
+ chained_step_names: dict[str, str] | None = None,
234
+ *,
235
+ kind: str = "Target",
236
+ operation: str,
237
+ ) -> str:
238
+ """Resolve *ref* (a step variable name or runtime name) to the runtime name.
239
+
240
+ ``step_names`` are the steps the operation can address. When *ref* only
241
+ matches ``chained_step_names`` (steps the operation cannot modify), or
242
+ matches nothing, a ``ValueError`` with an actionable message is raised.
243
+ """
244
+ if ref in step_names.values():
245
+ return ref
246
+ if ref in step_names:
247
+ return step_names[ref]
248
+
249
+ chained = chained_step_names or {}
250
+ if ref in chained or ref in chained.values():
251
+ raise ValueError(
252
+ f"{kind} step '{ref}' is added via a chained .step() call, which {operation} "
253
+ f"cannot modify. Rewrite it as a standalone '<workflow>.step(...)' statement first."
254
+ )
255
+
256
+ available = sorted(set(step_names.values()) | set(chained.values()))
257
+ if available:
258
+ raise ValueError(
259
+ f"{kind} step '{ref}' not found in workflow. Available steps: {', '.join(available)}."
260
+ )
261
+ raise ValueError(f"{kind} step '{ref}' not found in workflow. The workflow has no steps.")
262
+
263
+
193
264
  def is_bare_function_step(
194
265
  tree: cst.Module,
195
266
  entry_point: str,
@@ -5,8 +5,10 @@ import libcst as cst
5
5
  from ..cli_utils import arg_input
6
6
  from ..cst_utils import (
7
7
  collect_assignments,
8
+ collect_chained_step_names,
8
9
  collect_step_names,
9
10
  has_import,
11
+ require_step,
10
12
  resolve_entry_point_type,
11
13
  )
12
14
 
@@ -45,10 +47,16 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
45
47
  raise ValueError("add-edge requires a Workflow entry point.")
46
48
 
47
49
  when_expr = args.when if args.when else None
48
- assignments = collect_assignments(tree) if tree else {}
49
- step_names = collect_step_names(tree, entry_point, assignments) if tree else {}
50
+ assignments = collect_assignments(tree)
51
+ step_names = collect_step_names(tree, entry_point, assignments)
52
+ chained_step_names = collect_chained_step_names(tree, entry_point, assignments)
50
53
 
51
- return EdgeAdder(entry_point, args.source, args.target, when_expr, assignments, step_names)
54
+ require_step(args.target, step_names, chained_step_names, kind="Target", operation="add-edge")
55
+ # Sources only need to exist in the graph — they are referenced by runtime
56
+ # name inside the target's depends_on list.
57
+ source = require_step(args.source, {**step_names, **chained_step_names}, kind="Source", operation="add-edge")
58
+
59
+ return EdgeAdder(entry_point, source, args.target, when_expr, assignments, step_names)
52
60
 
53
61
 
54
62
  class EdgeAdder(cst.CSTTransformer):
@@ -1,9 +1,8 @@
1
1
  import argparse
2
- import json
3
2
 
4
3
  import libcst as cst
5
4
 
6
- from ..cli_utils import arg_input
5
+ from ..cli_utils import arg_input, parse_json_arg
7
6
  from ..cst_utils import (
8
7
  build_cst_value,
9
8
  collect_assignments,
@@ -132,6 +131,19 @@ def _clean_position(position: dict[str, float]) -> dict[str, int | float]:
132
131
  }
133
132
 
134
133
 
134
+ def _reject_non_name_config(config: dict, step_kind: str) -> None:
135
+ """Only Agent steps take constructor params via --config; for other step
136
+ kinds the only accepted key is 'name' (an alias for --name). Anything else
137
+ would previously be dropped silently — a common trap."""
138
+ unknown = set(config.keys()) - {"name"}
139
+ if unknown:
140
+ raise ValueError(
141
+ f"--config for {step_kind} steps only accepts 'name'; "
142
+ f"got: {', '.join(sorted(unknown))}. "
143
+ f"Use set-param to set the step's parameters, or set-config for its constructor."
144
+ )
145
+
146
+
135
147
  def register(subparsers: argparse._SubParsersAction) -> None:
136
148
  sp = subparsers.add_parser(
137
149
  "add-step",
@@ -160,6 +172,8 @@ def register(subparsers: argparse._SubParsersAction) -> None:
160
172
  type=arg_input,
161
173
  help=(
162
174
  'Agent constructor params as JSON. E.g. \'{"name": "agent_a", "model": "openai/gpt-4o-mini"}\'. '
175
+ "Framework tool and Custom steps only accept 'name' here (equivalent to --name); "
176
+ "use set-param for their step parameters. "
163
177
  "Use '@path' to read from file or '-' to read from stdin."
164
178
  ),
165
179
  )
@@ -175,7 +189,7 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
175
189
 
176
190
  assignments = collect_assignments(tree) if tree else {}
177
191
  step_type = args.step_type
178
- config = json.loads(args.config) if args.config else {}
192
+ config = parse_json_arg(args.config, "--config") if args.config else {}
179
193
 
180
194
  if args.x is not None and args.y is not None:
181
195
  position = _clean_position({"x": args.x, "y": args.y})
@@ -199,6 +213,7 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
199
213
  )
200
214
 
201
215
  if step_type == "Custom":
216
+ _reject_non_name_config(config, "Custom")
202
217
  if not args.definition:
203
218
  raise ValueError("--definition is required for Custom steps.")
204
219
  func_tree = cst.parse_module(args.definition)
@@ -210,7 +225,7 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
210
225
  if func_def is None:
211
226
  raise ValueError("--definition must contain a function definition.")
212
227
  func_name = func_def.name.value
213
- runtime_name = args.step_name if args.step_name else func_name
228
+ runtime_name = args.step_name or config.get("name") or func_name
214
229
  var_name = runtime_name
215
230
  # When the function name collides with the Tool variable name, add
216
231
  # a _fn suffix to the function to avoid shadowing.
@@ -258,9 +273,11 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
258
273
  )
259
274
 
260
275
  # Framework tool step.
276
+ _reject_non_name_config(config, "framework tool")
261
277
  framework_names = get_framework_tool_names()
262
- var_name = args.step_name if args.step_name else framework_names[step_type]
263
- runtime_name = args.step_name if args.step_name else framework_names[step_type]
278
+ step_name = args.step_name or config.get("name")
279
+ var_name = step_name if step_name else framework_names[step_type]
280
+ runtime_name = step_name if step_name else framework_names[step_type]
264
281
  return StepAdder(
265
282
  entry_point, assignments,
266
283
  step_type=step_type,
@@ -268,7 +285,7 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
268
285
  func_name=None,
269
286
  var_name=var_name,
270
287
  runtime_name=runtime_name,
271
- step_name=args.step_name,
288
+ step_name=step_name,
272
289
  position=position,
273
290
  )
274
291
 
@@ -1,9 +1,8 @@
1
1
  import argparse
2
- import json
3
2
 
4
3
  import libcst as cst
5
4
 
6
- from ..cli_utils import arg_input
5
+ from ..cli_utils import arg_input, parse_json_arg
7
6
  from ..cst_utils import (
8
7
  build_cst_value,
9
8
  collect_assignments,
@@ -99,7 +98,7 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
99
98
  if args.tool_name is not None and args.tool_name == "":
100
99
  raise ValueError("--name cannot be empty. Omit --name to use the default tool name.")
101
100
 
102
- config = json.loads(args.config) if getattr(args, "config", None) else {}
101
+ config = parse_json_arg(args.config, "--config") if getattr(args, "config", None) else {}
103
102
  if config:
104
103
  # Reject keys that would collide with explicit flags / derived values.
105
104
  # Without this, the generated source has duplicate kwargs and ruff
@@ -4,7 +4,9 @@ import libcst as cst
4
4
 
5
5
  from ..cst_utils import (
6
6
  collect_assignments,
7
+ collect_chained_step_names,
7
8
  collect_step_names,
9
+ require_step,
8
10
  resolve_entry_point_type,
9
11
  )
10
12
 
@@ -32,8 +34,15 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
32
34
  if ep_type != "Workflow":
33
35
  raise ValueError("remove-edge requires a Workflow entry point.")
34
36
 
35
- assignments = collect_assignments(tree) if tree else {}
36
- step_names = collect_step_names(tree, entry_point, assignments) if tree else {}
37
+ assignments = collect_assignments(tree)
38
+ step_names = collect_step_names(tree, entry_point, assignments)
39
+ chained_step_names = collect_chained_step_names(tree, entry_point, assignments)
40
+
41
+ # Only the target must be addressable — the source may already have been
42
+ # removed from the workflow, and remove-edge is how dangling references
43
+ # (stale depends_on entries, step_span kwargs) get cleaned up.
44
+ require_step(args.target, step_names, chained_step_names, kind="Target", operation="remove-edge")
45
+
37
46
  return EdgeRemover(entry_point, args.source, args.target, assignments, step_names)
38
47
 
39
48
 
@@ -1,9 +1,8 @@
1
1
  import argparse
2
- import json
3
2
 
4
3
  import libcst as cst
5
4
 
6
- from ..cli_utils import arg_input
5
+ from ..cli_utils import arg_input, parse_json_arg
7
6
  from ..cst_utils import (
8
7
  build_cst_value,
9
8
  collect_assignments,
@@ -53,7 +52,7 @@ def register(subparsers: argparse._SubParsersAction) -> None:
53
52
  def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None = None) -> cst.CSTTransformer:
54
53
  ep_type = resolve_entry_point_type(tree, entry_point) if tree else None
55
54
 
56
- config = json.loads(args.config) if args.config else {}
55
+ config = parse_json_arg(args.config, "--config") if args.config else {}
57
56
 
58
57
  # --- Workflow entry point ---
59
58
  if ep_type == "Workflow":
@@ -4,10 +4,13 @@ import re
4
4
 
5
5
  import libcst as cst
6
6
 
7
- from ..cli_utils import arg_input
7
+ from ..cli_utils import arg_input, parse_json_arg
8
8
  from ..cst_utils import (
9
9
  collect_assignments,
10
+ collect_chained_step_names,
11
+ collect_step_names,
10
12
  has_import,
13
+ require_step,
11
14
  resolve_entry_point_type,
12
15
  resolve_runnable_name,
13
16
  )
@@ -108,7 +111,9 @@ def register(subparsers: argparse._SubParsersAction) -> None:
108
111
  default=None,
109
112
  type=arg_input,
110
113
  help=(
111
- "Static value as a JSON literal (required for type=value). Use 'null' to remove the param. "
114
+ "Static value as a JSON literal (required for type=value). "
115
+ "Strings must include the JSON quotes, e.g. --value '\"is:unread\"'. "
116
+ "Use 'null' to remove the param. "
112
117
  "Use '@path' to read from file or '-' to read from stdin."
113
118
  ),
114
119
  )
@@ -120,32 +125,48 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
120
125
  if ep_type != "Workflow":
121
126
  raise ValueError("set-param requires a Workflow entry point.")
122
127
 
128
+ assignments = collect_assignments(tree)
129
+ step_names = collect_step_names(tree, entry_point, assignments)
130
+ chained_step_names = collect_chained_step_names(tree, entry_point, assignments)
131
+
132
+ require_step(args.target, step_names, chained_step_names, kind="Target", operation="set-param")
133
+
123
134
  param_type = args.param_type
124
135
 
125
136
  if param_type == "map":
126
137
  if not args.source:
127
138
  raise ValueError("--source is required for type=map.")
139
+ # Sources only need to exist in the graph (chained steps are fine) —
140
+ # they are referenced by runtime name inside step_span().
141
+ source = require_step(
142
+ args.source, {**step_names, **chained_step_names}, kind="Source", operation="set-param",
143
+ )
128
144
  return ParamSetter(
129
145
  entry_point=entry_point,
130
146
  target=args.target,
131
147
  param_name=args.name,
132
148
  param_type="map",
133
- source=args.source,
149
+ source=source,
134
150
  key=args.key,
135
- assignments=collect_assignments(tree) if tree else {},
151
+ assignments=assignments,
152
+ step_names=step_names,
136
153
  )
137
154
 
138
155
  if param_type == "value":
139
156
  if args.value is None:
140
157
  raise ValueError("--value is required for type=value.")
141
- value = json.loads(args.value)
158
+ value = parse_json_arg(
159
+ args.value, "--value",
160
+ hint="String values must include the JSON quotes, e.g. --value '\"is:unread label:inbox\"'.",
161
+ )
142
162
  return ParamSetter(
143
163
  entry_point=entry_point,
144
164
  target=args.target,
145
165
  param_name=args.name,
146
166
  param_type="value",
147
167
  value=value,
148
- assignments=collect_assignments(tree) if tree else {},
168
+ assignments=assignments,
169
+ step_names=step_names,
149
170
  )
150
171
 
151
172
  raise ValueError(f"Unknown param type: {param_type}")
@@ -164,6 +185,7 @@ class ParamSetter(cst.CSTTransformer):
164
185
  key: str | None = None,
165
186
  value: object = None,
166
187
  assignments: dict[str, cst.Call] | None = None,
188
+ step_names: dict[str, str] | None = None,
167
189
  ):
168
190
  self.entry_point = entry_point
169
191
  self.target = target
@@ -173,6 +195,7 @@ class ParamSetter(cst.CSTTransformer):
173
195
  self.key = key
174
196
  self.value = value
175
197
  self.assignments = assignments or {}
198
+ self.step_names = step_names or {}
176
199
  self.needs_reorder = param_type == "map"
177
200
 
178
201
  def _is_step_call(self, call: cst.Call) -> bool:
@@ -197,16 +220,19 @@ class ParamSetter(cst.CSTTransformer):
197
220
  return False
198
221
 
199
222
  def _matches_target(self, call: cst.Call) -> bool:
223
+ """Match by variable name or runtime name (mirrors add-edge)."""
200
224
  if not call.args:
201
225
  return False
202
226
  first_arg = call.args[0].value
203
227
  if isinstance(first_arg, cst.Name):
204
228
  var_name = first_arg.value
205
- if var_name in self.assignments:
206
- resolved = resolve_runnable_name(self.assignments[var_name])
207
- if resolved is not None:
208
- return resolved == self.target
209
- return var_name == self.target
229
+ if var_name == self.target:
230
+ return True
231
+ runtime_name = self.step_names.get(var_name)
232
+ if runtime_name is None and var_name in self.assignments:
233
+ runtime_name = resolve_runnable_name(self.assignments[var_name])
234
+ if runtime_name is not None and runtime_name == self.target:
235
+ return True
210
236
  return False
211
237
 
212
238
  def leave_Expr(self, original_node: cst.Expr, updated_node: cst.Expr) -> cst.Expr:
@@ -5,7 +5,10 @@ import libcst as cst
5
5
  from ..cst_utils import (
6
6
  build_cst_value,
7
7
  collect_assignments,
8
+ collect_chained_step_names,
9
+ collect_step_names,
8
10
  is_bare_function_step,
11
+ require_step,
9
12
  resolve_entry_point_type,
10
13
  resolve_runnable_name,
11
14
  wrap_bare_function_step,
@@ -42,7 +45,14 @@ def run(entry_point: str, args: argparse.Namespace, *, tree: cst.Module | None =
42
45
  assignments = collect_assignments(tree)
43
46
  return StepPositionSetter(entry_point, args.name, position, assignments), tree
44
47
 
45
- return StepPositionSetter(entry_point, args.name, position, assignments)
48
+ # Position lives on the step's constructor assignment, so chained
49
+ # steps are addressable too — validate against the full graph.
50
+ step_names = collect_step_names(tree, entry_point, assignments)
51
+ chained_step_names = collect_chained_step_names(tree, entry_point, assignments)
52
+ name = require_step(
53
+ args.name, {**step_names, **chained_step_names}, kind="Target", operation="set-position",
54
+ )
55
+ return StepPositionSetter(entry_point, name, position, assignments)
46
56
 
47
57
  # Agent (or unknown) entry point — set on the constructor directly.
48
58
  if args.name:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes