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,74 @@
1
+ """Document compressor."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from typing import TYPE_CHECKING
7
+
8
+ from pydantic import BaseModel
9
+
10
+ from coco_core.runnables import run_in_executor
11
+
12
+ if TYPE_CHECKING:
13
+ from collections.abc import Sequence
14
+
15
+ from coco_core.callbacks import Callbacks
16
+ from coco_core.documents import Document
17
+
18
+
19
+ class BaseDocumentCompressor(BaseModel, ABC):
20
+ """Base class for document compressors.
21
+
22
+ This abstraction is primarily used for post-processing of retrieved documents.
23
+
24
+ `Document` objects matching a given query are first retrieved.
25
+
26
+ Then the list of documents can be further processed.
27
+
28
+ For example, one could re-rank the retrieved documents using an LLM.
29
+
30
+ !!! note
31
+ Users should favor using a `RunnableLambda` instead of sub-classing from this
32
+ interface.
33
+
34
+ """
35
+
36
+ @abstractmethod
37
+ def compress_documents(
38
+ self,
39
+ documents: Sequence[Document],
40
+ query: str,
41
+ callbacks: Callbacks | None = None,
42
+ ) -> Sequence[Document]:
43
+ """Compress retrieved documents given the query context.
44
+
45
+ Args:
46
+ documents: The retrieved `Document` objects.
47
+ query: The query context.
48
+ callbacks: Optional `Callbacks` to run during compression.
49
+
50
+ Returns:
51
+ The compressed documents.
52
+
53
+ """
54
+
55
+ async def acompress_documents(
56
+ self,
57
+ documents: Sequence[Document],
58
+ query: str,
59
+ callbacks: Callbacks | None = None,
60
+ ) -> Sequence[Document]:
61
+ """Async compress retrieved documents given the query context.
62
+
63
+ Args:
64
+ documents: The retrieved `Document` objects.
65
+ query: The query context.
66
+ callbacks: Optional `Callbacks` to run during compression.
67
+
68
+ Returns:
69
+ The compressed documents.
70
+
71
+ """
72
+ return await run_in_executor(
73
+ None, self.compress_documents, documents, query, callbacks
74
+ )
@@ -0,0 +1,79 @@
1
+ """Document transformers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ from coco_core.runnables.config import run_in_executor
9
+
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Sequence
12
+
13
+ from coco_core.documents import Document
14
+
15
+
16
+ class BaseDocumentTransformer(ABC):
17
+ """Abstract base class for document transformation.
18
+
19
+ A document transformation takes a sequence of `Document` objects and returns a
20
+ sequence of transformed `Document` objects.
21
+
22
+ Example:
23
+ ```python
24
+ class EmbeddingsRedundantFilter(BaseDocumentTransformer, BaseModel):
25
+ embeddings: Embeddings
26
+ similarity_fn: Callable = cosine_similarity
27
+ similarity_threshold: float = 0.95
28
+
29
+ class Config:
30
+ arbitrary_types_allowed = True
31
+
32
+ def transform_documents(
33
+ self, documents: Sequence[Document], **kwargs: Any
34
+ ) -> Sequence[Document]:
35
+ stateful_documents = get_stateful_documents(documents)
36
+ embedded_documents = _get_embeddings_from_stateful_docs(
37
+ self.embeddings, stateful_documents
38
+ )
39
+ included_idxs = _filter_similar_embeddings(
40
+ embedded_documents,
41
+ self.similarity_fn,
42
+ self.similarity_threshold,
43
+ )
44
+ return [stateful_documents[i] for i in sorted(included_idxs)]
45
+
46
+ async def atransform_documents(
47
+ self, documents: Sequence[Document], **kwargs: Any
48
+ ) -> Sequence[Document]:
49
+ raise NotImplementedError
50
+ ```
51
+ """
52
+
53
+ @abstractmethod
54
+ def transform_documents(
55
+ self, documents: Sequence[Document], **kwargs: Any
56
+ ) -> Sequence[Document]:
57
+ """Transform a list of documents.
58
+
59
+ Args:
60
+ documents: A sequence of `Document` objects to be transformed.
61
+
62
+ Returns:
63
+ A sequence of transformed `Document` objects.
64
+ """
65
+
66
+ async def atransform_documents(
67
+ self, documents: Sequence[Document], **kwargs: Any
68
+ ) -> Sequence[Document]:
69
+ """Asynchronously transform a list of documents.
70
+
71
+ Args:
72
+ documents: A sequence of `Document` objects to be transformed.
73
+
74
+ Returns:
75
+ A sequence of transformed `Document` objects.
76
+ """
77
+ return await run_in_executor(
78
+ None, self.transform_documents, documents, **kwargs
79
+ )
@@ -0,0 +1,31 @@
1
+ """Embeddings."""
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from coco_core._import_utils import import_attr
6
+
7
+ if TYPE_CHECKING:
8
+ from coco_core.embeddings.embeddings import Embeddings
9
+ from coco_core.embeddings.fake import (
10
+ DeterministicFakeEmbedding,
11
+ FakeEmbeddings,
12
+ )
13
+
14
+ __all__ = ("DeterministicFakeEmbedding", "Embeddings", "FakeEmbeddings")
15
+
16
+ _dynamic_imports = {
17
+ "Embeddings": "embeddings",
18
+ "DeterministicFakeEmbedding": "fake",
19
+ "FakeEmbeddings": "fake",
20
+ }
21
+
22
+
23
+ def __getattr__(attr_name: str) -> object:
24
+ module_name = _dynamic_imports.get(attr_name)
25
+ result = import_attr(attr_name, module_name, __spec__.parent)
26
+ globals()[attr_name] = result
27
+ return result
28
+
29
+
30
+ def __dir__() -> list[str]:
31
+ return list(__all__)
@@ -0,0 +1,78 @@
1
+ """**Embeddings** interface."""
2
+
3
+ from abc import ABC, abstractmethod
4
+
5
+ from coco_core.runnables.config import run_in_executor
6
+
7
+
8
+ class Embeddings(ABC):
9
+ """Interface for embedding models.
10
+
11
+ This is an interface meant for implementing text embedding models.
12
+
13
+ Text embedding models are used to map text to a vector (a point in n-dimensional
14
+ space).
15
+
16
+ Texts that are similar will usually be mapped to points that are close to each
17
+ other in this space. The exact details of what's considered "similar" and how
18
+ "distance" is measured in this space are dependent on the specific embedding model.
19
+
20
+ This abstraction contains a method for embedding a list of documents and a method
21
+ for embedding a query text. The embedding of a query text is expected to be a single
22
+ vector, while the embedding of a list of documents is expected to be a list of
23
+ vectors.
24
+
25
+ Usually the query embedding is identical to the document embedding, but the
26
+ abstraction allows treating them independently.
27
+
28
+ In addition to the synchronous methods, this interface also provides asynchronous
29
+ versions of the methods.
30
+
31
+ By default, the asynchronous methods are implemented using the synchronous methods;
32
+ however, implementations may choose to override the asynchronous methods with
33
+ an async native implementation for performance reasons.
34
+ """
35
+
36
+ @abstractmethod
37
+ def embed_documents(self, texts: list[str]) -> list[list[float]]:
38
+ """Embed search docs.
39
+
40
+ Args:
41
+ texts: List of text to embed.
42
+
43
+ Returns:
44
+ List of embeddings.
45
+ """
46
+
47
+ @abstractmethod
48
+ def embed_query(self, text: str) -> list[float]:
49
+ """Embed query text.
50
+
51
+ Args:
52
+ text: Text to embed.
53
+
54
+ Returns:
55
+ Embedding.
56
+ """
57
+
58
+ async def aembed_documents(self, texts: list[str]) -> list[list[float]]:
59
+ """Asynchronous Embed search docs.
60
+
61
+ Args:
62
+ texts: List of text to embed.
63
+
64
+ Returns:
65
+ List of embeddings.
66
+ """
67
+ return await run_in_executor(None, self.embed_documents, texts)
68
+
69
+ async def aembed_query(self, text: str) -> list[float]:
70
+ """Asynchronous Embed query text.
71
+
72
+ Args:
73
+ text: Text to embed.
74
+
75
+ Returns:
76
+ Embedding.
77
+ """
78
+ return await run_in_executor(None, self.embed_query, text)
@@ -0,0 +1,129 @@
1
+ """Module contains a few fake embedding models for testing purposes."""
2
+
3
+ # Please do not add additional fake embedding model implementations here.
4
+ import contextlib
5
+ import hashlib
6
+
7
+ from pydantic import BaseModel
8
+ from typing_extensions import override
9
+
10
+ from coco_core.embeddings import Embeddings
11
+
12
+ with contextlib.suppress(ImportError):
13
+ import numpy as np
14
+
15
+
16
+ class FakeEmbeddings(Embeddings, BaseModel):
17
+ """Fake embedding model for unit testing purposes.
18
+
19
+ This embedding model creates embeddings by sampling from a normal distribution.
20
+
21
+ !!! danger "Toy model"
22
+ Do not use this outside of testing, as it is not a real embedding model.
23
+
24
+ Instantiate:
25
+ ```python
26
+ from coco_core.embeddings import FakeEmbeddings
27
+
28
+ embed = FakeEmbeddings(size=100)
29
+ ```
30
+
31
+ Embed single text:
32
+ ```python
33
+ input_text = "The meaning of life is 42"
34
+ vector = embed.embed_query(input_text)
35
+ print(vector[:3])
36
+ ```
37
+ ```python
38
+ [-0.700234640213188, -0.581266257710429, -1.1328482266445354]
39
+ ```
40
+
41
+ Embed multiple texts:
42
+ ```python
43
+ input_texts = ["Document 1...", "Document 2..."]
44
+ vectors = embed.embed_documents(input_texts)
45
+ print(len(vectors))
46
+ # The first 3 coordinates for the first vector
47
+ print(vectors[0][:3])
48
+ ```
49
+ ```python
50
+ 2
51
+ [-0.5670477847544458, -0.31403828652395727, -0.5840547508955257]
52
+ ```
53
+ """
54
+
55
+ size: int
56
+ """The size of the embedding vector."""
57
+
58
+ def _get_embedding(self) -> list[float]:
59
+ return list(np.random.default_rng().normal(size=self.size))
60
+
61
+ @override
62
+ def embed_documents(self, texts: list[str]) -> list[list[float]]:
63
+ return [self._get_embedding() for _ in texts]
64
+
65
+ @override
66
+ def embed_query(self, text: str) -> list[float]:
67
+ return self._get_embedding()
68
+
69
+
70
+ class DeterministicFakeEmbedding(Embeddings, BaseModel):
71
+ """Deterministic fake embedding model for unit testing purposes.
72
+
73
+ This embedding model creates embeddings by sampling from a normal distribution
74
+ with a seed based on the hash of the text.
75
+
76
+ !!! danger "Toy model"
77
+ Do not use this outside of testing, as it is not a real embedding model.
78
+
79
+ Instantiate:
80
+ ```python
81
+ from coco_core.embeddings import DeterministicFakeEmbedding
82
+
83
+ embed = DeterministicFakeEmbedding(size=100)
84
+ ```
85
+
86
+ Embed single text:
87
+ ```python
88
+ input_text = "The meaning of life is 42"
89
+ vector = embed.embed_query(input_text)
90
+ print(vector[:3])
91
+ ```
92
+ ```python
93
+ [-0.700234640213188, -0.581266257710429, -1.1328482266445354]
94
+ ```
95
+
96
+ Embed multiple texts:
97
+ ```python
98
+ input_texts = ["Document 1...", "Document 2..."]
99
+ vectors = embed.embed_documents(input_texts)
100
+ print(len(vectors))
101
+ # The first 3 coordinates for the first vector
102
+ print(vectors[0][:3])
103
+ ```
104
+ ```python
105
+ 2
106
+ [-0.5670477847544458, -0.31403828652395727, -0.5840547508955257]
107
+ ```
108
+ """
109
+
110
+ size: int
111
+ """The size of the embedding vector."""
112
+
113
+ def _get_embedding(self, seed: int) -> list[float]:
114
+ # set the seed for the random generator
115
+ rng = np.random.default_rng(seed)
116
+ return list(rng.normal(size=self.size))
117
+
118
+ @staticmethod
119
+ def _get_seed(text: str) -> int:
120
+ """Get a seed for the random generator, using the hash of the text."""
121
+ return int(hashlib.sha256(text.encode("utf-8")).hexdigest(), 16) % 10**8
122
+
123
+ @override
124
+ def embed_documents(self, texts: list[str]) -> list[list[float]]:
125
+ return [self._get_embedding(seed=self._get_seed(_)) for _ in texts]
126
+
127
+ @override
128
+ def embed_query(self, text: str) -> list[float]:
129
+ return self._get_embedding(seed=self._get_seed(text))
coco_core/env.py ADDED
@@ -0,0 +1,22 @@
1
+ """Utilities for getting information about the runtime environment."""
2
+
3
+ import platform
4
+ from functools import lru_cache
5
+
6
+ from coco_core import __version__
7
+
8
+
9
+ @lru_cache(maxsize=1)
10
+ def get_runtime_environment() -> dict[str, str]:
11
+ """Get information about the Coco runtime environment.
12
+
13
+ Returns:
14
+ A dictionary with information about the runtime environment.
15
+ """
16
+ return {
17
+ "library_version": __version__,
18
+ "library": "trustcoco-core",
19
+ "platform": platform.platform(),
20
+ "runtime": "python",
21
+ "runtime_version": platform.python_version(),
22
+ }
@@ -0,0 +1,47 @@
1
+ """Example selectors.
2
+
3
+ **Example selector** implements logic for selecting examples to include them in prompts.
4
+ This allows us to select examples that are most relevant to the input.
5
+ """
6
+
7
+ from typing import TYPE_CHECKING
8
+
9
+ from coco_core._import_utils import import_attr
10
+
11
+ if TYPE_CHECKING:
12
+ from coco_core.example_selectors.base import BaseExampleSelector
13
+ from coco_core.example_selectors.length_based import (
14
+ LengthBasedExampleSelector,
15
+ )
16
+ from coco_core.example_selectors.semantic_similarity import (
17
+ MaxMarginalRelevanceExampleSelector,
18
+ SemanticSimilarityExampleSelector,
19
+ sorted_values,
20
+ )
21
+
22
+ __all__ = (
23
+ "BaseExampleSelector",
24
+ "LengthBasedExampleSelector",
25
+ "MaxMarginalRelevanceExampleSelector",
26
+ "SemanticSimilarityExampleSelector",
27
+ "sorted_values",
28
+ )
29
+
30
+ _dynamic_imports = {
31
+ "BaseExampleSelector": "base",
32
+ "LengthBasedExampleSelector": "length_based",
33
+ "MaxMarginalRelevanceExampleSelector": "semantic_similarity",
34
+ "SemanticSimilarityExampleSelector": "semantic_similarity",
35
+ "sorted_values": "semantic_similarity",
36
+ }
37
+
38
+
39
+ def __getattr__(attr_name: str) -> object:
40
+ module_name = _dynamic_imports.get(attr_name)
41
+ result = import_attr(attr_name, module_name, __spec__.parent)
42
+ globals()[attr_name] = result
43
+ return result
44
+
45
+
46
+ def __dir__() -> list[str]:
47
+ return list(__all__)
@@ -0,0 +1,60 @@
1
+ """Interface for selecting examples to include in prompts."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from typing import Any
5
+
6
+ from coco_core.runnables import run_in_executor
7
+
8
+
9
+ class BaseExampleSelector(ABC):
10
+ """Interface for selecting examples to include in prompts."""
11
+
12
+ @abstractmethod
13
+ def add_example(self, example: dict[str, str]) -> Any:
14
+ """Add new example to store.
15
+
16
+ Args:
17
+ example: A dictionary with keys as input variables
18
+ and values as their values.
19
+
20
+ Returns:
21
+ Any return value.
22
+ """
23
+
24
+ async def aadd_example(self, example: dict[str, str]) -> Any:
25
+ """Async add new example to store.
26
+
27
+ Args:
28
+ example: A dictionary with keys as input variables
29
+ and values as their values.
30
+
31
+ Returns:
32
+ Any return value.
33
+ """
34
+ return await run_in_executor(None, self.add_example, example)
35
+
36
+ @abstractmethod
37
+ def select_examples(self, input_variables: dict[str, str]) -> list[dict[str, Any]]:
38
+ """Select which examples to use based on the inputs.
39
+
40
+ Args:
41
+ input_variables: A dictionary with keys as input variables
42
+ and values as their values.
43
+
44
+ Returns:
45
+ A list of examples.
46
+ """
47
+
48
+ async def aselect_examples(
49
+ self, input_variables: dict[str, str]
50
+ ) -> list[dict[str, Any]]:
51
+ """Async select which examples to use based on the inputs.
52
+
53
+ Args:
54
+ input_variables: A dictionary with keys as input variables
55
+ and values as their values.
56
+
57
+ Returns:
58
+ A list of examples.
59
+ """
60
+ return await run_in_executor(None, self.select_examples, input_variables)
@@ -0,0 +1,131 @@
1
+ """Select examples based on length."""
2
+
3
+ import re
4
+ from collections.abc import Callable
5
+ from typing import Any
6
+
7
+ from pydantic import BaseModel, Field, model_validator
8
+ from typing_extensions import Self
9
+
10
+ from coco_core.example_selectors.base import BaseExampleSelector
11
+ from coco_core.prompts.prompt import PromptTemplate
12
+
13
+
14
+ def _get_length_based(text: str) -> int:
15
+ return len(re.split(r"\n| ", text))
16
+
17
+
18
+ class LengthBasedExampleSelector(BaseExampleSelector, BaseModel):
19
+ r"""Select examples based on length.
20
+
21
+ Example:
22
+ ```python
23
+ from coco_core.example_selectors import LengthBasedExampleSelector
24
+ from coco_core.prompts import PromptTemplate
25
+
26
+ # Define examples
27
+ examples = [
28
+ {"input": "happy", "output": "sad"},
29
+ {"input": "tall", "output": "short"},
30
+ {"input": "fast", "output": "slow"},
31
+ ]
32
+
33
+ # Create prompt template
34
+ example_prompt = PromptTemplate(
35
+ input_variables=["input", "output"],
36
+ template="Input: {input}\nOutput: {output}",
37
+ )
38
+
39
+ # Create selector with max length constraint
40
+ selector = LengthBasedExampleSelector(
41
+ examples=examples,
42
+ example_prompt=example_prompt,
43
+ max_length=50, # Maximum prompt length
44
+ )
45
+
46
+ # Select examples for a new input
47
+ selected = selector.select_examples({"input": "large", "output": "tiny"})
48
+ # Returns examples that fit within max_length constraint
49
+ ```
50
+ """
51
+
52
+ examples: list[dict[str, Any]]
53
+ """A list of the examples that the prompt template expects."""
54
+
55
+ example_prompt: PromptTemplate
56
+ """Prompt template used to format the examples."""
57
+
58
+ get_text_length: Callable[[str], int] = _get_length_based
59
+ """Function to measure prompt length. Defaults to word count."""
60
+
61
+ max_length: int = 2048
62
+ """Max length for the prompt, beyond which examples are cut."""
63
+
64
+ example_text_lengths: list[int] = Field(default_factory=list)
65
+ """Length of each example."""
66
+
67
+ def add_example(self, example: dict[str, str]) -> None:
68
+ """Add new example to list.
69
+
70
+ Args:
71
+ example: A dictionary with keys as input variables
72
+ and values as their values.
73
+ """
74
+ self.examples.append(example)
75
+ string_example = self.example_prompt.format(**example)
76
+ self.example_text_lengths.append(self.get_text_length(string_example))
77
+
78
+ async def aadd_example(self, example: dict[str, str]) -> None:
79
+ """Async add new example to list.
80
+
81
+ Args:
82
+ example: A dictionary with keys as input variables
83
+ and values as their values.
84
+ """
85
+ self.add_example(example)
86
+
87
+ @model_validator(mode="after")
88
+ def post_init(self) -> Self:
89
+ """Validate that the examples are formatted correctly."""
90
+ if self.example_text_lengths:
91
+ return self
92
+ string_examples = [self.example_prompt.format(**eg) for eg in self.examples]
93
+ self.example_text_lengths = [self.get_text_length(eg) for eg in string_examples]
94
+ return self
95
+
96
+ def select_examples(self, input_variables: dict[str, str]) -> list[dict[str, Any]]:
97
+ """Select which examples to use based on the input lengths.
98
+
99
+ Args:
100
+ input_variables: A dictionary with keys as input variables
101
+ and values as their values.
102
+
103
+ Returns:
104
+ A list of examples to include in the prompt.
105
+ """
106
+ inputs = " ".join(input_variables.values())
107
+ remaining_length = self.max_length - self.get_text_length(inputs)
108
+ i = 0
109
+ examples = []
110
+ while remaining_length > 0 and i < len(self.examples):
111
+ new_length = remaining_length - self.example_text_lengths[i]
112
+ if new_length < 0:
113
+ break
114
+ examples.append(self.examples[i])
115
+ remaining_length = new_length
116
+ i += 1
117
+ return examples
118
+
119
+ async def aselect_examples(
120
+ self, input_variables: dict[str, str]
121
+ ) -> list[dict[str, Any]]:
122
+ """Async select which examples to use based on the input lengths.
123
+
124
+ Args:
125
+ input_variables: A dictionary with keys as input variables
126
+ and values as their values.
127
+
128
+ Returns:
129
+ A list of examples to include in the prompt.
130
+ """
131
+ return self.select_examples(input_variables)