coco-framework 0.1.0__py3-none-any.whl

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 (400) hide show
  1. coco/__init__.py +3 -0
  2. coco/agents/__init__.py +9 -0
  3. coco/agents/_subagent_transformer.py +307 -0
  4. coco/agents/factory.py +2164 -0
  5. coco/agents/middleware/__init__.py +100 -0
  6. coco/agents/middleware/_execution.py +385 -0
  7. coco/agents/middleware/_redaction.py +454 -0
  8. coco/agents/middleware/_retry.py +134 -0
  9. coco/agents/middleware/_trace_policy.py +61 -0
  10. coco/agents/middleware/context_editing.py +306 -0
  11. coco/agents/middleware/file_search.py +433 -0
  12. coco/agents/middleware/human_in_the_loop.py +680 -0
  13. coco/agents/middleware/internal_call_transformer.py +108 -0
  14. coco/agents/middleware/model_call_limit.py +267 -0
  15. coco/agents/middleware/model_fallback.py +417 -0
  16. coco/agents/middleware/model_retry.py +327 -0
  17. coco/agents/middleware/pii.py +878 -0
  18. coco/agents/middleware/provider_tool_search.py +307 -0
  19. coco/agents/middleware/shell_tool.py +949 -0
  20. coco/agents/middleware/summarization.py +910 -0
  21. coco/agents/middleware/todo.py +357 -0
  22. coco/agents/middleware/tool_call_limit.py +495 -0
  23. coco/agents/middleware/tool_emulator.py +251 -0
  24. coco/agents/middleware/tool_error.py +209 -0
  25. coco/agents/middleware/tool_retry.py +421 -0
  26. coco/agents/middleware/tool_selection.py +515 -0
  27. coco/agents/middleware/types.py +2201 -0
  28. coco/agents/structured_output.py +472 -0
  29. coco/chat_models/__init__.py +7 -0
  30. coco/chat_models/base.py +1082 -0
  31. coco/embeddings/__init__.py +18 -0
  32. coco/embeddings/base.py +279 -0
  33. coco/mcp/__init__.py +36 -0
  34. coco/mcp/adapter.py +245 -0
  35. coco/mcp/elicitation.py +394 -0
  36. coco/mcp/tools.py +307 -0
  37. coco/messages/__init__.py +73 -0
  38. coco/py.typed +0 -0
  39. coco/rate_limiters/__init__.py +13 -0
  40. coco/tools/__init__.py +22 -0
  41. coco/tools/tool_node.py +20 -0
  42. coco_anthropic/__init__.py +15 -0
  43. coco_anthropic/_client_utils.py +81 -0
  44. coco_anthropic/_compat.py +228 -0
  45. coco_anthropic/_sdk_compat.py +124 -0
  46. coco_anthropic/_version.py +3 -0
  47. coco_anthropic/chat_models.py +3349 -0
  48. coco_anthropic/data/__init__.py +1 -0
  49. coco_anthropic/data/_profiles.py +491 -0
  50. coco_anthropic/data/profile_augmentations.toml +69 -0
  51. coco_anthropic/experimental.py +140 -0
  52. coco_anthropic/llms.py +428 -0
  53. coco_anthropic/middleware/__init__.py +25 -0
  54. coco_anthropic/middleware/anthropic_tools.py +1197 -0
  55. coco_anthropic/middleware/bash.py +84 -0
  56. coco_anthropic/middleware/file_search.py +360 -0
  57. coco_anthropic/middleware/prompt_caching.py +276 -0
  58. coco_anthropic/output_parsers.py +93 -0
  59. coco_anthropic/py.typed +0 -0
  60. coco_core/__init__.py +20 -0
  61. coco_core/_api/__init__.py +87 -0
  62. coco_core/_api/beta_decorator.py +266 -0
  63. coco_core/_api/deprecation.py +637 -0
  64. coco_core/_api/internal.py +23 -0
  65. coco_core/_api/path.py +50 -0
  66. coco_core/_import_utils.py +41 -0
  67. coco_core/_protocol.py +625 -0
  68. coco_core/_security/__init__.py +36 -0
  69. coco_core/_security/_exceptions.py +9 -0
  70. coco_core/_security/_policy.py +313 -0
  71. coco_core/_security/_ssrf_protection.py +155 -0
  72. coco_core/_security/_transport.py +254 -0
  73. coco_core/agents.py +258 -0
  74. coco_core/caches.py +272 -0
  75. coco_core/callbacks/__init__.py +132 -0
  76. coco_core/callbacks/base.py +1229 -0
  77. coco_core/callbacks/file.py +266 -0
  78. coco_core/callbacks/manager.py +2826 -0
  79. coco_core/callbacks/stdout.py +123 -0
  80. coco_core/callbacks/streaming_stdout.py +154 -0
  81. coco_core/callbacks/usage.py +124 -0
  82. coco_core/chat_history.py +267 -0
  83. coco_core/chat_loaders.py +26 -0
  84. coco_core/chat_sessions.py +19 -0
  85. coco_core/cross_encoders.py +18 -0
  86. coco_core/document_loaders/__init__.py +36 -0
  87. coco_core/document_loaders/base.py +155 -0
  88. coco_core/document_loaders/blob_loaders.py +38 -0
  89. coco_core/documents/__init__.py +55 -0
  90. coco_core/documents/base.py +347 -0
  91. coco_core/documents/compressor.py +74 -0
  92. coco_core/documents/transformers.py +79 -0
  93. coco_core/embeddings/__init__.py +31 -0
  94. coco_core/embeddings/embeddings.py +78 -0
  95. coco_core/embeddings/fake.py +129 -0
  96. coco_core/env.py +22 -0
  97. coco_core/example_selectors/__init__.py +47 -0
  98. coco_core/example_selectors/base.py +60 -0
  99. coco_core/example_selectors/length_based.py +131 -0
  100. coco_core/example_selectors/semantic_similarity.py +366 -0
  101. coco_core/exceptions.py +166 -0
  102. coco_core/globals.py +72 -0
  103. coco_core/indexing/__init__.py +53 -0
  104. coco_core/indexing/api.py +954 -0
  105. coco_core/indexing/base.py +661 -0
  106. coco_core/indexing/in_memory.py +104 -0
  107. coco_core/language_models/__init__.py +116 -0
  108. coco_core/language_models/_compat_bridge.py +844 -0
  109. coco_core/language_models/_utils.py +343 -0
  110. coco_core/language_models/base.py +500 -0
  111. coco_core/language_models/chat_model_stream.py +1525 -0
  112. coco_core/language_models/chat_models.py +2748 -0
  113. coco_core/language_models/fake.py +137 -0
  114. coco_core/language_models/fake_chat_models.py +396 -0
  115. coco_core/language_models/llms.py +1569 -0
  116. coco_core/language_models/model_profile.py +183 -0
  117. coco_core/load/__init__.py +44 -0
  118. coco_core/load/_validation.py +191 -0
  119. coco_core/load/dump.py +120 -0
  120. coco_core/load/load.py +828 -0
  121. coco_core/load/mapping.py +1097 -0
  122. coco_core/load/serializable.py +406 -0
  123. coco_core/messages/__init__.py +198 -0
  124. coco_core/messages/ai.py +854 -0
  125. coco_core/messages/base.py +518 -0
  126. coco_core/messages/block_translators/__init__.py +112 -0
  127. coco_core/messages/block_translators/anthropic.py +534 -0
  128. coco_core/messages/block_translators/bedrock.py +108 -0
  129. coco_core/messages/block_translators/bedrock_converse.py +329 -0
  130. coco_core/messages/block_translators/coco_v0.py +303 -0
  131. coco_core/messages/block_translators/google_genai.py +610 -0
  132. coco_core/messages/block_translators/google_vertexai.py +21 -0
  133. coco_core/messages/block_translators/groq.py +157 -0
  134. coco_core/messages/block_translators/openai.py +1089 -0
  135. coco_core/messages/chat.py +64 -0
  136. coco_core/messages/content.py +1488 -0
  137. coco_core/messages/function.py +62 -0
  138. coco_core/messages/human.py +70 -0
  139. coco_core/messages/modifier.py +33 -0
  140. coco_core/messages/system.py +70 -0
  141. coco_core/messages/tool.py +418 -0
  142. coco_core/messages/utils.py +2442 -0
  143. coco_core/output_parsers/__init__.py +101 -0
  144. coco_core/output_parsers/base.py +361 -0
  145. coco_core/output_parsers/format_instructions.py +16 -0
  146. coco_core/output_parsers/json.py +139 -0
  147. coco_core/output_parsers/list.py +249 -0
  148. coco_core/output_parsers/openai_functions.py +324 -0
  149. coco_core/output_parsers/openai_tools.py +383 -0
  150. coco_core/output_parsers/pydantic.py +141 -0
  151. coco_core/output_parsers/string.py +63 -0
  152. coco_core/output_parsers/transform.py +175 -0
  153. coco_core/output_parsers/xml.py +301 -0
  154. coco_core/outputs/__init__.py +66 -0
  155. coco_core/outputs/chat_generation.py +147 -0
  156. coco_core/outputs/chat_result.py +39 -0
  157. coco_core/outputs/generation.py +80 -0
  158. coco_core/outputs/llm_result.py +112 -0
  159. coco_core/outputs/run_info.py +22 -0
  160. coco_core/prompt_values.py +161 -0
  161. coco_core/prompts/__init__.py +101 -0
  162. coco_core/prompts/base.py +508 -0
  163. coco_core/prompts/chat.py +1495 -0
  164. coco_core/prompts/dict.py +177 -0
  165. coco_core/prompts/few_shot.py +483 -0
  166. coco_core/prompts/few_shot_with_templates.py +239 -0
  167. coco_core/prompts/image.py +177 -0
  168. coco_core/prompts/loading.py +296 -0
  169. coco_core/prompts/message.py +97 -0
  170. coco_core/prompts/prompt.py +312 -0
  171. coco_core/prompts/string.py +399 -0
  172. coco_core/prompts/structured.py +214 -0
  173. coco_core/py.typed +0 -0
  174. coco_core/rate_limiters.py +254 -0
  175. coco_core/retrievers.py +328 -0
  176. coco_core/runnables/__init__.py +136 -0
  177. coco_core/runnables/base.py +6725 -0
  178. coco_core/runnables/branch.py +457 -0
  179. coco_core/runnables/config.py +712 -0
  180. coco_core/runnables/configurable.py +710 -0
  181. coco_core/runnables/fallbacks.py +663 -0
  182. coco_core/runnables/graph.py +741 -0
  183. coco_core/runnables/graph_ascii.py +366 -0
  184. coco_core/runnables/graph_mermaid.py +503 -0
  185. coco_core/runnables/graph_png.py +215 -0
  186. coco_core/runnables/history.py +631 -0
  187. coco_core/runnables/passthrough.py +849 -0
  188. coco_core/runnables/retry.py +379 -0
  189. coco_core/runnables/router.py +239 -0
  190. coco_core/runnables/schema.py +188 -0
  191. coco_core/runnables/utils.py +798 -0
  192. coco_core/stores.py +291 -0
  193. coco_core/structured_query.py +203 -0
  194. coco_core/sys_info.py +154 -0
  195. coco_core/tools/__init__.py +95 -0
  196. coco_core/tools/base.py +1948 -0
  197. coco_core/tools/convert.py +497 -0
  198. coco_core/tools/render.py +67 -0
  199. coco_core/tools/retriever.py +94 -0
  200. coco_core/tools/simple.py +208 -0
  201. coco_core/tools/structured.py +322 -0
  202. coco_core/tracers/__init__.py +47 -0
  203. coco_core/tracers/_compat.py +95 -0
  204. coco_core/tracers/_context.py +337 -0
  205. coco_core/tracers/_streaming.py +53 -0
  206. coco_core/tracers/base.py +955 -0
  207. coco_core/tracers/coco.py +279 -0
  208. coco_core/tracers/context.py +205 -0
  209. coco_core/tracers/core.py +766 -0
  210. coco_core/tracers/event_stream.py +1101 -0
  211. coco_core/tracers/log_stream.py +765 -0
  212. coco_core/tracers/memory_stream.py +200 -0
  213. coco_core/tracers/root_listeners.py +130 -0
  214. coco_core/tracers/run_collector.py +40 -0
  215. coco_core/tracers/schemas.py +14 -0
  216. coco_core/tracers/stdout.py +205 -0
  217. coco_core/utils/__init__.py +111 -0
  218. coco_core/utils/_gateway.py +274 -0
  219. coco_core/utils/_merge.py +218 -0
  220. coco_core/utils/aiter.py +357 -0
  221. coco_core/utils/env.py +86 -0
  222. coco_core/utils/formatting.py +80 -0
  223. coco_core/utils/function_calling.py +869 -0
  224. coco_core/utils/html.py +132 -0
  225. coco_core/utils/image.py +15 -0
  226. coco_core/utils/input.py +82 -0
  227. coco_core/utils/interactive_env.py +12 -0
  228. coco_core/utils/iter.py +229 -0
  229. coco_core/utils/json.py +230 -0
  230. coco_core/utils/json_schema.py +273 -0
  231. coco_core/utils/mustache.py +706 -0
  232. coco_core/utils/pydantic.py +631 -0
  233. coco_core/utils/strings.py +69 -0
  234. coco_core/utils/usage.py +61 -0
  235. coco_core/utils/utils.py +528 -0
  236. coco_core/utils/uuid.py +57 -0
  237. coco_core/vectorstores/__init__.py +53 -0
  238. coco_core/vectorstores/base.py +1111 -0
  239. coco_core/vectorstores/in_memory.py +546 -0
  240. coco_core/vectorstores/utils.py +163 -0
  241. coco_core/version.py +3 -0
  242. coco_framework-0.1.0.dist-info/METADATA +184 -0
  243. coco_framework-0.1.0.dist-info/RECORD +400 -0
  244. coco_framework-0.1.0.dist-info/WHEEL +4 -0
  245. coco_framework-0.1.0.dist-info/licenses/LICENSE +24 -0
  246. coco_framework-0.1.0.dist-info/licenses/NOTICE +15 -0
  247. coco_graph/_internal/__init__.py +4 -0
  248. coco_graph/_internal/_cache.py +31 -0
  249. coco_graph/_internal/_config.py +474 -0
  250. coco_graph/_internal/_constants.py +140 -0
  251. coco_graph/_internal/_fields.py +213 -0
  252. coco_graph/_internal/_future.py +220 -0
  253. coco_graph/_internal/_pydantic.py +275 -0
  254. coco_graph/_internal/_queue.py +124 -0
  255. coco_graph/_internal/_replay.py +90 -0
  256. coco_graph/_internal/_retry.py +29 -0
  257. coco_graph/_internal/_runnable.py +969 -0
  258. coco_graph/_internal/_scratchpad.py +19 -0
  259. coco_graph/_internal/_serde.py +253 -0
  260. coco_graph/_internal/_timeout.py +25 -0
  261. coco_graph/_internal/_typing.py +54 -0
  262. coco_graph/cache/base/__init__.py +48 -0
  263. coco_graph/cache/base/py.typed +0 -0
  264. coco_graph/cache/memory/__init__.py +73 -0
  265. coco_graph/cache/redis/__init__.py +144 -0
  266. coco_graph/cache/sqlite/__init__.py +120 -0
  267. coco_graph/callbacks.py +394 -0
  268. coco_graph/channels/__init__.py +29 -0
  269. coco_graph/channels/any_value.py +72 -0
  270. coco_graph/channels/base.py +121 -0
  271. coco_graph/channels/binop.py +155 -0
  272. coco_graph/channels/delta.py +202 -0
  273. coco_graph/channels/ephemeral_value.py +79 -0
  274. coco_graph/channels/last_value.py +151 -0
  275. coco_graph/channels/named_barrier_value.py +167 -0
  276. coco_graph/channels/topic.py +94 -0
  277. coco_graph/channels/untracked_value.py +73 -0
  278. coco_graph/checkpoint/base/__init__.py +861 -0
  279. coco_graph/checkpoint/base/id.py +109 -0
  280. coco_graph/checkpoint/base/py.typed +0 -0
  281. coco_graph/checkpoint/memory/__init__.py +698 -0
  282. coco_graph/checkpoint/memory/py.typed +0 -0
  283. coco_graph/checkpoint/postgres/__init__.py +602 -0
  284. coco_graph/checkpoint/postgres/_ainternal.py +23 -0
  285. coco_graph/checkpoint/postgres/_internal.py +21 -0
  286. coco_graph/checkpoint/postgres/aio.py +691 -0
  287. coco_graph/checkpoint/postgres/base.py +666 -0
  288. coco_graph/checkpoint/postgres/py.typed +0 -0
  289. coco_graph/checkpoint/postgres/shallow.py +967 -0
  290. coco_graph/checkpoint/serde/__init__.py +0 -0
  291. coco_graph/checkpoint/serde/_msgpack.py +97 -0
  292. coco_graph/checkpoint/serde/base.py +64 -0
  293. coco_graph/checkpoint/serde/encrypted.py +80 -0
  294. coco_graph/checkpoint/serde/event_hooks.py +52 -0
  295. coco_graph/checkpoint/serde/jsonplus.py +883 -0
  296. coco_graph/checkpoint/serde/py.typed +0 -0
  297. coco_graph/checkpoint/serde/types.py +68 -0
  298. coco_graph/checkpoint/sqlite/__init__.py +645 -0
  299. coco_graph/checkpoint/sqlite/_delta.py +172 -0
  300. coco_graph/checkpoint/sqlite/aio.py +738 -0
  301. coco_graph/checkpoint/sqlite/py.typed +0 -0
  302. coco_graph/checkpoint/sqlite/utils.py +116 -0
  303. coco_graph/config.py +196 -0
  304. coco_graph/constants.py +64 -0
  305. coco_graph/errors.py +241 -0
  306. coco_graph/func/__init__.py +620 -0
  307. coco_graph/graph/__init__.py +12 -0
  308. coco_graph/graph/_branch.py +225 -0
  309. coco_graph/graph/_node.py +103 -0
  310. coco_graph/graph/message.py +437 -0
  311. coco_graph/graph/state.py +1978 -0
  312. coco_graph/graph/ui.py +227 -0
  313. coco_graph/managed/__init__.py +3 -0
  314. coco_graph/managed/base.py +31 -0
  315. coco_graph/managed/is_last_step.py +24 -0
  316. coco_graph/prebuilt/__init__.py +23 -0
  317. coco_graph/prebuilt/_tool_call_stream.py +117 -0
  318. coco_graph/prebuilt/_tool_call_transformer.py +165 -0
  319. coco_graph/prebuilt/chat_agent_executor.py +1015 -0
  320. coco_graph/prebuilt/interrupt.py +105 -0
  321. coco_graph/prebuilt/py.typed +0 -0
  322. coco_graph/prebuilt/tool_node.py +2030 -0
  323. coco_graph/prebuilt/tool_validator.py +221 -0
  324. coco_graph/pregel/__init__.py +3 -0
  325. coco_graph/pregel/_algo.py +1460 -0
  326. coco_graph/pregel/_call.py +298 -0
  327. coco_graph/pregel/_checkpoint.py +331 -0
  328. coco_graph/pregel/_config.py +0 -0
  329. coco_graph/pregel/_draw.py +294 -0
  330. coco_graph/pregel/_executor.py +223 -0
  331. coco_graph/pregel/_io.py +174 -0
  332. coco_graph/pregel/_log.py +3 -0
  333. coco_graph/pregel/_loop.py +1988 -0
  334. coco_graph/pregel/_messages.py +461 -0
  335. coco_graph/pregel/_read.py +312 -0
  336. coco_graph/pregel/_retry.py +854 -0
  337. coco_graph/pregel/_runner.py +941 -0
  338. coco_graph/pregel/_tools.py +268 -0
  339. coco_graph/pregel/_utils.py +221 -0
  340. coco_graph/pregel/_validate.py +120 -0
  341. coco_graph/pregel/_write.py +192 -0
  342. coco_graph/pregel/debug.py +302 -0
  343. coco_graph/pregel/main.py +4364 -0
  344. coco_graph/pregel/protocol.py +288 -0
  345. coco_graph/pregel/types.py +38 -0
  346. coco_graph/py.typed +0 -0
  347. coco_graph/runtime.py +350 -0
  348. coco_graph/store/base/__init__.py +1322 -0
  349. coco_graph/store/base/batch.py +371 -0
  350. coco_graph/store/base/embed.py +436 -0
  351. coco_graph/store/base/py.typed +0 -0
  352. coco_graph/store/memory/__init__.py +592 -0
  353. coco_graph/store/memory/py.typed +0 -0
  354. coco_graph/store/postgres/__init__.py +4 -0
  355. coco_graph/store/postgres/aio.py +592 -0
  356. coco_graph/store/postgres/base.py +1480 -0
  357. coco_graph/store/postgres/py.typed +0 -0
  358. coco_graph/store/sqlite/__init__.py +4 -0
  359. coco_graph/store/sqlite/aio.py +632 -0
  360. coco_graph/store/sqlite/base.py +1514 -0
  361. coco_graph/stream/__init__.py +45 -0
  362. coco_graph/stream/_convert.py +32 -0
  363. coco_graph/stream/_mux.py +523 -0
  364. coco_graph/stream/_types.py +330 -0
  365. coco_graph/stream/run_stream.py +735 -0
  366. coco_graph/stream/stream_channel.py +341 -0
  367. coco_graph/stream/transformers.py +1039 -0
  368. coco_graph/types.py +1079 -0
  369. coco_graph/typing.py +48 -0
  370. coco_graph/utils/__init__.py +1 -0
  371. coco_graph/utils/config.py +4 -0
  372. coco_graph/utils/runnable.py +3 -0
  373. coco_graph/version.py +13 -0
  374. coco_graph/warnings.py +69 -0
  375. coco_openai/__init__.py +20 -0
  376. coco_openai/_compat.py +45 -0
  377. coco_openai/_version.py +3 -0
  378. coco_openai/chat_models/__init__.py +6 -0
  379. coco_openai/chat_models/_client_utils.py +684 -0
  380. coco_openai/chat_models/_compat.py +525 -0
  381. coco_openai/chat_models/azure.py +1227 -0
  382. coco_openai/chat_models/base.py +5654 -0
  383. coco_openai/chat_models/codex.py +557 -0
  384. coco_openai/chatgpt_oauth.py +1063 -0
  385. coco_openai/data/__init__.py +1 -0
  386. coco_openai/data/_profiles.py +1655 -0
  387. coco_openai/data/profile_augmentations.toml +127 -0
  388. coco_openai/embeddings/__init__.py +6 -0
  389. coco_openai/embeddings/azure.py +240 -0
  390. coco_openai/embeddings/base.py +820 -0
  391. coco_openai/llms/__init__.py +6 -0
  392. coco_openai/llms/azure.py +249 -0
  393. coco_openai/llms/base.py +919 -0
  394. coco_openai/middleware/__init__.py +11 -0
  395. coco_openai/middleware/openai_moderation.py +484 -0
  396. coco_openai/output_parsers/__init__.py +9 -0
  397. coco_openai/output_parsers/tools.py +9 -0
  398. coco_openai/py.typed +0 -0
  399. coco_openai/tools/__init__.py +5 -0
  400. coco_openai/tools/custom_tool.py +111 -0
@@ -0,0 +1,366 @@
1
+ """Example selector that selects examples based on SemanticSimilarity."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ from pydantic import BaseModel, ConfigDict
9
+
10
+ from coco_core.example_selectors.base import BaseExampleSelector
11
+ from coco_core.vectorstores import VectorStore
12
+
13
+ if TYPE_CHECKING:
14
+ from coco_core.documents import Document
15
+ from coco_core.embeddings import Embeddings
16
+
17
+
18
+ def sorted_values(values: dict[str, str]) -> list[str]:
19
+ """Return a list of values in dict sorted by key.
20
+
21
+ Args:
22
+ values: A dictionary with keys as input variables
23
+ and values as their values.
24
+
25
+ Returns:
26
+ A list of values in dict sorted by key.
27
+ """
28
+ return [values[val] for val in sorted(values)]
29
+
30
+
31
+ class _VectorStoreExampleSelector(BaseExampleSelector, BaseModel, ABC):
32
+ """Example selector that selects examples based on SemanticSimilarity."""
33
+
34
+ vectorstore: VectorStore
35
+ """VectorStore that contains information about examples."""
36
+
37
+ k: int = 4
38
+ """Number of examples to select."""
39
+
40
+ example_keys: list[str] | None = None
41
+ """Optional keys to filter examples to."""
42
+
43
+ input_keys: list[str] | None = None
44
+ """Optional keys to filter input to. If provided, the search is based on
45
+ the input variables instead of all variables."""
46
+
47
+ vectorstore_kwargs: dict[str, Any] | None = None
48
+ """Extra arguments passed to similarity_search function of the `VectorStore`."""
49
+
50
+ model_config = ConfigDict(
51
+ arbitrary_types_allowed=True,
52
+ extra="forbid",
53
+ )
54
+
55
+ @staticmethod
56
+ def _example_to_text(example: dict[str, str], input_keys: list[str] | None) -> str:
57
+ if input_keys:
58
+ return " ".join(sorted_values({key: example[key] for key in input_keys}))
59
+ return " ".join(sorted_values(example))
60
+
61
+ def _documents_to_examples(self, documents: list[Document]) -> list[dict[str, Any]]:
62
+ # Get the examples from the metadata.
63
+ # This assumes that examples are stored in metadata.
64
+ examples = [dict(e.metadata) for e in documents]
65
+ # If example keys are provided, filter examples to those keys.
66
+ if self.example_keys:
67
+ examples = [{k: eg[k] for k in self.example_keys} for eg in examples]
68
+ return examples
69
+
70
+ def add_example(self, example: dict[str, str]) -> str:
71
+ """Add a new example to vectorstore.
72
+
73
+ Args:
74
+ example: A dictionary with keys as input variables
75
+ and values as their values.
76
+
77
+ Returns:
78
+ The ID of the added example.
79
+ """
80
+ ids = self.vectorstore.add_texts(
81
+ [self._example_to_text(example, self.input_keys)], metadatas=[example]
82
+ )
83
+ return ids[0]
84
+
85
+ async def aadd_example(self, example: dict[str, str]) -> str:
86
+ """Async add new example to vectorstore.
87
+
88
+ Args:
89
+ example: A dictionary with keys as input variables
90
+ and values as their values.
91
+
92
+ Returns:
93
+ The ID of the added example.
94
+ """
95
+ ids = await self.vectorstore.aadd_texts(
96
+ [self._example_to_text(example, self.input_keys)], metadatas=[example]
97
+ )
98
+ return ids[0]
99
+
100
+
101
+ class SemanticSimilarityExampleSelector(_VectorStoreExampleSelector):
102
+ """Select examples based on semantic similarity."""
103
+
104
+ def select_examples(self, input_variables: dict[str, str]) -> list[dict[str, Any]]:
105
+ """Select examples based on semantic similarity.
106
+
107
+ Args:
108
+ input_variables: The input variables to use for search.
109
+
110
+ Returns:
111
+ The selected examples.
112
+ """
113
+ # Get the docs with the highest similarity.
114
+ vectorstore_kwargs = self.vectorstore_kwargs or {}
115
+ example_docs = self.vectorstore.similarity_search(
116
+ self._example_to_text(input_variables, self.input_keys),
117
+ k=self.k,
118
+ **vectorstore_kwargs,
119
+ )
120
+ return self._documents_to_examples(example_docs)
121
+
122
+ async def aselect_examples(
123
+ self, input_variables: dict[str, str]
124
+ ) -> list[dict[str, Any]]:
125
+ """Asynchronously select examples based on semantic similarity.
126
+
127
+ Args:
128
+ input_variables: The input variables to use for search.
129
+
130
+ Returns:
131
+ The selected examples.
132
+ """
133
+ # Get the docs with the highest similarity.
134
+ vectorstore_kwargs = self.vectorstore_kwargs or {}
135
+ example_docs = await self.vectorstore.asimilarity_search(
136
+ self._example_to_text(input_variables, self.input_keys),
137
+ k=self.k,
138
+ **vectorstore_kwargs,
139
+ )
140
+ return self._documents_to_examples(example_docs)
141
+
142
+ @classmethod
143
+ def from_examples(
144
+ cls,
145
+ examples: list[dict[str, str]],
146
+ embeddings: Embeddings,
147
+ vectorstore_cls: type[VectorStore],
148
+ k: int = 4,
149
+ input_keys: list[str] | None = None,
150
+ *,
151
+ example_keys: list[str] | None = None,
152
+ vectorstore_kwargs: dict[str, Any] | None = None,
153
+ **vectorstore_cls_kwargs: Any,
154
+ ) -> SemanticSimilarityExampleSelector:
155
+ """Create k-shot example selector using example list and embeddings.
156
+
157
+ Reshuffles examples dynamically based on query similarity.
158
+
159
+ Args:
160
+ examples: List of examples to use in the prompt.
161
+ embeddings: An initialized embedding API interface, e.g. OpenAIEmbeddings().
162
+ vectorstore_cls: A vector store DB interface class, e.g. FAISS.
163
+ k: Number of examples to select.
164
+ input_keys: If provided, the search is based on the input variables
165
+ instead of all variables.
166
+ example_keys: If provided, keys to filter examples to.
167
+ vectorstore_kwargs: Extra arguments passed to similarity_search function
168
+ of the `VectorStore`.
169
+ vectorstore_cls_kwargs: optional kwargs containing url for vector store
170
+
171
+ Returns:
172
+ The ExampleSelector instantiated, backed by a vector store.
173
+ """
174
+ string_examples = [cls._example_to_text(eg, input_keys) for eg in examples]
175
+ vectorstore = vectorstore_cls.from_texts(
176
+ string_examples, embeddings, metadatas=examples, **vectorstore_cls_kwargs
177
+ )
178
+ return cls(
179
+ vectorstore=vectorstore,
180
+ k=k,
181
+ input_keys=input_keys,
182
+ example_keys=example_keys,
183
+ vectorstore_kwargs=vectorstore_kwargs,
184
+ )
185
+
186
+ @classmethod
187
+ async def afrom_examples(
188
+ cls,
189
+ examples: list[dict[str, str]],
190
+ embeddings: Embeddings,
191
+ vectorstore_cls: type[VectorStore],
192
+ k: int = 4,
193
+ input_keys: list[str] | None = None,
194
+ *,
195
+ example_keys: list[str] | None = None,
196
+ vectorstore_kwargs: dict[str, Any] | None = None,
197
+ **vectorstore_cls_kwargs: Any,
198
+ ) -> SemanticSimilarityExampleSelector:
199
+ """Async create k-shot example selector using example list and embeddings.
200
+
201
+ Reshuffles examples dynamically based on query similarity.
202
+
203
+ Args:
204
+ examples: List of examples to use in the prompt.
205
+ embeddings: An initialized embedding API interface, e.g. OpenAIEmbeddings().
206
+ vectorstore_cls: A vector store DB interface class, e.g. FAISS.
207
+ k: Number of examples to select.
208
+ input_keys: If provided, the search is based on the input variables
209
+ instead of all variables.
210
+ example_keys: If provided, keys to filter examples to.
211
+ vectorstore_kwargs: Extra arguments passed to similarity_search function
212
+ of the `VectorStore`.
213
+ vectorstore_cls_kwargs: optional kwargs containing url for vector store
214
+
215
+ Returns:
216
+ The ExampleSelector instantiated, backed by a vector store.
217
+ """
218
+ string_examples = [cls._example_to_text(eg, input_keys) for eg in examples]
219
+ vectorstore = await vectorstore_cls.afrom_texts(
220
+ string_examples, embeddings, metadatas=examples, **vectorstore_cls_kwargs
221
+ )
222
+ return cls(
223
+ vectorstore=vectorstore,
224
+ k=k,
225
+ input_keys=input_keys,
226
+ example_keys=example_keys,
227
+ vectorstore_kwargs=vectorstore_kwargs,
228
+ )
229
+
230
+
231
+ class MaxMarginalRelevanceExampleSelector(_VectorStoreExampleSelector):
232
+ """Select examples based on Max Marginal Relevance.
233
+
234
+ This was shown to improve performance in this paper:
235
+ https://arxiv.org/pdf/2211.13892.pdf
236
+ """
237
+
238
+ fetch_k: int = 20
239
+ """Number of examples to fetch to rerank."""
240
+
241
+ def select_examples(self, input_variables: dict[str, str]) -> list[dict[str, Any]]:
242
+ """Select examples based on Max Marginal Relevance.
243
+
244
+ Args:
245
+ input_variables: The input variables to use for search.
246
+
247
+ Returns:
248
+ The selected examples.
249
+ """
250
+ example_docs = self.vectorstore.max_marginal_relevance_search(
251
+ self._example_to_text(input_variables, self.input_keys),
252
+ k=self.k,
253
+ fetch_k=self.fetch_k,
254
+ )
255
+ return self._documents_to_examples(example_docs)
256
+
257
+ async def aselect_examples(
258
+ self, input_variables: dict[str, str]
259
+ ) -> list[dict[str, Any]]:
260
+ """Asynchronously select examples based on Max Marginal Relevance.
261
+
262
+ Args:
263
+ input_variables: The input variables to use for search.
264
+
265
+ Returns:
266
+ The selected examples.
267
+ """
268
+ example_docs = await self.vectorstore.amax_marginal_relevance_search(
269
+ self._example_to_text(input_variables, self.input_keys),
270
+ k=self.k,
271
+ fetch_k=self.fetch_k,
272
+ )
273
+ return self._documents_to_examples(example_docs)
274
+
275
+ @classmethod
276
+ def from_examples(
277
+ cls,
278
+ examples: list[dict[str, str]],
279
+ embeddings: Embeddings,
280
+ vectorstore_cls: type[VectorStore],
281
+ k: int = 4,
282
+ input_keys: list[str] | None = None,
283
+ fetch_k: int = 20,
284
+ example_keys: list[str] | None = None,
285
+ vectorstore_kwargs: dict[str, Any] | None = None,
286
+ **vectorstore_cls_kwargs: Any,
287
+ ) -> MaxMarginalRelevanceExampleSelector:
288
+ """Create k-shot example selector using example list and embeddings.
289
+
290
+ Reshuffles examples dynamically based on Max Marginal Relevance.
291
+
292
+ Args:
293
+ examples: List of examples to use in the prompt.
294
+ embeddings: An initialized embedding API interface, e.g. OpenAIEmbeddings().
295
+ vectorstore_cls: A vector store DB interface class, e.g. FAISS.
296
+ k: Number of examples to select.
297
+ fetch_k: Number of `Document` objects to fetch to pass to MMR algorithm.
298
+ input_keys: If provided, the search is based on the input variables
299
+ instead of all variables.
300
+ example_keys: If provided, keys to filter examples to.
301
+ vectorstore_kwargs: Extra arguments passed to similarity_search function
302
+ of the `VectorStore`.
303
+ vectorstore_cls_kwargs: optional kwargs containing url for vector store
304
+
305
+ Returns:
306
+ The ExampleSelector instantiated, backed by a vector store.
307
+ """
308
+ string_examples = [cls._example_to_text(eg, input_keys) for eg in examples]
309
+ vectorstore = vectorstore_cls.from_texts(
310
+ string_examples, embeddings, metadatas=examples, **vectorstore_cls_kwargs
311
+ )
312
+ return cls(
313
+ vectorstore=vectorstore,
314
+ k=k,
315
+ fetch_k=fetch_k,
316
+ input_keys=input_keys,
317
+ example_keys=example_keys,
318
+ vectorstore_kwargs=vectorstore_kwargs,
319
+ )
320
+
321
+ @classmethod
322
+ async def afrom_examples(
323
+ cls,
324
+ examples: list[dict[str, str]],
325
+ embeddings: Embeddings,
326
+ vectorstore_cls: type[VectorStore],
327
+ *,
328
+ k: int = 4,
329
+ input_keys: list[str] | None = None,
330
+ fetch_k: int = 20,
331
+ example_keys: list[str] | None = None,
332
+ vectorstore_kwargs: dict[str, Any] | None = None,
333
+ **vectorstore_cls_kwargs: Any,
334
+ ) -> MaxMarginalRelevanceExampleSelector:
335
+ """Create k-shot example selector using example list and embeddings.
336
+
337
+ Reshuffles examples dynamically based on Max Marginal Relevance.
338
+
339
+ Args:
340
+ examples: List of examples to use in the prompt.
341
+ embeddings: An initialized embedding API interface, e.g. OpenAIEmbeddings().
342
+ vectorstore_cls: A vector store DB interface class, e.g. FAISS.
343
+ k: Number of examples to select.
344
+ fetch_k: Number of `Document` objects to fetch to pass to MMR algorithm.
345
+ input_keys: If provided, the search is based on the input variables
346
+ instead of all variables.
347
+ example_keys: If provided, keys to filter examples to.
348
+ vectorstore_kwargs: Extra arguments passed to similarity_search function
349
+ of the `VectorStore`.
350
+ vectorstore_cls_kwargs: optional kwargs containing url for vector store
351
+
352
+ Returns:
353
+ The ExampleSelector instantiated, backed by a vector store.
354
+ """
355
+ string_examples = [cls._example_to_text(eg, input_keys) for eg in examples]
356
+ vectorstore = await vectorstore_cls.afrom_texts(
357
+ string_examples, embeddings, metadatas=examples, **vectorstore_cls_kwargs
358
+ )
359
+ return cls(
360
+ vectorstore=vectorstore,
361
+ k=k,
362
+ fetch_k=fetch_k,
363
+ input_keys=input_keys,
364
+ example_keys=example_keys,
365
+ vectorstore_kwargs=vectorstore_kwargs,
366
+ )
@@ -0,0 +1,166 @@
1
+ """Custom **exceptions** for Coco."""
2
+
3
+ from enum import Enum
4
+ from typing import Any
5
+
6
+
7
+ class CocoException(Exception): # noqa: N818
8
+ """General Coco exception."""
9
+
10
+
11
+ class TracerException(CocoException):
12
+ """Base class for exceptions in tracers module."""
13
+
14
+
15
+ class OutputParserException(ValueError, CocoException): # noqa: N818
16
+ """Exception that output parsers should raise to signify a parsing error.
17
+
18
+ This exists to differentiate parsing errors from other code or execution errors
19
+ that also may arise inside the output parser.
20
+
21
+ `OutputParserException` will be available to catch and handle in ways to fix the
22
+ parsing error, while other errors will be raised.
23
+ """
24
+
25
+ def __init__(
26
+ self,
27
+ error: Any,
28
+ observation: str | None = None,
29
+ llm_output: str | None = None,
30
+ send_to_llm: bool = False, # noqa: FBT001,FBT002
31
+ ):
32
+ """Create an `OutputParserException`.
33
+
34
+ Args:
35
+ error: The error that's being re-raised or an error message.
36
+ observation: String explanation of error which can be passed to a model to
37
+ try and remediate the issue.
38
+ llm_output: String model output which is error-ing.
39
+
40
+ send_to_llm: Whether to send the observation and llm_output back to an Agent
41
+ after an `OutputParserException` has been raised.
42
+
43
+ This gives the underlying model driving the agent the context that the
44
+ previous output was improperly structured, in the hopes that it will
45
+ update the output to the correct format.
46
+
47
+ Raises:
48
+ ValueError: If `send_to_llm` is `True` but either observation or
49
+ `llm_output` are not provided.
50
+ """
51
+ if isinstance(error, str):
52
+ error = create_message(
53
+ message=error, error_code=ErrorCode.OUTPUT_PARSING_FAILURE
54
+ )
55
+
56
+ super().__init__(error)
57
+ if send_to_llm and (observation is None or llm_output is None):
58
+ msg = (
59
+ "Arguments 'observation' & 'llm_output'"
60
+ " are required if 'send_to_llm' is True"
61
+ )
62
+ raise ValueError(msg)
63
+ self.observation = observation
64
+ self.llm_output = llm_output
65
+ self.send_to_llm = send_to_llm
66
+
67
+
68
+ class ModelError(CocoException):
69
+ """Base exception for failures related to model invocation.
70
+
71
+ Subclasses correspond to conditions that model providers report consistently,
72
+ keyed to the HTTP status they surface it with, so the same condition maps to
73
+ the same exception type regardless of provider.
74
+
75
+ Provider integrations raise subclasses that also inherit from the provider
76
+ SDK's own exception type, so code catching either continues to work.
77
+ """
78
+
79
+ is_retryable = False
80
+ """Whether retrying the same model request may succeed."""
81
+
82
+
83
+ class ModelAuthenticationError(ModelError):
84
+ """Exception raised when model provider authentication fails (HTTP 401)."""
85
+
86
+
87
+ class ModelPermissionDeniedError(ModelError):
88
+ """Exception raised when credentials lack permission for a request (HTTP 403)."""
89
+
90
+
91
+ class ModelInvalidRequestError(ModelError):
92
+ """Exception raised when a provider rejects a request as invalid (e.g. HTTP 400)."""
93
+
94
+
95
+ class ModelNotFoundError(ModelError):
96
+ """Exception raised when the requested model cannot be found (HTTP 404)."""
97
+
98
+
99
+ class ModelRateLimitError(ModelError):
100
+ """Exception raised when a model provider rate limit is exceeded (HTTP 429)."""
101
+
102
+ is_retryable = True
103
+
104
+
105
+ class ModelAPIError(ModelError):
106
+ """Exception raised when a model provider reports a server failure (HTTP 5xx)."""
107
+
108
+ is_retryable = True
109
+
110
+
111
+ class ModelConnectionError(ModelError):
112
+ """Exception raised when a model provider cannot be reached."""
113
+
114
+ is_retryable = True
115
+
116
+
117
+ class ModelTimeoutError(ModelError):
118
+ """Exception raised when a model request times out."""
119
+
120
+ is_retryable = True
121
+
122
+
123
+ class ContextOverflowError(ModelError):
124
+ """Exception raised when input exceeds the model's context limit.
125
+
126
+ This exception is raised by chat models when the input tokens exceed
127
+ the maximum context window supported by the model.
128
+ """
129
+
130
+
131
+ class ErrorCode(Enum):
132
+ """Error codes."""
133
+
134
+ INVALID_PROMPT_INPUT = "INVALID_PROMPT_INPUT"
135
+ INVALID_TOOL_RESULTS = "INVALID_TOOL_RESULTS" # Used in JS; not Py (yet)
136
+ MESSAGE_COERCION_FAILURE = "MESSAGE_COERCION_FAILURE"
137
+ MODEL_AUTHENTICATION = "MODEL_AUTHENTICATION" # Used in JS; not Py (yet)
138
+ MODEL_NOT_FOUND = "MODEL_NOT_FOUND" # Used in JS; not Py (yet)
139
+ MODEL_RATE_LIMIT = "MODEL_RATE_LIMIT" # Used in JS; not Py (yet)
140
+ OUTPUT_PARSING_FAILURE = "OUTPUT_PARSING_FAILURE"
141
+
142
+
143
+ def create_message(*, message: str, error_code: ErrorCode) -> str:
144
+ """Create a message with a link to the Coco troubleshooting guide.
145
+
146
+ Args:
147
+ message: The message to display.
148
+ error_code: The error code to display.
149
+
150
+ Returns:
151
+ The full message with the troubleshooting link.
152
+
153
+ Example:
154
+ ```python
155
+ create_message(
156
+ message="Failed to parse output",
157
+ error_code=ErrorCode.OUTPUT_PARSING_FAILURE,
158
+ )
159
+ "Failed to parse output. For troubleshooting, visit: ..."
160
+ ```
161
+ """
162
+ return (
163
+ f"{message}\n"
164
+ "For troubleshooting, visit: https://docs.langchain.com/oss/python/langchain"
165
+ f"/errors/{error_code.value} "
166
+ )
coco_core/globals.py ADDED
@@ -0,0 +1,72 @@
1
+ """Global values and configuration that apply to all of Coco."""
2
+
3
+ from typing import TYPE_CHECKING, Optional
4
+
5
+ if TYPE_CHECKING:
6
+ from coco_core.caches import BaseCache
7
+
8
+
9
+ # DO NOT USE THESE VALUES DIRECTLY!
10
+ # Use them only via `get_<X>()` and `set_<X>()` below,
11
+ # or else your code may behave unexpectedly with other uses of these global settings:
12
+ # https://github.com/langchain-ai/langchain/pull/11311#issuecomment-1743780004
13
+ _verbose: bool = False
14
+ _debug: bool = False
15
+ _llm_cache: Optional["BaseCache"] = None
16
+
17
+
18
+ def set_verbose(value: bool) -> None: # noqa: FBT001
19
+ """Set a new value for the `verbose` global setting.
20
+
21
+ Args:
22
+ value: The new value for the `verbose` global setting.
23
+ """
24
+ global _verbose # noqa: PLW0603
25
+ _verbose = value
26
+
27
+
28
+ def get_verbose() -> bool:
29
+ """Get the value of the `verbose` global setting.
30
+
31
+ Returns:
32
+ The value of the `verbose` global setting.
33
+ """
34
+ return _verbose
35
+
36
+
37
+ def set_debug(value: bool) -> None: # noqa: FBT001
38
+ """Set a new value for the `debug` global setting.
39
+
40
+ Args:
41
+ value: The new value for the `debug` global setting.
42
+ """
43
+ global _debug # noqa: PLW0603
44
+ _debug = value
45
+
46
+
47
+ def get_debug() -> bool:
48
+ """Get the value of the `debug` global setting.
49
+
50
+ Returns:
51
+ The value of the `debug` global setting.
52
+ """
53
+ return _debug
54
+
55
+
56
+ def set_llm_cache(value: Optional["BaseCache"]) -> None:
57
+ """Set a new LLM cache, overwriting the previous value, if any.
58
+
59
+ Args:
60
+ value: The new LLM cache to use. If `None`, the LLM cache is disabled.
61
+ """
62
+ global _llm_cache # noqa: PLW0603
63
+ _llm_cache = value
64
+
65
+
66
+ def get_llm_cache() -> Optional["BaseCache"]:
67
+ """Get the value of the `llm_cache` global setting.
68
+
69
+ Returns:
70
+ The value of the `llm_cache` global setting.
71
+ """
72
+ return _llm_cache
@@ -0,0 +1,53 @@
1
+ """Code to help indexing data into a vectorstore.
2
+
3
+ This package contains helper logic to help deal with indexing data into
4
+ a `VectorStore` while avoiding duplicated content and over-writing content
5
+ if it's unchanged.
6
+ """
7
+
8
+ from typing import TYPE_CHECKING
9
+
10
+ from coco_core._import_utils import import_attr
11
+
12
+ if TYPE_CHECKING:
13
+ from coco_core.indexing.api import IndexingResult, aindex, index
14
+ from coco_core.indexing.base import (
15
+ DeleteResponse,
16
+ DocumentIndex,
17
+ InMemoryRecordManager,
18
+ RecordManager,
19
+ UpsertResponse,
20
+ )
21
+
22
+ __all__ = (
23
+ "DeleteResponse",
24
+ "DocumentIndex",
25
+ "InMemoryRecordManager",
26
+ "IndexingResult",
27
+ "RecordManager",
28
+ "UpsertResponse",
29
+ "aindex",
30
+ "index",
31
+ )
32
+
33
+ _dynamic_imports = {
34
+ "aindex": "api",
35
+ "index": "api",
36
+ "IndexingResult": "api",
37
+ "DeleteResponse": "base",
38
+ "DocumentIndex": "base",
39
+ "InMemoryRecordManager": "base",
40
+ "RecordManager": "base",
41
+ "UpsertResponse": "base",
42
+ }
43
+
44
+
45
+ def __getattr__(attr_name: str) -> object:
46
+ module_name = _dynamic_imports.get(attr_name)
47
+ result = import_attr(attr_name, module_name, __spec__.parent)
48
+ globals()[attr_name] = result
49
+ return result
50
+
51
+
52
+ def __dir__() -> list[str]:
53
+ return list(__all__)