timbal 2.2.5__tar.gz → 2.2.7__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.5 → timbal-2.2.7}/PKG-INFO +1 -1
  2. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/_version.py +2 -2
  3. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/models.py +2 -0
  4. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/models.yaml +20 -0
  5. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/netsuite.py +71 -22
  6. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/file.py +23 -8
  7. {timbal-2.2.5 → timbal-2.2.7}/.gitignore +0 -0
  8. {timbal-2.2.5 → timbal-2.2.7}/LICENSE +0 -0
  9. {timbal-2.2.5 → timbal-2.2.7}/README.md +0 -0
  10. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/chat-completions.mdx +0 -0
  11. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/create-from-workforce.mdx +0 -0
  12. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/jobs/cancel.mdx +0 -0
  13. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/jobs/get.mdx +0 -0
  14. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/jobs/list.mdx +0 -0
  15. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/jobs/retry.mdx +0 -0
  16. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/link.mdx +0 -0
  17. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/list-context-vars.mdx +0 -0
  18. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/list-policies.mdx +0 -0
  19. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/messages.mdx +0 -0
  20. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/responses.mdx +0 -0
  21. {timbal-2.2.5 → timbal-2.2.7}/docs/api-reference/ace/unlink.mdx +0 -0
  22. {timbal-2.2.5 → timbal-2.2.7}/pyproject.toml +0 -0
  23. {timbal-2.2.5 → timbal-2.2.7}/pyrightconfig.json +0 -0
  24. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/__init__.py +0 -0
  25. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/__init__.py +0 -0
  26. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/__main__.py +0 -0
  27. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/cli_utils.py +0 -0
  28. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/cst_utils.py +0 -0
  29. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/flow.py +0 -0
  30. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/format.py +0 -0
  31. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/model_discovery.py +0 -0
  32. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/test.py +0 -0
  33. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/tool_discovery.py +0 -0
  34. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/__init__.py +0 -0
  35. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/add_edge.py +0 -0
  36. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/add_step.py +0 -0
  37. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/add_tool.py +0 -0
  38. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/remove_edge.py +0 -0
  39. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/remove_step.py +0 -0
  40. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/remove_tool.py +0 -0
  41. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/set_config.py +0 -0
  42. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/set_param.py +0 -0
  43. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/codegen/transformers/set_position.py +0 -0
  44. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/__init__.py +0 -0
  45. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/base.py +0 -0
  46. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/impl/__init__.py +0 -0
  47. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/impl/anthropic.py +0 -0
  48. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/impl/default.py +0 -0
  49. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/impl/message.py +0 -0
  50. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/impl/openai.py +0 -0
  51. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/impl/string.py +0 -0
  52. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/impl/timbal.py +0 -0
  53. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/collectors/registry.py +0 -0
  54. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/__init__.py +0 -0
  55. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/agent.py +0 -0
  56. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/fallback_model.py +0 -0
  57. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/llm_router.py +0 -0
  58. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/mcp.py +0 -0
  59. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/memory_compaction.py +0 -0
  60. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/runnable.py +0 -0
  61. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/skill.py +0 -0
  62. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/test_model.py +0 -0
  63. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/tool.py +0 -0
  64. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/tool_set.py +0 -0
  65. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/core/workflow.py +0 -0
  66. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/errors.py +0 -0
  67. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/__init__.py +0 -0
  68. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/cli.py +0 -0
  69. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/display.py +0 -0
  70. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/fixtures/agent.py +0 -0
  71. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/fixtures/eval_examples.yaml +0 -0
  72. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/fixtures/eval_flow_validators.yaml +0 -0
  73. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/fixtures/eval_negations.yaml +0 -0
  74. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/fixtures/eval_parallel.yaml +0 -0
  75. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/fixtures/eval_subagent.yaml +0 -0
  76. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/fixtures/eval_transforms.yaml +0 -0
  77. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/fixtures/test_invalid_validator.yaml +0 -0
  78. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/models.py +0 -0
  79. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/runner.py +0 -0
  80. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/utils.py +0 -0
  81. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/__init__.py +0 -0
  82. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/base.py +0 -0
  83. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/comparison_base.py +0 -0
  84. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/contains.py +0 -0
  85. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/contains_all.py +0 -0
  86. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/contains_any.py +0 -0
  87. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/context.py +0 -0
  88. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/email.py +0 -0
  89. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/ends_with.py +0 -0
  90. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/eq.py +0 -0
  91. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/gt.py +0 -0
  92. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/gte.py +0 -0
  93. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/json.py +0 -0
  94. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/language.py +0 -0
  95. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/length.py +0 -0
  96. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/llm_base.py +0 -0
  97. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/lt.py +0 -0
  98. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/lte.py +0 -0
  99. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/max_length.py +0 -0
  100. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/min_length.py +0 -0
  101. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/not_null.py +0 -0
  102. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/parallel.py +0 -0
  103. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/pattern.py +0 -0
  104. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/prompt.py +0 -0
  105. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/semantic.py +0 -0
  106. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/seq.py +0 -0
  107. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/starts_with.py +0 -0
  108. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/evals/validators/type.py +0 -0
  109. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/logs.py +0 -0
  110. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/platform/__init__.py +0 -0
  111. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/platform/integrations.py +0 -0
  112. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/platform/knowledge_bases/__init__.py +0 -0
  113. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/platform/knowledge_bases/query.py +0 -0
  114. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/platform/tool_proxy.py +0 -0
  115. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/platform/types.py +0 -0
  116. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/platform/utils.py +0 -0
  117. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/server/__init__.py +0 -0
  118. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/server/__main__.py +0 -0
  119. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/server/http.py +0 -0
  120. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/server/jobs.py +0 -0
  121. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/server/voice.html +0 -0
  122. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/server/voice.py +0 -0
  123. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/__init__.py +0 -0
  124. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/config.py +0 -0
  125. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/config_loader.py +0 -0
  126. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/context.py +0 -0
  127. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/dependency_analyzer.py +0 -0
  128. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/__init__.py +0 -0
  129. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/exporters/__init__.py +0 -0
  130. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/exporters/otel.py +0 -0
  131. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/providers/__init__.py +0 -0
  132. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/providers/base.py +0 -0
  133. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/providers/in_memory.py +0 -0
  134. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/providers/jsonl.py +0 -0
  135. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/providers/platform.py +0 -0
  136. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/providers/sqlite.py +0 -0
  137. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/span.py +0 -0
  138. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/state/tracing/trace.py +0 -0
  139. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/__init__.py +0 -0
  140. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/_creds.py +0 -0
  141. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/asana.py +0 -0
  142. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/bash.py +0 -0
  143. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/cala.py +0 -0
  144. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/cloudflare.py +0 -0
  145. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/dynamics_business_central.py +0 -0
  146. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/dynamics_sales.py +0 -0
  147. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/edit.py +0 -0
  148. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/elasticsearch.py +0 -0
  149. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/elevenlabs.py +0 -0
  150. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/excel.py +0 -0
  151. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/fal.py +0 -0
  152. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/fathom.py +0 -0
  153. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/firecrawl.py +0 -0
  154. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/gemini_images.py +0 -0
  155. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/gmail.py +0 -0
  156. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_analytics.py +0 -0
  157. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_business.py +0 -0
  158. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_calendar.py +0 -0
  159. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_docs.py +0 -0
  160. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_drive.py +0 -0
  161. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_maps.py +0 -0
  162. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_merchant_center.py +0 -0
  163. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_search_console.py +0 -0
  164. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/google_sheets.py +0 -0
  165. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/happy_scribe.py +0 -0
  166. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/higgsfield.py +0 -0
  167. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/hubspot.py +0 -0
  168. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/interaction.py +0 -0
  169. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/jira.py +0 -0
  170. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/klaviyo.py +0 -0
  171. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/knowledge_base.py +0 -0
  172. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/krea.py +0 -0
  173. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/lancedb.py +0 -0
  174. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/linkedin.py +0 -0
  175. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/mongodb.py +0 -0
  176. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/onedrive.py +0 -0
  177. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/outlook.py +0 -0
  178. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/parallel.py +0 -0
  179. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/pinecone.py +0 -0
  180. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/powerbi.py +0 -0
  181. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/quiver_ai.py +0 -0
  182. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/read.py +0 -0
  183. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/replicate.py +0 -0
  184. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/resend.py +0 -0
  185. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/salesforce.py +0 -0
  186. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/scraperapi.py +0 -0
  187. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/sharepoint.py +0 -0
  188. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/shopify.py +0 -0
  189. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/slack.py +0 -0
  190. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/stripe.py +0 -0
  191. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/tavily.py +0 -0
  192. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/web_search.py +0 -0
  193. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/write.py +0 -0
  194. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/xai.py +0 -0
  195. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/zendesk.py +0 -0
  196. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/tools/zoho_crm.py +0 -0
  197. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/__init__.py +0 -0
  198. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/approval.py +0 -0
  199. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/content/__init__.py +0 -0
  200. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/content/base.py +0 -0
  201. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/content/custom.py +0 -0
  202. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/content/file.py +0 -0
  203. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/content/text.py +0 -0
  204. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/content/thinking.py +0 -0
  205. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/content/tool_result.py +0 -0
  206. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/content/tool_use.py +0 -0
  207. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/events/__init__.py +0 -0
  208. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/events/approval.py +0 -0
  209. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/events/base.py +0 -0
  210. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/events/delta.py +0 -0
  211. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/events/interaction.py +0 -0
  212. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/events/output.py +0 -0
  213. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/events/start.py +0 -0
  214. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/message.py +0 -0
  215. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/types/run_status.py +0 -0
  216. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/utils/__init__.py +0 -0
  217. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/utils/import_spec.py +0 -0
  218. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/utils/model.py +0 -0
  219. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/utils/net.py +0 -0
  220. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/utils/schema.py +0 -0
  221. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/utils/serialization.py +0 -0
  222. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/voice/__init__.py +0 -0
  223. {timbal-2.2.5 → timbal-2.2.7}/python/timbal/voice/elevenlabs.py +0 -0
  224. {timbal-2.2.5 → timbal-2.2.7}/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.5
3
+ Version: 2.2.7
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.5'
22
- __version_tuple__ = version_tuple = (2, 2, 5)
21
+ __version__ = version = '2.2.7'
22
+ __version_tuple__ = version_tuple = (2, 2, 7)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -43,7 +43,9 @@ def get_context_window(model_id: str) -> int | None:
43
43
  # ---------------------------------------------------------------------------
44
44
  # Model type with provider prefixes
45
45
  Model = Literal[
46
+ "anthropic/claude-fable-5",
46
47
  "anthropic/claude-opus-4-8",
48
+ "anthropic/claude-sonnet-5",
47
49
  "anthropic/claude-opus-4-7",
48
50
  "anthropic/claude-opus-4-6",
49
51
  "anthropic/claude-opus-4-5",
@@ -10,6 +10,16 @@
10
10
 
11
11
  models:
12
12
 
13
+ - id: "anthropic/claude-fable-5"
14
+ provider: anthropic
15
+ display_name: "Claude Fable 5"
16
+ description: "Anthropic's most capable widely released model for long-horizon agentic work, complex reasoning, and ambitious coding tasks."
17
+ input_price: 10.0
18
+ output_price: 50.0
19
+ context_window: 1000000
20
+ capabilities: [vision, tools, reasoning]
21
+ notes: "Includes safety classifiers; blocked requests return stop_reason refusal. Configure Opus 4.8 fallback for production workloads."
22
+
13
23
  - id: "anthropic/claude-opus-4-8"
14
24
  provider: anthropic
15
25
  display_name: "Claude Opus 4.8"
@@ -19,6 +29,16 @@ models:
19
29
  context_window: 1000000
20
30
  capabilities: [vision, tools, reasoning]
21
31
 
32
+ - id: "anthropic/claude-sonnet-5"
33
+ provider: anthropic
34
+ display_name: "Claude Sonnet 5"
35
+ description: "Best combination of speed and intelligence. Drop-in upgrade from Sonnet 4.6 for coding, agents, and professional work."
36
+ input_price: 3.0
37
+ output_price: 15.0
38
+ context_window: 1000000
39
+ capabilities: [vision, tools, reasoning]
40
+ notes: "Introductory API pricing ($2/$10 per 1M tokens) through August 31, 2026."
41
+
22
42
  - id: "anthropic/claude-opus-4-7"
23
43
  provider: anthropic
24
44
  display_name: "Claude Opus 4.7"
@@ -29,6 +29,8 @@ def _netsuite_auth_header(
29
29
  consumer_secret: str,
30
30
  token_id: str,
31
31
  token_secret: str,
32
+ query_params: dict[str, Any] | None = None,
33
+ body: str | None = None,
32
34
  ) -> str:
33
35
  """Generate OAuth 1.0a Token-Based Authentication (TBA) header for NetSuite."""
34
36
  import base64
@@ -41,7 +43,7 @@ def _netsuite_auth_header(
41
43
  nonce = uuid.uuid4().hex
42
44
  timestamp = str(int(time.time()))
43
45
 
44
- params: dict[str, str] = {
46
+ oauth_params: dict[str, str] = {
45
47
  "oauth_consumer_key": consumer_key,
46
48
  "oauth_nonce": nonce,
47
49
  "oauth_signature_method": "HMAC-SHA256",
@@ -49,10 +51,21 @@ def _netsuite_auth_header(
49
51
  "oauth_token": token_id,
50
52
  "oauth_version": "1.0",
51
53
  }
54
+ if body is not None:
55
+ # NetSuite requires oauth_body_hash for non-form POST/PATCH/PUT bodies.
56
+ oauth_params["oauth_body_hash"] = base64.b64encode(
57
+ hashlib.sha1(body.encode(), usedforsecurity=False).digest()
58
+ ).decode()
59
+
60
+ signature_params = dict(oauth_params)
61
+ if query_params:
62
+ for key, value in query_params.items():
63
+ if value is not None:
64
+ signature_params[str(key)] = str(value)
52
65
 
53
66
  sorted_params = "&".join(
54
67
  f"{urllib.parse.quote(k, safe='')}={urllib.parse.quote(v, safe='')}"
55
- for k, v in sorted(params.items())
68
+ for k, v in sorted(signature_params.items())
56
69
  )
57
70
  base_string = (
58
71
  f"{method.upper()}&"
@@ -64,11 +77,11 @@ def _netsuite_auth_header(
64
77
  hmac.new(signing_key.encode(), base_string.encode(), hashlib.sha256).digest()
65
78
  ).decode()
66
79
 
67
- params["oauth_signature"] = signature
80
+ oauth_params["oauth_signature"] = signature
68
81
  realm = account_id.strip().upper()
69
82
 
70
83
  header_parts = [f'realm="{urllib.parse.quote(realm, safe="")}"'] + [
71
- f'{k}="{urllib.parse.quote(v, safe="")}"' for k, v in sorted(params.items())
84
+ f'{k}="{urllib.parse.quote(v, safe="")}"' for k, v in sorted(oauth_params.items())
72
85
  ]
73
86
  return "OAuth " + ", ".join(header_parts)
74
87
 
@@ -273,7 +286,9 @@ class NetSuiteGetAccount(Tool):
273
286
  if fields:
274
287
  params["fields"] = fields
275
288
 
276
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
289
+ auth = _netsuite_auth_header(
290
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
291
+ )
277
292
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
278
293
  response = await client.get(
279
294
  url,
@@ -328,7 +343,9 @@ class NetSuiteListAccounts(Tool):
328
343
  if query:
329
344
  params["q"] = query
330
345
 
331
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
346
+ auth = _netsuite_auth_header(
347
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
348
+ )
332
349
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
333
350
  response = await client.get(url, headers={"Authorization": auth, "Content-Type": "application/json"}, params=params)
334
351
  response.raise_for_status()
@@ -492,7 +509,9 @@ class NetSuiteGetAssemblyBuild(Tool):
492
509
  if fields:
493
510
  params["fields"] = fields
494
511
 
495
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
512
+ auth = _netsuite_auth_header(
513
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
514
+ )
496
515
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
497
516
  response = await client.get(
498
517
  url,
@@ -547,7 +566,9 @@ class NetSuiteListAssemblyBuilds(Tool):
547
566
  if query:
548
567
  params["q"] = query
549
568
 
550
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
569
+ auth = _netsuite_auth_header(
570
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
571
+ )
551
572
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
552
573
  response = await client.get(url, headers={"Authorization": auth, "Content-Type": "application/json"}, params=params)
553
574
  response.raise_for_status()
@@ -952,7 +973,9 @@ class NetSuiteGetAssemblyItem(Tool):
952
973
  if fields:
953
974
  params["fields"] = fields
954
975
 
955
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
976
+ auth = _netsuite_auth_header(
977
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
978
+ )
956
979
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
957
980
  response = await client.get(
958
981
  url,
@@ -1007,7 +1030,9 @@ class NetSuiteListAssemblyItems(Tool):
1007
1030
  if query:
1008
1031
  params["q"] = query
1009
1032
 
1010
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
1033
+ auth = _netsuite_auth_header(
1034
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
1035
+ )
1011
1036
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
1012
1037
  response = await client.get(url, headers={"Authorization": auth, "Content-Type": "application/json"}, params=params)
1013
1038
  response.raise_for_status()
@@ -1108,7 +1133,9 @@ class NetSuiteSuiteQL(Tool):
1108
1133
 
1109
1134
  payload = {"q": query}
1110
1135
  params = {"limit": min(limit, 1000), "offset": offset}
1111
- auth = _netsuite_auth_header("POST", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
1136
+ auth = _netsuite_auth_header(
1137
+ "POST", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
1138
+ )
1112
1139
 
1113
1140
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
1114
1141
  response = await client.post(
@@ -1284,7 +1311,9 @@ class NetSuiteGetBillingAccount(Tool):
1284
1311
  if fields:
1285
1312
  params["fields"] = fields
1286
1313
 
1287
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
1314
+ auth = _netsuite_auth_header(
1315
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
1316
+ )
1288
1317
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
1289
1318
  response = await client.get(
1290
1319
  url,
@@ -1339,7 +1368,9 @@ class NetSuiteListBillingAccounts(Tool):
1339
1368
  if query:
1340
1369
  params["q"] = query
1341
1370
 
1342
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
1371
+ auth = _netsuite_auth_header(
1372
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
1373
+ )
1343
1374
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
1344
1375
  response = await client.get(url, headers={"Authorization": auth, "Content-Type": "application/json"}, params=params)
1345
1376
  response.raise_for_status()
@@ -1552,7 +1583,9 @@ class NetSuiteGetBillingSchedule(Tool):
1552
1583
  if fields:
1553
1584
  params["fields"] = fields
1554
1585
 
1555
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
1586
+ auth = _netsuite_auth_header(
1587
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
1588
+ )
1556
1589
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
1557
1590
  response = await client.get(
1558
1591
  url,
@@ -1607,7 +1640,9 @@ class NetSuiteListBillingSchedules(Tool):
1607
1640
  if query:
1608
1641
  params["q"] = query
1609
1642
 
1610
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
1643
+ auth = _netsuite_auth_header(
1644
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
1645
+ )
1611
1646
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
1612
1647
  response = await client.get(url, headers={"Authorization": auth, "Content-Type": "application/json"}, params=params)
1613
1648
  response.raise_for_status()
@@ -1916,7 +1951,9 @@ class NetSuiteGetCalendarEvent(Tool):
1916
1951
  if fields:
1917
1952
  params["fields"] = fields
1918
1953
 
1919
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
1954
+ auth = _netsuite_auth_header(
1955
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
1956
+ )
1920
1957
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
1921
1958
  response = await client.get(
1922
1959
  url,
@@ -1971,7 +2008,9 @@ class NetSuiteListCalendarEvents(Tool):
1971
2008
  if query:
1972
2009
  params["q"] = query
1973
2010
 
1974
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
2011
+ auth = _netsuite_auth_header(
2012
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
2013
+ )
1975
2014
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
1976
2015
  response = await client.get(url, headers={"Authorization": auth, "Content-Type": "application/json"}, params=params)
1977
2016
  response.raise_for_status()
@@ -2118,7 +2157,9 @@ class NetSuiteCustomSuiteQL(Tool):
2118
2157
 
2119
2158
  payload = {"q": query}
2120
2159
  params = {"limit": min(limit, 1000), "offset": offset}
2121
- auth = _netsuite_auth_header("POST", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
2160
+ auth = _netsuite_auth_header(
2161
+ "POST", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
2162
+ )
2122
2163
 
2123
2164
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
2124
2165
  response = await client.post(
@@ -2287,7 +2328,9 @@ class NetSuiteGetIntercompanyJournalEntry(Tool):
2287
2328
  if fields:
2288
2329
  params["fields"] = fields
2289
2330
 
2290
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
2331
+ auth = _netsuite_auth_header(
2332
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
2333
+ )
2291
2334
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
2292
2335
  response = await client.get(
2293
2336
  url,
@@ -2342,7 +2385,9 @@ class NetSuiteListIntercompanyJournalEntries(Tool):
2342
2385
  if query:
2343
2386
  params["q"] = query
2344
2387
 
2345
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
2388
+ auth = _netsuite_auth_header(
2389
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
2390
+ )
2346
2391
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
2347
2392
  response = await client.get(url, headers={"Authorization": auth, "Content-Type": "application/json"}, params=params)
2348
2393
  response.raise_for_status()
@@ -2557,7 +2602,9 @@ class NetSuiteGetBinTransfer(Tool):
2557
2602
  if fields:
2558
2603
  params["fields"] = fields
2559
2604
 
2560
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
2605
+ auth = _netsuite_auth_header(
2606
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
2607
+ )
2561
2608
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
2562
2609
  response = await client.get(
2563
2610
  url,
@@ -2612,7 +2659,9 @@ class NetSuiteListBinTransfers(Tool):
2612
2659
  if query:
2613
2660
  params["q"] = query
2614
2661
 
2615
- auth = _netsuite_auth_header("GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret)
2662
+ auth = _netsuite_auth_header(
2663
+ "GET", url, account_id, consumer_key, consumer_secret, token_id, token_secret, query_params=params
2664
+ )
2616
2665
  async with httpx.AsyncClient(timeout=httpx.Timeout(30.0, connect=10.0)) as client:
2617
2666
  response = await client.get(url, headers={"Authorization": auth, "Content-Type": "application/json"}, params=params)
2618
2667
  response.raise_for_status()
@@ -5,7 +5,7 @@ import tempfile
5
5
  from collections.abc import Callable, Iterator
6
6
  from pathlib import Path
7
7
  from typing import Any
8
- from urllib.parse import quote, urlparse
8
+ from urllib.parse import unquote, urlparse
9
9
  from urllib.request import urlopen
10
10
 
11
11
  from pydantic import (
@@ -36,6 +36,13 @@ def _is_local_path(source: str) -> bool:
36
36
  )
37
37
 
38
38
 
39
+ # Hosts serving platform-persisted content. URLs on these hosts are already
40
+ # durable — re-uploading them via POST /files is wasteful and (worse) renames
41
+ # the object using the encoded basename. `platform_config.cdn` is checked too,
42
+ # but its default ("content.timbal.ai") predates the timbalusercontent.com move.
43
+ _PLATFORM_CDN_HOSTS = ("timbalusercontent.com", "content.timbal.ai")
44
+
45
+
39
46
  def _extract_filename(headers: dict, url: str) -> str:
40
47
  """Extract filename from Content-Disposition header, falling back to URL path."""
41
48
  filename = None
@@ -46,7 +53,9 @@ def _extract_filename(headers: dict, url: str) -> str:
46
53
  except (IndexError, AttributeError):
47
54
  pass
48
55
  if not filename:
49
- filename = url.split("/")[-1]
56
+ # Decode the basename: URL paths are percent-encoded, but the filename is
57
+ # used as-is for re-uploads — keeping it encoded double-encodes downstream.
58
+ filename = unquote(urlparse(url).path.split("/")[-1])
50
59
  return filename
51
60
 
52
61
 
@@ -386,7 +395,12 @@ class File(io.IOBase):
386
395
  url = str(self)
387
396
  if not run_context.platform_config:
388
397
  return url
389
- elif url.startswith(f"https://{run_context.platform_config.cdn}"):
398
+ # .hostname (unlike .netloc) drops port/userinfo and lowercases,
399
+ # so e.g. "content.timbal.ai:443" still matches. The configured cdn
400
+ # may carry a port too — strip it the same way.
401
+ host = urlparse(url).hostname
402
+ cdn_host = urlparse(f"//{run_context.platform_config.cdn}").hostname
403
+ if host and (host == cdn_host or host in _PLATFORM_CDN_HOSTS):
390
404
  object.__setattr__(self, "__persisted__", url)
391
405
  return url
392
406
 
@@ -416,11 +430,12 @@ class File(io.IOBase):
416
430
  from ..platform.utils import _request
417
431
  res = await _request("POST", path, files=files)
418
432
  upload_response = UploadFileResponse.model_validate(res.json())
419
- # Re-encode only the filename segment; the rest of the URL is already safe.
420
- # NOTE: str.rstrip() takes a *set of chars*, not a suffix, so it would chew
421
- # arbitrary trailing chars from the URL when they happen to be in the name.
422
- url = upload_response.url.removesuffix(upload_response.name)
423
- url = f"{url}{quote(upload_response.name)}"
433
+ # The platform returns a fully percent-encoded URL use it verbatim.
434
+ # Reconstructing it from `name` (raw, unencoded) breaks whenever the name
435
+ # needs encoding: removesuffix() finds no match, so the encoded name got
436
+ # appended to the already-complete URL, yielding a duplicated, doubly
437
+ # encoded path that 403s on the CDN.
438
+ url = upload_response.url
424
439
  object.__setattr__(self, "__persisted__", url)
425
440
  return url
426
441
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes