pi-ai-python 1.3.0__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 (229) hide show
  1. pi_ai_python-1.3.0/.gitignore +13 -0
  2. pi_ai_python-1.3.0/LICENSE +22 -0
  3. pi_ai_python-1.3.0/PKG-INFO +167 -0
  4. pi_ai_python-1.3.0/README.md +128 -0
  5. pi_ai_python-1.3.0/README.zh-CN.md +114 -0
  6. pi_ai_python-1.3.0/packages/agent/README.md +400 -0
  7. pi_ai_python-1.3.0/packages/agent/src/pi_agent/__init__.py +127 -0
  8. pi_ai_python-1.3.0/packages/agent/src/pi_agent/agent.py +617 -0
  9. pi_ai_python-1.3.0/packages/agent/src/pi_agent/agent_loop.py +820 -0
  10. pi_ai_python-1.3.0/packages/agent/src/pi_agent/proxy.py +269 -0
  11. pi_ai_python-1.3.0/packages/agent/src/pi_agent/py.typed +0 -0
  12. pi_ai_python-1.3.0/packages/agent/src/pi_agent/stream_fn.py +27 -0
  13. pi_ai_python-1.3.0/packages/agent/src/pi_agent/tools.py +327 -0
  14. pi_ai_python-1.3.0/packages/agent/src/pi_agent/types.py +394 -0
  15. pi_ai_python-1.3.0/packages/agent/tests/agent_helpers.py +251 -0
  16. pi_ai_python-1.3.0/packages/agent/tests/conftest.py +26 -0
  17. pi_ai_python-1.3.0/packages/agent/tests/test_agent.py +1113 -0
  18. pi_ai_python-1.3.0/packages/agent/tests/test_agent_loop.py +1522 -0
  19. pi_ai_python-1.3.0/packages/agent/tests/test_proxy.py +296 -0
  20. pi_ai_python-1.3.0/packages/agent/tests/test_tools.py +441 -0
  21. pi_ai_python-1.3.0/packages/ai/README.md +834 -0
  22. pi_ai_python-1.3.0/packages/ai/src/pi_ai/__init__.py +263 -0
  23. pi_ai_python-1.3.0/packages/ai/src/pi_ai/abort.py +315 -0
  24. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/__init__.py +1 -0
  25. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/anthropic_messages.py +1782 -0
  26. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/azure_openai_config.py +138 -0
  27. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/azure_openai_responses.py +245 -0
  28. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/bedrock_converse_stream.py +1598 -0
  29. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/classifier_shared.py +211 -0
  30. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/cloudflare.py +36 -0
  31. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/cloudflare_workers_ai_system_one.py +80 -0
  32. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/constrained_sampling.py +279 -0
  33. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/github_copilot_headers.py +30 -0
  34. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/google_generative_ai.py +138 -0
  35. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/google_shared.py +927 -0
  36. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/google_vertex.py +234 -0
  37. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/lazy.py +156 -0
  38. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/llama_cpp_classify.py +449 -0
  39. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/mistral_conversations.py +756 -0
  40. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/openai_codex_responses.py +1545 -0
  41. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/openai_completions.py +1594 -0
  42. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/openai_decisions.py +210 -0
  43. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/openai_prompt_cache.py +19 -0
  44. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/openai_responses.py +418 -0
  45. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/openai_responses_shared.py +840 -0
  46. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/openai_sdk.py +204 -0
  47. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/openrouter_images.py +153 -0
  48. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/pi_messages.py +449 -0
  49. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/registry.py +103 -0
  50. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/simple_options.py +119 -0
  51. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/system_one_shared.py +148 -0
  52. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/transform_messages.py +211 -0
  53. pi_ai_python-1.3.0/packages/ai/src/pi_ai/api/typesafe_system_one.py +43 -0
  54. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/__init__.py +1 -0
  55. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/context.py +47 -0
  56. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/credential_store.py +208 -0
  57. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/helpers.py +123 -0
  58. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/__init__.py +5 -0
  59. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/_common.py +454 -0
  60. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/anthropic.py +283 -0
  61. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/callback_server.py +339 -0
  62. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/device_code.py +127 -0
  63. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/github_copilot.py +508 -0
  64. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/kimi_coding.py +283 -0
  65. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/load.py +64 -0
  66. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/meta.py +238 -0
  67. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/openai_chatgpt.py +321 -0
  68. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/openai_codex.py +391 -0
  69. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/openrouter.py +173 -0
  70. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/pkce.py +23 -0
  71. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/radius.py +311 -0
  72. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/oauth/xai.py +220 -0
  73. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/resolve.py +190 -0
  74. pi_ai_python-1.3.0/packages/ai/src/pi_ai/auth/types.py +292 -0
  75. pi_ai_python-1.3.0/packages/ai/src/pi_ai/cli.py +265 -0
  76. pi_ai_python-1.3.0/packages/ai/src/pi_ai/compat.py +651 -0
  77. pi_ai_python-1.3.0/packages/ai/src/pi_ai/env_api_keys.py +137 -0
  78. pi_ai_python-1.3.0/packages/ai/src/pi_ai/event_stream.py +329 -0
  79. pi_ai_python-1.3.0/packages/ai/src/pi_ai/models.py +1191 -0
  80. pi_ai_python-1.3.0/packages/ai/src/pi_ai/models_store.py +121 -0
  81. pi_ai_python-1.3.0/packages/ai/src/pi_ai/oauth.py +90 -0
  82. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/__init__.py +1 -0
  83. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/all.py +154 -0
  84. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/amazon_bedrock.py +116 -0
  85. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/ant_ling.py +23 -0
  86. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/anthropic.py +105 -0
  87. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/azure.py +103 -0
  88. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/baseten.py +23 -0
  89. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/catalog.py +167 -0
  90. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/cerebras.py +23 -0
  91. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/cloudflare_ai_gateway.py +30 -0
  92. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/cloudflare_auth.py +112 -0
  93. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/cloudflare_stream.py +84 -0
  94. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/cloudflare_workers_ai.py +26 -0
  95. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/amazon-bedrock.json +1 -0
  96. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/ant-ling.json +1 -0
  97. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/anthropic.json +1 -0
  98. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/azure.json +1 -0
  99. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/baseten.json +1 -0
  100. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/cerebras.json +1 -0
  101. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/cloudflare-ai-gateway.json +1 -0
  102. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/cloudflare-workers-ai.json +1 -0
  103. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/deepseek.json +1 -0
  104. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/fireworks.json +1 -0
  105. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/github-copilot.json +1 -0
  106. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/google-vertex.json +1 -0
  107. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/google.json +1 -0
  108. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/groq.json +1 -0
  109. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/huggingface.json +1 -0
  110. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/kimi-coding.json +1 -0
  111. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/manifest.json +1 -0
  112. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/meta.json +1 -0
  113. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/minimax-cn.json +1 -0
  114. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/minimax.json +1 -0
  115. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/mistral.json +1 -0
  116. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/moonshotai-cn.json +1 -0
  117. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/moonshotai.json +1 -0
  118. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/nvidia.json +1 -0
  119. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/openai-codex.json +1 -0
  120. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/openai.json +1 -0
  121. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/opencode-go.json +1 -0
  122. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/opencode.json +1 -0
  123. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/openrouter.json +1 -0
  124. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/qwen-token-plan-cn.json +1 -0
  125. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/qwen-token-plan-individual.json +1 -0
  126. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/qwen-token-plan.json +1 -0
  127. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/radius.json +1 -0
  128. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/together.json +1 -0
  129. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/typesafe.json +1 -0
  130. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/vercel-ai-gateway.json +1 -0
  131. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/xai.json +1 -0
  132. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/xiaomi-token-plan-ams.json +1 -0
  133. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/xiaomi-token-plan-cn.json +1 -0
  134. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/xiaomi-token-plan-sgp.json +1 -0
  135. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/xiaomi.json +1 -0
  136. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/zai-coding-cn.json +1 -0
  137. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/data/zai.json +1 -0
  138. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/deepseek.py +23 -0
  139. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/faux.py +680 -0
  140. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/fireworks.py +26 -0
  141. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/github_copilot.py +46 -0
  142. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/google.py +23 -0
  143. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/google_vertex.py +131 -0
  144. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/groq.py +23 -0
  145. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/huggingface.py +23 -0
  146. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/kimi_coding.py +32 -0
  147. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/meta.py +32 -0
  148. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/minimax.py +23 -0
  149. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/minimax_cn.py +23 -0
  150. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/mistral.py +23 -0
  151. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/moonshotai.py +23 -0
  152. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/moonshotai_cn.py +23 -0
  153. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/nvidia.py +23 -0
  154. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/openai.py +44 -0
  155. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/openai_codex.py +26 -0
  156. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/opencode.py +36 -0
  157. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/opencode_go.py +33 -0
  158. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/opencode_headers.py +60 -0
  159. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/openrouter.py +145 -0
  160. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/openrouter_api.py +122 -0
  161. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/qwen_token_plan.py +23 -0
  162. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/qwen_token_plan_cn.py +23 -0
  163. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/qwen_token_plan_individual.py +23 -0
  164. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/radius.py +146 -0
  165. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/radius_config.py +136 -0
  166. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/together.py +23 -0
  167. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/typesafe.py +22 -0
  168. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/vercel_ai_gateway.py +25 -0
  169. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/xai.py +32 -0
  170. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/xiaomi.py +23 -0
  171. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/xiaomi_token_plan_ams.py +23 -0
  172. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/xiaomi_token_plan_cn.py +23 -0
  173. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/xiaomi_token_plan_sgp.py +23 -0
  174. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/zai.py +23 -0
  175. pi_ai_python-1.3.0/packages/ai/src/pi_ai/providers/zai_coding_cn.py +23 -0
  176. pi_ai_python-1.3.0/packages/ai/src/pi_ai/py.typed +0 -0
  177. pi_ai_python-1.3.0/packages/ai/src/pi_ai/serialization.py +477 -0
  178. pi_ai_python-1.3.0/packages/ai/src/pi_ai/session_resources.py +33 -0
  179. pi_ai_python-1.3.0/packages/ai/src/pi_ai/types.py +1003 -0
  180. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/__init__.py +1 -0
  181. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/callbacks.py +15 -0
  182. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/diagnostics.py +70 -0
  183. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/error_body.py +89 -0
  184. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/estimate.py +125 -0
  185. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/fastjson.py +63 -0
  186. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/http.py +409 -0
  187. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/json_parse.py +424 -0
  188. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/misc.py +193 -0
  189. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/model_operations.py +73 -0
  190. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/models_error.py +35 -0
  191. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/oauth_page.py +121 -0
  192. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/overflow.py +87 -0
  193. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/retry.py +193 -0
  194. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/schema.py +283 -0
  195. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/text.py +65 -0
  196. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/transcript.py +271 -0
  197. pi_ai_python-1.3.0/packages/ai/src/pi_ai/utils/validation.py +813 -0
  198. pi_ai_python-1.3.0/packages/ai/tests/conftest.py +87 -0
  199. pi_ai_python-1.3.0/packages/ai/tests/test_anthropic_client.py +610 -0
  200. pi_ai_python-1.3.0/packages/ai/tests/test_anthropic_payload.py +1214 -0
  201. pi_ai_python-1.3.0/packages/ai/tests/test_anthropic_sse_parsing.py +718 -0
  202. pi_ai_python-1.3.0/packages/ai/tests/test_azure_openai_responses.py +248 -0
  203. pi_ai_python-1.3.0/packages/ai/tests/test_bedrock_aws.py +746 -0
  204. pi_ai_python-1.3.0/packages/ai/tests/test_bedrock_converse_stream.py +1247 -0
  205. pi_ai_python-1.3.0/packages/ai/tests/test_cli.py +177 -0
  206. pi_ai_python-1.3.0/packages/ai/tests/test_cloudflare_workers_ai_system_one.py +209 -0
  207. pi_ai_python-1.3.0/packages/ai/tests/test_core_utils.py +611 -0
  208. pi_ai_python-1.3.0/packages/ai/tests/test_event_stream.py +195 -0
  209. pi_ai_python-1.3.0/packages/ai/tests/test_faux_provider.py +387 -0
  210. pi_ai_python-1.3.0/packages/ai/tests/test_google_shared.py +799 -0
  211. pi_ai_python-1.3.0/packages/ai/tests/test_google_streams.py +945 -0
  212. pi_ai_python-1.3.0/packages/ai/tests/test_json_parse.py +129 -0
  213. pi_ai_python-1.3.0/packages/ai/tests/test_llama_cpp_classify.py +439 -0
  214. pi_ai_python-1.3.0/packages/ai/tests/test_mistral_conversations.py +705 -0
  215. pi_ai_python-1.3.0/packages/ai/tests/test_models_runtime.py +1123 -0
  216. pi_ai_python-1.3.0/packages/ai/tests/test_oauth.py +2234 -0
  217. pi_ai_python-1.3.0/packages/ai/tests/test_openai_codex_responses.py +1196 -0
  218. pi_ai_python-1.3.0/packages/ai/tests/test_openai_completions.py +1152 -0
  219. pi_ai_python-1.3.0/packages/ai/tests/test_openai_decisions.py +264 -0
  220. pi_ai_python-1.3.0/packages/ai/tests/test_openai_responses.py +1619 -0
  221. pi_ai_python-1.3.0/packages/ai/tests/test_openrouter_images.py +235 -0
  222. pi_ai_python-1.3.0/packages/ai/tests/test_pi_messages.py +529 -0
  223. pi_ai_python-1.3.0/packages/ai/tests/test_providers.py +855 -0
  224. pi_ai_python-1.3.0/packages/ai/tests/test_providers_auth.py +525 -0
  225. pi_ai_python-1.3.0/packages/ai/tests/test_providers_streams.py +403 -0
  226. pi_ai_python-1.3.0/packages/ai/tests/test_transcript.py +190 -0
  227. pi_ai_python-1.3.0/packages/ai/tests/test_typesafe_system_one.py +337 -0
  228. pi_ai_python-1.3.0/packages/ai/tests/test_validation.py +194 -0
  229. pi_ai_python-1.3.0/pyproject.toml +123 -0
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ .mypy_cache/
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ .coverage
11
+ htmlcov/
12
+ .env
13
+ auth.json
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mario Zechner (pi, https://github.com/earendil-works/pi)
4
+ Copyright (c) 2026 nivalume (pi-py Python port)
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.5
2
+ Name: pi-ai-python
3
+ Version: 1.3.0
4
+ Summary: Python port of pi's AI libraries: a unified LLM API (pi_ai) and a stateful agent runtime (pi_agent)
5
+ Project-URL: Homepage, https://github.com/nivalume/pi-py
6
+ Project-URL: Source, https://github.com/nivalume/pi-py
7
+ Project-URL: Upstream, https://github.com/earendil-works/pi
8
+ Author: nivalume
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: agent,ai,anthropic,bedrock,gemini,llm,openai,streaming,tools
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Framework :: AsyncIO
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: anthropic>=1.15
22
+ Requires-Dist: google-genai>=2.31
23
+ Requires-Dist: httpx>=0.27
24
+ Requires-Dist: openai>=3.35
25
+ Provides-Extra: all
26
+ Requires-Dist: boto3>=1.43; extra == 'all'
27
+ Requires-Dist: orjson>=3.10; extra == 'all'
28
+ Requires-Dist: pydantic>=2.6; extra == 'all'
29
+ Requires-Dist: websockets>=13; extra == 'all'
30
+ Provides-Extra: bedrock
31
+ Requires-Dist: boto3>=1.43; extra == 'bedrock'
32
+ Provides-Extra: fast
33
+ Requires-Dist: orjson>=3.10; extra == 'fast'
34
+ Provides-Extra: pydantic
35
+ Requires-Dist: pydantic>=2.6; extra == 'pydantic'
36
+ Provides-Extra: websocket
37
+ Requires-Dist: websockets>=13; extra == 'websocket'
38
+ Description-Content-Type: text/markdown
39
+
40
+ # pi-py
41
+
42
+ Python port of [pi](https://github.com/earendil-works/pi)'s core libraries, published on
43
+ PyPI as one package, `pi-ai-python`, with two import packages:
44
+
45
+ | Import | Upstream | What it does |
46
+ | --- | --- | --- |
47
+ | [`pi_ai`](https://github.com/nivalume/pi-py/blob/main/packages/ai/README.md) | `@earendil-works/pi-ai` | Unified LLM API: provider collections, auth resolution (API keys, OAuth), streaming events, token and cost tracking, tool calling, cross-provider context hand-off, image generation, classification |
48
+ | [`pi_agent`](https://github.com/nivalume/pi-py/blob/main/packages/agent/README.md) | `@earendil-works/pi-agent-core` | Stateful agent: tool execution (parallel or sequential), steering and follow-up queues, lifecycle events, hooks |
49
+
50
+ ```bash
51
+ pip install pi-ai-python # httpx + official SDKs: anthropic, openai, google-genai
52
+ pip install "pi-ai-python[bedrock]" # + boto3 for Amazon Bedrock
53
+ pip install "pi-ai-python[all]" # + orjson, websockets, pydantic, boto3
54
+ ```
55
+
56
+ 中文说明见 [README.zh-CN.md](https://github.com/nivalume/pi-py/blob/main/README.zh-CN.md)。
57
+
58
+ ```python
59
+ import asyncio
60
+
61
+ from pi_ai import Context, UserMessage
62
+ from pi_ai.providers.all import builtin_models
63
+
64
+
65
+ async def main() -> None:
66
+ models = builtin_models() # every built-in provider; auth comes from env vars such as ANTHROPIC_API_KEY
67
+ model = models.get_model("anthropic", "claude-sonnet-4-5")
68
+ stream = models.stream(model, Context(system_prompt="Be brief.", messages=[UserMessage("Hello!")]))
69
+ async for event in stream:
70
+ if event.type == "text_delta":
71
+ print(event.delta, end="", flush=True)
72
+ message = await stream.result()
73
+ print(f"\n{message.usage.input} in / {message.usage.output} out, ${message.usage.cost.total:.4f}")
74
+
75
+
76
+ asyncio.run(main())
77
+ ```
78
+
79
+ ```python
80
+ from pi_agent import Agent, AgentInitialState, agent_tool
81
+
82
+
83
+ @agent_tool
84
+ async def get_time(timezone: str = "UTC") -> str:
85
+ """Get the current time.
86
+
87
+ Args:
88
+ timezone: IANA timezone name.
89
+ """
90
+ ...
91
+
92
+
93
+ agent = Agent(
94
+ initial_state=AgentInitialState(system_prompt="You are helpful.", model=model, tools=[get_time]),
95
+ stream_fn=models.stream_simple,
96
+ )
97
+ async for event in agent.events("What time is it in Tokyo?"):
98
+ print(event.type)
99
+ ```
100
+
101
+ ## Same API, Python conventions
102
+
103
+ The port keeps pi's architecture and semantics: the same `Models`/`Provider`
104
+ runtime, the same event protocol (`start` → `text_delta`… → `done`/`error`), the
105
+ same transcript model (system prompt and tools carried by system messages), the
106
+ same auth precedence rules, the same model catalog, and the same agent loop.
107
+ Names follow Python conventions:
108
+
109
+ | TypeScript | Python |
110
+ | --- | --- |
111
+ | `createModels()`, `models.streamSimple(...)` | `create_models()`, `models.stream_simple(...)` |
112
+ | `{ apiKey, sessionId, maxTokens }` options | `api_key=..., session_id=..., max_tokens=...` keyword arguments (or a dict) |
113
+ | `message.stopReason`, `usage.cacheRead` | `message.stop_reason`, `usage.cache_read` |
114
+ | `{ role: "user", content: "hi", timestamp }` | `UserMessage("hi")` (timestamp defaults to now) |
115
+ | `Type.Object({...})` (TypeBox) | `Type.Object({...})` (built in) or a Pydantic model |
116
+ | `AbortController` / `signal` | `pi_ai.AbortController` / `signal=` |
117
+ | `for await (const e of stream)` / `await stream.result()` | `async for e in stream` / `await stream.result()` |
118
+ | `agent.continue()` | `agent.continue_()` (alias `agent.resume()`) |
119
+
120
+ String values that appear on the wire or in persisted transcripts are unchanged
121
+ (`"toolUse"`, `"toolResult"`, `"text_delta"`, API ids, provider ids), and
122
+ `pi_ai.serialization` reads and writes pi's camelCase JSON, so sessions, model
123
+ definitions and `auth.json` credential files are interchangeable with TypeScript pi.
124
+
125
+ ## Design notes
126
+
127
+ * **Official vendor SDKs.** As in pi, the Anthropic, OpenAI (Chat Completions,
128
+ Responses, Azure, OpenRouter images), Google (Gemini, Vertex) and Bedrock adapters use
129
+ the vendors' official SDKs: `anthropic`, `openai`, `google-genai` and `boto3`
130
+ (`pi-ai-python[bedrock]`). The SDK clients share one pooled `httpx.AsyncClient` per event loop.
131
+ APIs that pi calls without an SDK (Mistral, OpenAI Codex, pi-messages, classifiers)
132
+ use `httpx` directly.
133
+ * **Fast streaming path.** Slotted data classes, an allocation-light event queue,
134
+ zero-copy forwarding between wrapped streams, an incremental partial-JSON parser
135
+ for tool-call arguments (about 60x faster than re-parsing each delta on large
136
+ arguments), linear-time accumulation of streamed text, optional `orjson` decoding,
137
+ and compiled, cached tool-argument validators. On one core the anthropic-messages
138
+ adapter processes about 110,000 stream events per second and openai-completions about
139
+ 70,000, where the openai SDK's SSE decoder is the limit (see `benchmarks/`).
140
+ * **Lazy everything.** Model catalogs load per provider on first use; API
141
+ implementations and OAuth flows import on first request.
142
+ * **Async-native cancellation.** `AbortSignal` aborts interrupt pending network reads
143
+ immediately (task cancellation scoped by `abort_scope`), and aborted requests end
144
+ their stream with `stop_reason == "aborted"` instead of raising.
145
+ * **Python-friendly additions.** Pydantic models as tool parameter schemas,
146
+ `@agent_tool` to build tools from typed functions, `Agent.events()` as an async
147
+ iterator, `FileCredentialStore` (pi's `auth.json` format with cross-process locking),
148
+ keyword-argument options, streams that can be created outside an event loop and
149
+ closed with `async with`.
150
+
151
+ ## Development
152
+
153
+ ```bash
154
+ uv sync # create .venv with the package (editable) and dev tools
155
+ uv run pytest # run all tests (offline; HTTP is mocked)
156
+ uv run ruff check . && uv run ruff format --check .
157
+ uv run pyright
158
+ uv run python benchmarks/bench_partial_json.py
159
+ uv run python benchmarks/bench_stream.py
160
+ ```
161
+
162
+ Model catalog data (`packages/ai/src/pi_ai/providers/data/*.json`) is the generated
163
+ catalog shipped with `@earendil-works/pi-ai` 1.3.0.
164
+
165
+ ## License
166
+
167
+ MIT. Based on pi by Mario Zechner and contributors.
@@ -0,0 +1,128 @@
1
+ # pi-py
2
+
3
+ Python port of [pi](https://github.com/earendil-works/pi)'s core libraries, published on
4
+ PyPI as one package, `pi-ai-python`, with two import packages:
5
+
6
+ | Import | Upstream | What it does |
7
+ | --- | --- | --- |
8
+ | [`pi_ai`](https://github.com/nivalume/pi-py/blob/main/packages/ai/README.md) | `@earendil-works/pi-ai` | Unified LLM API: provider collections, auth resolution (API keys, OAuth), streaming events, token and cost tracking, tool calling, cross-provider context hand-off, image generation, classification |
9
+ | [`pi_agent`](https://github.com/nivalume/pi-py/blob/main/packages/agent/README.md) | `@earendil-works/pi-agent-core` | Stateful agent: tool execution (parallel or sequential), steering and follow-up queues, lifecycle events, hooks |
10
+
11
+ ```bash
12
+ pip install pi-ai-python # httpx + official SDKs: anthropic, openai, google-genai
13
+ pip install "pi-ai-python[bedrock]" # + boto3 for Amazon Bedrock
14
+ pip install "pi-ai-python[all]" # + orjson, websockets, pydantic, boto3
15
+ ```
16
+
17
+ 中文说明见 [README.zh-CN.md](https://github.com/nivalume/pi-py/blob/main/README.zh-CN.md)。
18
+
19
+ ```python
20
+ import asyncio
21
+
22
+ from pi_ai import Context, UserMessage
23
+ from pi_ai.providers.all import builtin_models
24
+
25
+
26
+ async def main() -> None:
27
+ models = builtin_models() # every built-in provider; auth comes from env vars such as ANTHROPIC_API_KEY
28
+ model = models.get_model("anthropic", "claude-sonnet-4-5")
29
+ stream = models.stream(model, Context(system_prompt="Be brief.", messages=[UserMessage("Hello!")]))
30
+ async for event in stream:
31
+ if event.type == "text_delta":
32
+ print(event.delta, end="", flush=True)
33
+ message = await stream.result()
34
+ print(f"\n{message.usage.input} in / {message.usage.output} out, ${message.usage.cost.total:.4f}")
35
+
36
+
37
+ asyncio.run(main())
38
+ ```
39
+
40
+ ```python
41
+ from pi_agent import Agent, AgentInitialState, agent_tool
42
+
43
+
44
+ @agent_tool
45
+ async def get_time(timezone: str = "UTC") -> str:
46
+ """Get the current time.
47
+
48
+ Args:
49
+ timezone: IANA timezone name.
50
+ """
51
+ ...
52
+
53
+
54
+ agent = Agent(
55
+ initial_state=AgentInitialState(system_prompt="You are helpful.", model=model, tools=[get_time]),
56
+ stream_fn=models.stream_simple,
57
+ )
58
+ async for event in agent.events("What time is it in Tokyo?"):
59
+ print(event.type)
60
+ ```
61
+
62
+ ## Same API, Python conventions
63
+
64
+ The port keeps pi's architecture and semantics: the same `Models`/`Provider`
65
+ runtime, the same event protocol (`start` → `text_delta`… → `done`/`error`), the
66
+ same transcript model (system prompt and tools carried by system messages), the
67
+ same auth precedence rules, the same model catalog, and the same agent loop.
68
+ Names follow Python conventions:
69
+
70
+ | TypeScript | Python |
71
+ | --- | --- |
72
+ | `createModels()`, `models.streamSimple(...)` | `create_models()`, `models.stream_simple(...)` |
73
+ | `{ apiKey, sessionId, maxTokens }` options | `api_key=..., session_id=..., max_tokens=...` keyword arguments (or a dict) |
74
+ | `message.stopReason`, `usage.cacheRead` | `message.stop_reason`, `usage.cache_read` |
75
+ | `{ role: "user", content: "hi", timestamp }` | `UserMessage("hi")` (timestamp defaults to now) |
76
+ | `Type.Object({...})` (TypeBox) | `Type.Object({...})` (built in) or a Pydantic model |
77
+ | `AbortController` / `signal` | `pi_ai.AbortController` / `signal=` |
78
+ | `for await (const e of stream)` / `await stream.result()` | `async for e in stream` / `await stream.result()` |
79
+ | `agent.continue()` | `agent.continue_()` (alias `agent.resume()`) |
80
+
81
+ String values that appear on the wire or in persisted transcripts are unchanged
82
+ (`"toolUse"`, `"toolResult"`, `"text_delta"`, API ids, provider ids), and
83
+ `pi_ai.serialization` reads and writes pi's camelCase JSON, so sessions, model
84
+ definitions and `auth.json` credential files are interchangeable with TypeScript pi.
85
+
86
+ ## Design notes
87
+
88
+ * **Official vendor SDKs.** As in pi, the Anthropic, OpenAI (Chat Completions,
89
+ Responses, Azure, OpenRouter images), Google (Gemini, Vertex) and Bedrock adapters use
90
+ the vendors' official SDKs: `anthropic`, `openai`, `google-genai` and `boto3`
91
+ (`pi-ai-python[bedrock]`). The SDK clients share one pooled `httpx.AsyncClient` per event loop.
92
+ APIs that pi calls without an SDK (Mistral, OpenAI Codex, pi-messages, classifiers)
93
+ use `httpx` directly.
94
+ * **Fast streaming path.** Slotted data classes, an allocation-light event queue,
95
+ zero-copy forwarding between wrapped streams, an incremental partial-JSON parser
96
+ for tool-call arguments (about 60x faster than re-parsing each delta on large
97
+ arguments), linear-time accumulation of streamed text, optional `orjson` decoding,
98
+ and compiled, cached tool-argument validators. On one core the anthropic-messages
99
+ adapter processes about 110,000 stream events per second and openai-completions about
100
+ 70,000, where the openai SDK's SSE decoder is the limit (see `benchmarks/`).
101
+ * **Lazy everything.** Model catalogs load per provider on first use; API
102
+ implementations and OAuth flows import on first request.
103
+ * **Async-native cancellation.** `AbortSignal` aborts interrupt pending network reads
104
+ immediately (task cancellation scoped by `abort_scope`), and aborted requests end
105
+ their stream with `stop_reason == "aborted"` instead of raising.
106
+ * **Python-friendly additions.** Pydantic models as tool parameter schemas,
107
+ `@agent_tool` to build tools from typed functions, `Agent.events()` as an async
108
+ iterator, `FileCredentialStore` (pi's `auth.json` format with cross-process locking),
109
+ keyword-argument options, streams that can be created outside an event loop and
110
+ closed with `async with`.
111
+
112
+ ## Development
113
+
114
+ ```bash
115
+ uv sync # create .venv with the package (editable) and dev tools
116
+ uv run pytest # run all tests (offline; HTTP is mocked)
117
+ uv run ruff check . && uv run ruff format --check .
118
+ uv run pyright
119
+ uv run python benchmarks/bench_partial_json.py
120
+ uv run python benchmarks/bench_stream.py
121
+ ```
122
+
123
+ Model catalog data (`packages/ai/src/pi_ai/providers/data/*.json`) is the generated
124
+ catalog shipped with `@earendil-works/pi-ai` 1.3.0.
125
+
126
+ ## License
127
+
128
+ MIT. Based on pi by Mario Zechner and contributors.
@@ -0,0 +1,114 @@
1
+ # pi-py
2
+
3
+ [pi](https://github.com/earendil-works/pi) 核心库的 Python 实现,包含两个模块:
4
+
5
+ | Import 名 | 对应上游 | 作用 |
6
+ | --- | --- | --- |
7
+ | [`pi_ai`](packages/ai/README.md) | `@earendil-works/pi-ai` | 统一的 LLM API:provider 集合、鉴权解析(API key / OAuth)、流式事件、token 与费用统计、工具调用、跨 provider 上下文切换、图像生成、分类 |
8
+ | [`pi_agent`](packages/agent/README.md) | `@earendil-works/pi-agent-core` | 有状态 Agent:工具执行(并行/串行)、steering 与 follow-up 队列、生命周期事件、钩子 |
9
+
10
+ 两者在 PyPI 上作为同一个包 `pi-ai-python` 发布。
11
+
12
+ ## 安装
13
+
14
+ ```bash
15
+ pip install pi-ai-python # 依赖 httpx 和官方 SDK:anthropic、openai、google-genai
16
+ pip install "pi-ai-python[bedrock]" # 可选:boto3,用于 Amazon Bedrock
17
+ pip install "pi-ai-python[fast]" # 可选:orjson 加速 JSON 解码
18
+ pip install "pi-ai-python[all]" # 可选:orjson + websockets + pydantic + boto3
19
+ ```
20
+
21
+ 开发环境:
22
+
23
+ ```bash
24
+ uv sync
25
+ uv run pytest
26
+ ```
27
+
28
+ ## 快速开始
29
+
30
+ ```python
31
+ import asyncio
32
+
33
+ from pi_ai import Context, UserMessage
34
+ from pi_ai.providers.all import builtin_models
35
+
36
+
37
+ async def main() -> None:
38
+ models = builtin_models() # 注册全部内置 provider,鉴权读取 ANTHROPIC_API_KEY 等环境变量
39
+ model = models.get_model("anthropic", "claude-sonnet-4-5")
40
+ stream = models.stream(model, Context(system_prompt="回答要简洁。", messages=[UserMessage("你好!")]))
41
+ async for event in stream:
42
+ if event.type == "text_delta":
43
+ print(event.delta, end="", flush=True)
44
+ message = await stream.result()
45
+ print(f"\n输入 {message.usage.input} / 输出 {message.usage.output} tokens,费用 ${message.usage.cost.total:.4f}")
46
+
47
+
48
+ asyncio.run(main())
49
+ ```
50
+
51
+ Agent:
52
+
53
+ ```python
54
+ from pi_agent import Agent, AgentInitialState, agent_tool
55
+
56
+
57
+ @agent_tool
58
+ async def get_weather(city: str) -> str:
59
+ """查询天气。
60
+
61
+ Args:
62
+ city: 城市名。
63
+ """
64
+ return f"{city}:晴,25°C"
65
+
66
+
67
+ agent = Agent(
68
+ initial_state=AgentInitialState(system_prompt="你是一个助手。", model=model, tools=[get_weather]),
69
+ stream_fn=models.stream_simple,
70
+ )
71
+ async for event in agent.events("北京天气怎么样?"):
72
+ if event.type == "message_update" and event.assistant_message_event.type == "text_delta":
73
+ print(event.assistant_message_event.delta, end="")
74
+ ```
75
+
76
+ ## 与 pi 保持一致的 API
77
+
78
+ 架构与语义与 TypeScript 版一致:同样的 `Models`/`Provider` 运行时、同样的事件协议
79
+ (`start` → `text_delta`… → `done`/`error`)、同样的 transcript 模型(系统提示词和工具由
80
+ system message 承载)、同样的鉴权优先级、同样的模型目录和 Agent 循环。命名遵循 Python 习惯:
81
+
82
+ | TypeScript | Python |
83
+ | --- | --- |
84
+ | `createModels()`、`models.streamSimple(...)` | `create_models()`、`models.stream_simple(...)` |
85
+ | `{ apiKey, sessionId, maxTokens }` | 关键字参数 `api_key=..., session_id=..., max_tokens=...`(也可传 dict) |
86
+ | `message.stopReason`、`usage.cacheRead` | `message.stop_reason`、`usage.cache_read` |
87
+ | `{ role: "user", content: "hi", timestamp }` | `UserMessage("hi")`(timestamp 默认为当前时间) |
88
+ | TypeBox `Type.Object({...})` | 内置 `Type.Object({...})` 或 Pydantic 模型 |
89
+ | `AbortController` / `signal` | `pi_ai.AbortController` / `signal=` |
90
+ | `agent.continue()` | `agent.continue_()`(别名 `agent.resume()`) |
91
+
92
+ 线上协议和持久化中出现的字符串值保持不变(`"toolUse"`、`"toolResult"`、`"text_delta"`、API id、
93
+ provider id)。`pi_ai.serialization` 读写 pi 的 camelCase JSON,会话记录、模型定义和
94
+ `auth.json` 凭据文件都可以与 TypeScript 版互通。
95
+
96
+ ## 设计改进
97
+
98
+ * **使用厂商官方 SDK**:与 pi 一致,Anthropic、OpenAI(Chat Completions、Responses、Azure、OpenRouter 图片)、
99
+ Google(Gemini、Vertex)和 Bedrock 适配器分别使用官方 SDK `anthropic`、`openai`、`google-genai`、`boto3`
100
+ (`pi-ai-python[bedrock]`),各 SDK 客户端共用每个事件循环一个的 `httpx.AsyncClient` 连接池。
101
+ pi 本身不经 SDK 调用的 API(Mistral、OpenAI Codex、pi-messages、分类器)直接使用 `httpx`。
102
+ * **性能**:slots 数据类、低分配的事件队列、包装流之间零拷贝转发、增量式部分 JSON 解析
103
+ (大参数工具调用比逐 delta 全量重解析快约 60 倍)、流式文本线性时间累加、可选 orjson、编译并缓存的参数校验器。
104
+ 单核每秒处理流事件:anthropic-messages 约 11 万,openai-completions 约 7 万(瓶颈在 openai SDK 的 SSE 解码,见 `benchmarks/`)。
105
+ * **全面懒加载**:模型目录按 provider 首次访问时加载;API 实现和 OAuth 流程在首次请求时导入。
106
+ * **原生异步取消**:`AbortSignal` 可立即中断挂起的网络读取,被中止的请求以 `stop_reason == "aborted"` 结束而不是抛异常。
107
+ * **Python 友好的扩展**:Pydantic 模型作为工具参数、`@agent_tool` 从类型注解生成工具、`Agent.events()` 异步迭代器、
108
+ `FileCredentialStore`(pi 的 `auth.json` 格式,带跨进程锁)、事件循环外创建的流、`async with` 关闭流。
109
+
110
+ 详细文档:[pi_ai](packages/ai/README.md)、[pi_agent](packages/agent/README.md)。
111
+
112
+ ## 许可证
113
+
114
+ MIT,基于 Mario Zechner 等人的 pi。