mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-06-01 22:38:17 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e53a676c04 | ||
|
|
1aba9fe415 | ||
|
|
4dafb05735 | ||
|
|
5cdc420c50 |
6
.github/workflows/vulnerability-scan.yml
vendored
6
.github/workflows/vulnerability-scan.yml
vendored
@@ -71,7 +71,8 @@ jobs:
|
||||
--ignore-vuln PYSEC-2025-215 \
|
||||
--ignore-vuln PYSEC-2025-216 \
|
||||
--ignore-vuln PYSEC-2025-217 \
|
||||
--ignore-vuln PYSEC-2025-218
|
||||
--ignore-vuln PYSEC-2025-218 \
|
||||
--ignore-vuln GHSA-f4j7-r4q5-qw2c
|
||||
# Ignored CVEs:
|
||||
# PYSEC-2024-277 - joblib 1.5.3: disputed; NumpyArrayWrapper only used with trusted caches
|
||||
# PYSEC-2026-89 - markdown 3.10.2: DoS via malformed HTML; fix 3.8.1 — already past, advisory range is stale
|
||||
@@ -81,6 +82,9 @@ jobs:
|
||||
# PYSEC-2025-189..197 - torch 2.11.0: memory-corruption/DoS in functions only reachable via untrusted models; no fix available
|
||||
# PYSEC-2025-210, PYSEC-2026-139 - torch 2.11.0: profiler/deserialization issues; no fix available
|
||||
# PYSEC-2025-211..218 - transformers 5.5.4: deserialization/code injection via malicious model checkpoints; no fix available
|
||||
# GHSA-f4j7-r4q5-qw2c - chromadb 1.1.1 (CVE-2026-45829): pre-auth RCE via /api/v2/tenants/{tenant}/databases/{db}/collections when trust_remote_code=true.
|
||||
# Advisory: vulnerable >=1.0.0,<=1.5.9, firstPatchedVersion=none. We only use chromadb.PersistentClient (lib/crewai/src/crewai/rag/chromadb/factory.py)
|
||||
# and chromadb.utils.embedding_functions; the chromadb HTTP server is never started, so the vulnerable route is not exposed.
|
||||
continue-on-error: true
|
||||
|
||||
- name: Display results
|
||||
|
||||
@@ -28,7 +28,34 @@ repos:
|
||||
hooks:
|
||||
- id: pip-audit
|
||||
name: pip-audit
|
||||
entry: bash -c 'source .venv/bin/activate && uv run pip-audit --skip-editable --ignore-vuln CVE-2026-3219' --
|
||||
# Keep this ignore list in sync with .github/workflows/vulnerability-scan.yml.
|
||||
entry: >-
|
||||
bash -c 'source .venv/bin/activate && uv run pip-audit --skip-editable
|
||||
--ignore-vuln PYSEC-2024-277
|
||||
--ignore-vuln PYSEC-2026-89
|
||||
--ignore-vuln PYSEC-2026-97
|
||||
--ignore-vuln PYSEC-2025-148
|
||||
--ignore-vuln PYSEC-2025-183
|
||||
--ignore-vuln PYSEC-2025-189
|
||||
--ignore-vuln PYSEC-2025-190
|
||||
--ignore-vuln PYSEC-2025-191
|
||||
--ignore-vuln PYSEC-2025-192
|
||||
--ignore-vuln PYSEC-2025-193
|
||||
--ignore-vuln PYSEC-2025-194
|
||||
--ignore-vuln PYSEC-2025-195
|
||||
--ignore-vuln PYSEC-2025-196
|
||||
--ignore-vuln PYSEC-2025-197
|
||||
--ignore-vuln PYSEC-2025-210
|
||||
--ignore-vuln PYSEC-2026-139
|
||||
--ignore-vuln PYSEC-2025-211
|
||||
--ignore-vuln PYSEC-2025-212
|
||||
--ignore-vuln PYSEC-2025-213
|
||||
--ignore-vuln PYSEC-2025-214
|
||||
--ignore-vuln PYSEC-2025-215
|
||||
--ignore-vuln PYSEC-2025-216
|
||||
--ignore-vuln PYSEC-2025-217
|
||||
--ignore-vuln PYSEC-2025-218
|
||||
--ignore-vuln GHSA-f4j7-r4q5-qw2c' --
|
||||
language: system
|
||||
pass_filenames: false
|
||||
stages: [pre-push, manual]
|
||||
|
||||
134
docs/ar/enterprise/integrations/snowflake.mdx
Normal file
134
docs/ar/enterprise/integrations/snowflake.mdx
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
title: تكامل Snowflake
|
||||
description: "ربط وكلاء CrewAI بـ Snowflake Cortex Analyst و Cortex Search وتنفيذ SQL من خلال خادم MCP المُدار من Snowflake."
|
||||
icon: "snowflake"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## نظرة عامة
|
||||
|
||||
اربط وكلاء CrewAI مباشرة ببيانات Snowflake الخاصة بك من خلال [خادم MCP المُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp). يتيح تكامل Snowflake لوكلائك الاستعلام عن البيانات المنظمة باستخدام **Cortex Analyst**، والبحث في البيانات غير المنظمة باستخدام **Cortex Search**، وتنفيذ SQL مُدار على مستودعات البيانات الخاصة بك — كل ذلك دون كتابة أو استضافة أي كود للموصّل.
|
||||
|
||||
داخلياً، تكامل Snowflake هو غلاف مُدار حول دعم [Custom MCP Server](/ar/enterprise/guides/custom-mcp-server) في CrewAI. يكشف Snowflake عن قدرات Cortex AI الخاصة به من خلال نقطة نهاية [Model Context Protocol](https://modelcontextprotocol.io/)، ويتصل CrewAI بها بشكل آمن نيابةً عنك. أي أداة تكشفها على جانب Snowflake — Cortex Analyst أو Cortex Search أو تنفيذ SQL أو Cortex Agents أو أدواتك المخصصة — تصبح متاحة لطواقمك.
|
||||
|
||||
## القدرات الرئيسية
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Cortex Analyst" icon="chart-bar">
|
||||
اطرح أسئلة بلغة طبيعية ودع [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) يولّد وينفذ SQL على بياناتك **المنظمة** باستخدام نماذج دلالية غنية.
|
||||
</Card>
|
||||
<Card title="Cortex Search" icon="magnifying-glass">
|
||||
استرجع البيانات **غير المنظمة** ذات الصلة لسير عمل RAG والمعرفة باستخدام [Cortex Search](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview)، خدمة البحث المُدارة بالكامل من Snowflake.
|
||||
</Card>
|
||||
<Card title="تنفيذ SQL" icon="database">
|
||||
نفّذ استعلامات SQL مُدارة مباشرة على مستودعات Snowflake الخاصة بك، مع وضع القراءة فقط القابل للتكوين، والمهلات الزمنية، واختيار المستودع.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
نظراً لأن التكامل يكشف عن أي أدوات ينشرها خادم MCP الخاص بك، يمكنك أيضاً كشف **Cortex Agents** و**الأدوات المخصصة** (الدوال المعرّفة من المستخدم والإجراءات المخزّنة) لوكلاء CrewAI.
|
||||
|
||||
## المتطلبات الأساسية
|
||||
|
||||
قبل استخدام تكامل Snowflake، تأكد من توفر ما يلي:
|
||||
|
||||
- حساب [CrewAI AMP](https://app.crewai.com) مع اشتراك فعّال
|
||||
- حساب Snowflake مع إمكانية الوصول إلى ميزات Cortex AI
|
||||
- [خادم MCP مُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) مُكوّن بالأدوات التي تريد كشفها
|
||||
- صلاحيات Snowflake المناسبة (USAGE/SELECT) على خادم MCP والكائنات الأساسية
|
||||
|
||||
## إعداد خادم Snowflake MCP
|
||||
|
||||
يعمل خادم MCP المُدار من Snowflake داخل حساب Snowflake الخاص بك ويحدد الأدوات المتاحة للعملاء الخارجيين مثل CrewAI. أنشئ واحداً باستخدام أمر [`CREATE MCP SERVER`](https://docs.snowflake.com/en/sql-reference/sql/create-mcp-server)، مع سرد خدمات Cortex Search وعروض Cortex Analyst الدلالية وأدوات SQL التي تريد كشفها.
|
||||
|
||||
```sql
|
||||
CREATE MCP SERVER my_mcp_server
|
||||
FROM SPECIFICATION $$
|
||||
tools:
|
||||
- name: "sales_analyst"
|
||||
type: "CORTEX_ANALYST"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.sales_semantic_view"
|
||||
description: "Answer questions about sales metrics"
|
||||
- name: "docs_search"
|
||||
type: "CORTEX_SEARCH_SERVICE_QUERY"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.support_docs_search"
|
||||
description: "Search internal support documentation"
|
||||
- name: "run_sql"
|
||||
type: "SQL_EXECUTION"
|
||||
description: "Execute read-only SQL queries"
|
||||
$$;
|
||||
```
|
||||
|
||||
<Note>
|
||||
تتبع نقطة نهاية MCP التنسيق `https://<account_URL>/api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}`. يبني CrewAI هذا العنوان تلقائياً من **عنوان URL للحساب** و**قاعدة البيانات** و**المخطط** و**اسم خادم MCP** الذي تقدمه عند تكوين التكامل.
|
||||
</Note>
|
||||
|
||||
للمواصفات الكاملة — بما في ذلك Cortex Agents والأدوات المخصصة وحدود حجم الاستجابة وخيارات الحوكمة — راجع [وثائق خادم MCP المُدار من Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp).
|
||||
|
||||
## ربط Snowflake في CrewAI AMP
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/snowflake-configure.png" alt="تكوين تكامل Snowflake في CrewAI AMP" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="فتح الأدوات والتكاملات">
|
||||
انتقل إلى **الأدوات والتكاملات** في الشريط الجانبي الأيسر لـ CrewAI AMP، وابحث عن **Snowflake** في قائمة التطبيقات، وافتح لوحة التكوين الخاصة به.
|
||||
</Step>
|
||||
|
||||
<Step title="تقديم تفاصيل الاتصال">
|
||||
املأ حقول الاتصال التي يستخدمها CrewAI للوصول إلى خادم Snowflake MCP الخاص بك:
|
||||
|
||||
| الحقل | مطلوب | الوصف |
|
||||
|-------|-------|-------|
|
||||
| **الاسم** | نعم | اسم وصفي لهذا الاتصال (القيمة الافتراضية `Snowflake`). |
|
||||
| **الوصف** | لا | ملخص اختياري لما يوفره هذا الاتصال. |
|
||||
| **عنوان URL للحساب** | نعم | عنوان URL لحساب Snowflake الخاص بك، مثل `xy12345.us-east-1.snowflakecomputing.com`. |
|
||||
| **قاعدة البيانات** | نعم | قاعدة البيانات التي تحتوي على خادم MCP الخاص بك (مثل `MY_DATABASE`). |
|
||||
| **المخطط** | نعم | المخطط الذي يحتوي على خادم MCP الخاص بك (مثل `MY_SCHEMA`). |
|
||||
| **اسم خادم MCP** | نعم | اسم كائن خادم MCP الذي أنشأته في Snowflake (مثل `MY_MCP_SERVER`). |
|
||||
</Step>
|
||||
|
||||
<Step title="اختيار طريقة المصادقة">
|
||||
اختر كيفية مصادقة CrewAI مع Snowflake. يُوصى باستخدام **OAuth**.
|
||||
|
||||
- **استخدام OAuth** — اتصل بشكل آمن باستخدام OAuth 2.0 للمصادقة القائمة على الرموز دون مشاركة بيانات الاعتماد الخاصة بك. يتعامل CrewAI مع تدفق التفويض الكامل ويجدد الرموز تلقائياً. انسخ **عنوان URI لإعادة التوجيه** المعروض في النموذج (`https://oauth.crewai.com/oauth/add`) وسجّله كعنوان URI لإعادة التوجيه المعتمد في [تكامل أمان OAuth](https://docs.snowflake.com/en/user-guide/oauth-custom) في Snowflake.
|
||||
- **استخدام رمز وصول شخصي** — المصادقة باستخدام [رمز وصول برمجي](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) مُنشأ من إعدادات حساب Snowflake الخاص بك. قم بتعيين دور بأقل صلاحيات للرمز للحد من التعرض.
|
||||
</Step>
|
||||
|
||||
<Step title="المصادقة">
|
||||
انقر على **المصادقة**. بالنسبة لـ OAuth، ستتم إعادة توجيهك إلى Snowflake لتفويض الوصول. بمجرد المصادقة، يظهر خادم Snowflake في قائمة الاتصالات وتصبح أدواته متاحة لطواقمك.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
مع OAuth، يتم مصادقة كل مستخدم بشكل فردي وتُنفّذ الاستعلامات بدور `DEFAULT_ROLE` الخاص به في Snowflake. تأكد من أن المستخدمين المتصلين لديهم دور ومستودع افتراضي محدد (`ALTER USER <username> SET DEFAULT_ROLE = '<role>' DEFAULT_WAREHOUSE = '<warehouse>'`) حتى تتوفر موارد الحوسبة لأدوات Cortex Analyst و SQL.
|
||||
</Tip>
|
||||
|
||||
## استخدام أدوات Snowflake في طواقمك
|
||||
|
||||
بمجرد الاتصال، تظهر الأدوات التي يكشفها خادم MCP الخاص بك إلى جانب الاتصالات المدمجة في صفحة **الأدوات والتكاملات**. يمكنك:
|
||||
|
||||
- **تعيين الأدوات للوكلاء** في طواقمك تماماً مثل أي أداة CrewAI أخرى.
|
||||
- **إدارة الرؤية** للتحكم في أعضاء الفريق الذين يمكنهم استخدام الاتصال.
|
||||
- **تعديل أو إزالة** الاتصال في أي وقت من قائمة الاتصالات.
|
||||
|
||||
يمكن لوكلائك الآن سؤال Cortex Analyst عن المقاييس، وتشغيل Cortex Search على مستنداتك، وتنفيذ SQL — مع تدفق النتائج تلقائياً إلى استدلالهم.
|
||||
|
||||
<Warning>
|
||||
يفرض Snowflake الحوكمة على خادم MCP: يحدد التحكم في الوصول القائم على الأدوار الأدوات التي يمكن للمستخدم اكتشافها واستدعاؤها، وتنطبق حدود على حجم الاستجابة وعدد الأدوات (بحد أقصى 50 لكل خادم) وعمق التكرار. إذا فشل استدعاء أداة، تأكد من أن دور المستخدم المتصل لديه الصلاحيات المطلوبة على خادم MCP والكائنات الأساسية.
|
||||
</Warning>
|
||||
|
||||
## معرفة المزيد
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="خادم MCP المُدار من Snowflake" icon="snowflake" href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp">
|
||||
الوثائق الرسمية من Snowflake لإنشاء وإدارة خادم MCP.
|
||||
</Card>
|
||||
<Card title="خوادم Custom MCP في CrewAI" icon="plug" href="/ar/enterprise/guides/custom-mcp-server">
|
||||
تعرّف على كيفية اتصال CrewAI بأي خادم MCP، الأساس الذي يبني عليه تكامل Snowflake.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="تحتاج مساعدة؟" icon="headset" href="mailto:support@crewai.com">
|
||||
تواصل مع فريق الدعم للحصول على المساعدة في تكامل Snowflake أو استكشاف الأخطاء وإصلاحها.
|
||||
</Card>
|
||||
@@ -481,6 +481,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -998,6 +999,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -1482,6 +1484,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -1965,6 +1968,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -2448,6 +2452,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -2941,6 +2946,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -3434,6 +3440,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -3927,6 +3934,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -4420,6 +4428,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -4902,6 +4911,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -5384,6 +5394,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -5866,6 +5877,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -6350,6 +6362,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -6832,6 +6845,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -7317,6 +7331,7 @@
|
||||
"en/enterprise/integrations/salesforce",
|
||||
"en/enterprise/integrations/shopify",
|
||||
"en/enterprise/integrations/slack",
|
||||
"en/enterprise/integrations/snowflake",
|
||||
"en/enterprise/integrations/stripe",
|
||||
"en/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -7841,6 +7856,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -8335,6 +8351,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -8796,6 +8813,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -9257,6 +9275,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -9717,6 +9736,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -10187,6 +10207,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -10657,6 +10678,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -11127,6 +11149,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -11597,6 +11620,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -12057,6 +12081,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -12517,6 +12542,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -12977,6 +13003,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -13436,6 +13463,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -13895,6 +13923,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -14355,6 +14384,7 @@
|
||||
"pt-BR/enterprise/integrations/salesforce",
|
||||
"pt-BR/enterprise/integrations/shopify",
|
||||
"pt-BR/enterprise/integrations/slack",
|
||||
"pt-BR/enterprise/integrations/snowflake",
|
||||
"pt-BR/enterprise/integrations/stripe",
|
||||
"pt-BR/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -14891,6 +14921,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -15397,6 +15428,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -15870,6 +15902,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -16343,6 +16376,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -16816,6 +16850,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -17299,6 +17334,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -17782,6 +17818,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -18265,6 +18302,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -18748,6 +18786,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -19221,6 +19260,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -19694,6 +19734,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -20167,6 +20208,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -20639,6 +20681,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -21111,6 +21154,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -21584,6 +21628,7 @@
|
||||
"ko/enterprise/integrations/salesforce",
|
||||
"ko/enterprise/integrations/shopify",
|
||||
"ko/enterprise/integrations/slack",
|
||||
"ko/enterprise/integrations/snowflake",
|
||||
"ko/enterprise/integrations/stripe",
|
||||
"ko/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -22120,6 +22165,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -22626,6 +22672,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -23099,6 +23146,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -23572,6 +23620,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -24045,6 +24094,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -24528,6 +24578,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -25011,6 +25062,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -25494,6 +25546,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -25977,6 +26030,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -26450,6 +26504,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -26923,6 +26978,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -27396,6 +27452,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -27868,6 +27925,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -28340,6 +28398,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
@@ -28813,6 +28872,7 @@
|
||||
"ar/enterprise/integrations/salesforce",
|
||||
"ar/enterprise/integrations/shopify",
|
||||
"ar/enterprise/integrations/slack",
|
||||
"ar/enterprise/integrations/snowflake",
|
||||
"ar/enterprise/integrations/stripe",
|
||||
"ar/enterprise/integrations/zendesk"
|
||||
]
|
||||
|
||||
134
docs/en/enterprise/integrations/snowflake.mdx
Normal file
134
docs/en/enterprise/integrations/snowflake.mdx
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
title: Snowflake Integration
|
||||
description: "Connect CrewAI agents to Snowflake Cortex Analyst, Cortex Search, and SQL execution through the Snowflake-managed MCP server."
|
||||
icon: "snowflake"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Connect your CrewAI agents directly to your Snowflake data through the [Snowflake-managed MCP server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp). The Snowflake integration lets your agents query structured data with **Cortex Analyst**, search unstructured data with **Cortex Search**, and run governed SQL against your warehouses — all without writing or hosting any connector code.
|
||||
|
||||
Under the hood, the Snowflake integration is a managed wrapper around CrewAI's [Custom MCP Server](/en/enterprise/guides/custom-mcp-server) support. Snowflake exposes its Cortex AI capabilities through a [Model Context Protocol](https://modelcontextprotocol.io/) endpoint, and CrewAI connects to it securely on your behalf. Any tool you expose on the Snowflake side — Cortex Analyst, Cortex Search, SQL execution, Cortex Agents, or your own custom tools — becomes available to your crews.
|
||||
|
||||
## Key Capabilities
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Cortex Analyst" icon="chart-bar">
|
||||
Ask questions in natural language and let [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) generate and run SQL against your **structured** data using rich semantic models.
|
||||
</Card>
|
||||
<Card title="Cortex Search" icon="magnifying-glass">
|
||||
Retrieve relevant **unstructured** data for RAG and knowledge workflows with [Cortex Search](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview), Snowflake's fully managed search service.
|
||||
</Card>
|
||||
<Card title="SQL Execution" icon="database">
|
||||
Run governed SQL queries directly against your Snowflake warehouses, with configurable read-only mode, timeouts, and warehouse selection.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
Because the integration surfaces whatever tools your MCP server publishes, you can also expose **Cortex Agents** and **custom tools** (user-defined functions and stored procedures) to your CrewAI agents.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before using the Snowflake integration, ensure you have:
|
||||
|
||||
- A [CrewAI AMP](https://app.crewai.com) account with an active subscription
|
||||
- A Snowflake account with access to Cortex AI features
|
||||
- A [Snowflake-managed MCP server](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) configured with the tools you want to expose
|
||||
- Appropriate Snowflake privileges (USAGE/SELECT) on the MCP server and its underlying objects
|
||||
|
||||
## Setting Up the Snowflake MCP Server
|
||||
|
||||
The Snowflake-managed MCP server runs inside your Snowflake account and defines which tools are available to external clients like CrewAI. Create one with the [`CREATE MCP SERVER`](https://docs.snowflake.com/en/sql-reference/sql/create-mcp-server) command, listing the Cortex Search services, Cortex Analyst semantic views, and SQL tools you want to expose.
|
||||
|
||||
```sql
|
||||
CREATE MCP SERVER my_mcp_server
|
||||
FROM SPECIFICATION $$
|
||||
tools:
|
||||
- name: "sales_analyst"
|
||||
type: "CORTEX_ANALYST"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.sales_semantic_view"
|
||||
description: "Answer questions about sales metrics"
|
||||
- name: "docs_search"
|
||||
type: "CORTEX_SEARCH_SERVICE_QUERY"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.support_docs_search"
|
||||
description: "Search internal support documentation"
|
||||
- name: "run_sql"
|
||||
type: "SQL_EXECUTION"
|
||||
description: "Execute read-only SQL queries"
|
||||
$$;
|
||||
```
|
||||
|
||||
<Note>
|
||||
The MCP endpoint follows the format `https://<account_URL>/api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}`. CrewAI builds this URL automatically from the **Account URL**, **Database**, **Schema**, and **MCP Server Name** you provide when configuring the integration.
|
||||
</Note>
|
||||
|
||||
For the complete specification — including Cortex Agents, custom tools, response-size limits, and governance options — see the [Snowflake-managed MCP server documentation](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp).
|
||||
|
||||
## Connecting Snowflake in CrewAI AMP
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/snowflake-configure.png" alt="Configure Snowflake integration in CrewAI AMP" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="Open Tools & Integrations">
|
||||
Navigate to **Tools & Integrations** in the left sidebar of CrewAI AMP, find **Snowflake** in the list of applications, and open its configuration panel.
|
||||
</Step>
|
||||
|
||||
<Step title="Provide connection details">
|
||||
Fill in the connection fields that CrewAI uses to reach your Snowflake MCP server:
|
||||
|
||||
| Field | Required | Description |
|
||||
|-------|----------|-------------|
|
||||
| **Name** | Yes | A descriptive name for this connection (defaults to `Snowflake`). |
|
||||
| **Description** | No | An optional summary of what this connection provides. |
|
||||
| **Account URL** | Yes | Your Snowflake account URL, e.g. `xy12345.us-east-1.snowflakecomputing.com`. |
|
||||
| **Database** | Yes | The database that contains your MCP server (e.g. `MY_DATABASE`). |
|
||||
| **Schema** | Yes | The schema that contains your MCP server (e.g. `MY_SCHEMA`). |
|
||||
| **MCP Server Name** | Yes | The name of the MCP server object you created in Snowflake (e.g. `MY_MCP_SERVER`). |
|
||||
</Step>
|
||||
|
||||
<Step title="Choose an authentication method">
|
||||
Select how CrewAI authenticates to Snowflake. **OAuth** is recommended.
|
||||
|
||||
- **Use OAuth** — Connect securely using OAuth 2.0 for token-based authentication without sharing your credentials. CrewAI handles the full authorization flow and refreshes tokens automatically. Copy the **Redirect URI** shown in the form (`https://oauth.crewai.com/oauth/add`) and register it as an authorized redirect URI in your Snowflake [OAuth security integration](https://docs.snowflake.com/en/user-guide/oauth-custom).
|
||||
- **Use personal access token** — Authenticate using a [programmatic access token](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) generated from your Snowflake account settings. Assign a least-privileged role to the token to limit exposure.
|
||||
</Step>
|
||||
|
||||
<Step title="Authenticate">
|
||||
Click **Authenticate**. For OAuth, you'll be redirected to Snowflake to authorize access. Once authenticated, the Snowflake server appears in your Connections and its tools become available to your crews.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
With OAuth, each user authenticates individually and queries run with their Snowflake `DEFAULT_ROLE`. Make sure connecting users have a default role and warehouse set (`ALTER USER <username> SET DEFAULT_ROLE = '<role>' DEFAULT_WAREHOUSE = '<warehouse>'`) so Cortex Analyst and SQL tools have compute to run on.
|
||||
</Tip>
|
||||
|
||||
## Using Snowflake Tools in Your Crews
|
||||
|
||||
Once connected, the tools your MCP server exposes appear alongside built-in connections on the **Tools & Integrations** page. You can:
|
||||
|
||||
- **Assign tools to agents** in your crews just like any other CrewAI tool.
|
||||
- **Manage visibility** to control which team members can use the connection.
|
||||
- **Edit or remove** the connection at any time from the Connections list.
|
||||
|
||||
Your agents can now ask Cortex Analyst for metrics, run Cortex Search over your documents, and execute SQL — with results flowing back into their reasoning automatically.
|
||||
|
||||
<Warning>
|
||||
Snowflake enforces governance on the MCP server: role-based access control determines which tools a user can discover and invoke, and limits apply to response size, tool count (max 50 per server), and recursion depth. If a tool call fails, confirm the connecting user's role has the required privileges on the MCP server and its underlying objects.
|
||||
</Warning>
|
||||
|
||||
## Learn More
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Snowflake-managed MCP Server" icon="snowflake" href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp">
|
||||
Official Snowflake documentation for creating and governing the MCP server.
|
||||
</Card>
|
||||
<Card title="Custom MCP Servers in CrewAI" icon="plug" href="/en/enterprise/guides/custom-mcp-server">
|
||||
Learn how CrewAI connects to any MCP server, the foundation the Snowflake integration builds on.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="Need Help?" icon="headset" href="mailto:support@crewai.com">
|
||||
Contact our support team for assistance with the Snowflake integration or troubleshooting.
|
||||
</Card>
|
||||
BIN
docs/images/enterprise/snowflake-configure.png
Normal file
BIN
docs/images/enterprise/snowflake-configure.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 MiB |
134
docs/ko/enterprise/integrations/snowflake.mdx
Normal file
134
docs/ko/enterprise/integrations/snowflake.mdx
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
title: Snowflake 연동
|
||||
description: "Snowflake 관리형 MCP 서버를 통해 CrewAI 에이전트를 Snowflake Cortex Analyst, Cortex Search 및 SQL 실행에 연결합니다."
|
||||
icon: "snowflake"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## 개요
|
||||
|
||||
[Snowflake 관리형 MCP 서버](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp)를 통해 CrewAI 에이전트를 Snowflake 데이터에 직접 연결하세요. Snowflake 연동을 사용하면 에이전트가 **Cortex Analyst**로 구조화된 데이터를 쿼리하고, **Cortex Search**로 비구조화된 데이터를 검색하며, 커넥터 코드를 작성하거나 호스팅할 필요 없이 웨어하우스에 대해 관리되는 SQL을 실행할 수 있습니다.
|
||||
|
||||
내부적으로 Snowflake 연동은 CrewAI의 [Custom MCP Server](/ko/enterprise/guides/custom-mcp-server) 지원을 기반으로 하는 관리형 래퍼입니다. Snowflake는 [Model Context Protocol](https://modelcontextprotocol.io/) 엔드포인트를 통해 Cortex AI 기능을 노출하며, CrewAI가 이를 안전하게 연결합니다. Snowflake 측에서 노출하는 모든 도구 — Cortex Analyst, Cortex Search, SQL 실행, Cortex Agents 또는 사용자 정의 도구 — 가 크루에서 사용할 수 있게 됩니다.
|
||||
|
||||
## 주요 기능
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Cortex Analyst" icon="chart-bar">
|
||||
자연어로 질문하고 [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst)가 풍부한 시맨틱 모델을 사용하여 **구조화된** 데이터에 대해 SQL을 생성하고 실행하도록 합니다.
|
||||
</Card>
|
||||
<Card title="Cortex Search" icon="magnifying-glass">
|
||||
Snowflake의 완전 관리형 검색 서비스인 [Cortex Search](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview)를 사용하여 RAG 및 지식 워크플로우를 위한 관련 **비구조화된** 데이터를 검색합니다.
|
||||
</Card>
|
||||
<Card title="SQL 실행" icon="database">
|
||||
구성 가능한 읽기 전용 모드, 타임아웃 및 웨어하우스 선택을 통해 Snowflake 웨어하우스에 대해 관리되는 SQL 쿼리를 직접 실행합니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
연동이 MCP 서버가 게시하는 도구를 노출하므로, **Cortex Agents** 및 **사용자 정의 도구**(사용자 정의 함수 및 저장 프로시저)도 CrewAI 에이전트에 노출할 수 있습니다.
|
||||
|
||||
## 사전 준비 사항
|
||||
|
||||
Snowflake 연동을 사용하기 전에 다음을 확인하십시오:
|
||||
|
||||
- 활성 구독이 있는 [CrewAI AMP](https://app.crewai.com) 계정
|
||||
- Cortex AI 기능에 액세스할 수 있는 Snowflake 계정
|
||||
- 노출하려는 도구가 구성된 [Snowflake 관리형 MCP 서버](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp)
|
||||
- MCP 서버 및 기본 객체에 대한 적절한 Snowflake 권한(USAGE/SELECT)
|
||||
|
||||
## Snowflake MCP 서버 설정
|
||||
|
||||
Snowflake 관리형 MCP 서버는 Snowflake 계정 내에서 실행되며 CrewAI와 같은 외부 클라이언트에서 사용할 수 있는 도구를 정의합니다. [`CREATE MCP SERVER`](https://docs.snowflake.com/en/sql-reference/sql/create-mcp-server) 명령을 사용하여 노출하려는 Cortex Search 서비스, Cortex Analyst 시맨틱 뷰 및 SQL 도구를 나열하여 생성합니다.
|
||||
|
||||
```sql
|
||||
CREATE MCP SERVER my_mcp_server
|
||||
FROM SPECIFICATION $$
|
||||
tools:
|
||||
- name: "sales_analyst"
|
||||
type: "CORTEX_ANALYST"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.sales_semantic_view"
|
||||
description: "Answer questions about sales metrics"
|
||||
- name: "docs_search"
|
||||
type: "CORTEX_SEARCH_SERVICE_QUERY"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.support_docs_search"
|
||||
description: "Search internal support documentation"
|
||||
- name: "run_sql"
|
||||
type: "SQL_EXECUTION"
|
||||
description: "Execute read-only SQL queries"
|
||||
$$;
|
||||
```
|
||||
|
||||
<Note>
|
||||
MCP 엔드포인트는 `https://<account_URL>/api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}` 형식을 따릅니다. CrewAI는 연동 구성 시 제공하는 **계정 URL**, **데이터베이스**, **스키마** 및 **MCP 서버 이름**을 사용하여 이 URL을 자동으로 구성합니다.
|
||||
</Note>
|
||||
|
||||
Cortex Agents, 사용자 정의 도구, 응답 크기 제한 및 거버넌스 옵션을 포함한 전체 사양은 [Snowflake 관리형 MCP 서버 문서](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp)를 참조하세요.
|
||||
|
||||
## CrewAI AMP에서 Snowflake 연결
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/snowflake-configure.png" alt="CrewAI AMP에서 Snowflake 연동 구성" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="도구 및 연동 열기">
|
||||
CrewAI AMP 왼쪽 사이드바에서 **도구 및 연동**으로 이동하고, 애플리케이션 목록에서 **Snowflake**를 찾아 구성 패널을 엽니다.
|
||||
</Step>
|
||||
|
||||
<Step title="연결 세부 정보 제공">
|
||||
CrewAI가 Snowflake MCP 서버에 연결하는 데 사용하는 연결 필드를 채웁니다:
|
||||
|
||||
| 필드 | 필수 | 설명 |
|
||||
|------|------|------|
|
||||
| **이름** | 예 | 이 연결의 설명적 이름(기본값: `Snowflake`). |
|
||||
| **설명** | 아니오 | 이 연결이 제공하는 내용에 대한 선택적 요약. |
|
||||
| **계정 URL** | 예 | Snowflake 계정 URL, 예: `xy12345.us-east-1.snowflakecomputing.com`. |
|
||||
| **데이터베이스** | 예 | MCP 서버가 포함된 데이터베이스(예: `MY_DATABASE`). |
|
||||
| **스키마** | 예 | MCP 서버가 포함된 스키마(예: `MY_SCHEMA`). |
|
||||
| **MCP 서버 이름** | 예 | Snowflake에서 생성한 MCP 서버 객체의 이름(예: `MY_MCP_SERVER`). |
|
||||
</Step>
|
||||
|
||||
<Step title="인증 방법 선택">
|
||||
CrewAI가 Snowflake에 인증하는 방법을 선택합니다. **OAuth**가 권장됩니다.
|
||||
|
||||
- **OAuth 사용** — 자격 증명을 공유하지 않고 토큰 기반 인증을 위해 OAuth 2.0을 사용하여 안전하게 연결합니다. CrewAI가 전체 인증 흐름을 처리하고 자동으로 토큰을 갱신합니다. 양식에 표시된 **리디렉트 URI**(`https://oauth.crewai.com/oauth/add`)를 복사하여 Snowflake [OAuth 보안 연동](https://docs.snowflake.com/en/user-guide/oauth-custom)에 인증된 리디렉트 URI로 등록하세요.
|
||||
- **개인 액세스 토큰 사용** — Snowflake 계정 설정에서 생성한 [프로그래밍 방식 액세스 토큰](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens)을 사용하여 인증합니다. 노출을 제한하기 위해 토큰에 최소 권한 역할을 할당하세요.
|
||||
</Step>
|
||||
|
||||
<Step title="인증">
|
||||
**인증**을 클릭합니다. OAuth의 경우 Snowflake로 리디렉션되어 액세스를 승인합니다. 인증되면 Snowflake 서버가 연결 목록에 나타나고 해당 도구를 크루에서 사용할 수 있게 됩니다.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
OAuth를 사용하면 각 사용자가 개별적으로 인증하며 쿼리는 해당 Snowflake `DEFAULT_ROLE`로 실행됩니다. 연결하는 사용자에게 기본 역할과 웨어하우스가 설정되어 있는지 확인하세요(`ALTER USER <username> SET DEFAULT_ROLE = '<role>' DEFAULT_WAREHOUSE = '<warehouse>'`). 그래야 Cortex Analyst 및 SQL 도구에 실행할 컴퓨팅이 있습니다.
|
||||
</Tip>
|
||||
|
||||
## 크루에서 Snowflake 도구 사용
|
||||
|
||||
연결되면 MCP 서버가 노출하는 도구가 **도구 및 연동** 페이지에서 기본 연결과 함께 표시됩니다. 다음을 수행할 수 있습니다:
|
||||
|
||||
- 다른 CrewAI 도구처럼 크루의 **에이전트에 도구를 할당**합니다.
|
||||
- **가시성을 관리**하여 어떤 팀원이 연결을 사용할 수 있는지 제어합니다.
|
||||
- 연결 목록에서 언제든지 연결을 **편집하거나 제거**합니다.
|
||||
|
||||
이제 에이전트가 Cortex Analyst에 메트릭을 요청하고, 문서에 대해 Cortex Search를 실행하고, SQL을 실행할 수 있으며 — 결과가 자동으로 추론에 반영됩니다.
|
||||
|
||||
<Warning>
|
||||
Snowflake는 MCP 서버에 거버넌스를 적용합니다: 역할 기반 액세스 제어가 사용자가 발견하고 호출할 수 있는 도구를 결정하며, 응답 크기, 도구 수(서버당 최대 50개) 및 재귀 깊이에 제한이 적용됩니다. 도구 호출이 실패하면 연결하는 사용자의 역할에 MCP 서버 및 기본 객체에 대한 필수 권한이 있는지 확인하세요.
|
||||
</Warning>
|
||||
|
||||
## 자세히 알아보기
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Snowflake 관리형 MCP 서버" icon="snowflake" href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp">
|
||||
MCP 서버를 생성하고 관리하기 위한 공식 Snowflake 문서.
|
||||
</Card>
|
||||
<Card title="CrewAI의 Custom MCP 서버" icon="plug" href="/ko/enterprise/guides/custom-mcp-server">
|
||||
CrewAI가 모든 MCP 서버에 연결하는 방법을 알아보세요. Snowflake 연동이 기반으로 하는 기초입니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="도움이 필요하신가요?" icon="headset" href="mailto:support@crewai.com">
|
||||
Snowflake 연동 또는 문제 해결에 대해 지원팀에 문의하세요.
|
||||
</Card>
|
||||
134
docs/pt-BR/enterprise/integrations/snowflake.mdx
Normal file
134
docs/pt-BR/enterprise/integrations/snowflake.mdx
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
title: Integração com Snowflake
|
||||
description: "Conecte agentes CrewAI ao Snowflake Cortex Analyst, Cortex Search e execução SQL através do servidor MCP gerenciado pelo Snowflake."
|
||||
icon: "snowflake"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
## Visão Geral
|
||||
|
||||
Conecte seus agentes CrewAI diretamente aos seus dados no Snowflake através do [servidor MCP gerenciado pelo Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp). A integração com o Snowflake permite que seus agentes consultem dados estruturados com **Cortex Analyst**, pesquisem dados não estruturados com **Cortex Search** e executem SQL governado nos seus warehouses — tudo sem escrever ou hospedar nenhum código de conector.
|
||||
|
||||
Internamente, a integração com o Snowflake é um wrapper gerenciado em torno do suporte a [Custom MCP Server](/pt-BR/enterprise/guides/custom-mcp-server) do CrewAI. O Snowflake expõe suas capacidades de Cortex AI através de um endpoint [Model Context Protocol](https://modelcontextprotocol.io/), e o CrewAI se conecta a ele de forma segura em seu nome. Qualquer ferramenta que você exponha no lado do Snowflake — Cortex Analyst, Cortex Search, execução SQL, Cortex Agents ou suas próprias ferramentas personalizadas — fica disponível para suas crews.
|
||||
|
||||
## Capacidades Principais
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Cortex Analyst" icon="chart-bar">
|
||||
Faça perguntas em linguagem natural e deixe o [Cortex Analyst](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-analyst) gerar e executar SQL nos seus dados **estruturados** usando modelos semânticos ricos.
|
||||
</Card>
|
||||
<Card title="Cortex Search" icon="magnifying-glass">
|
||||
Recupere dados **não estruturados** relevantes para fluxos de trabalho de RAG e conhecimento com o [Cortex Search](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/cortex-search-overview), o serviço de busca totalmente gerenciado do Snowflake.
|
||||
</Card>
|
||||
<Card title="Execução SQL" icon="database">
|
||||
Execute consultas SQL governadas diretamente nos seus warehouses Snowflake, com modo somente leitura configurável, timeouts e seleção de warehouse.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
Como a integração expõe quaisquer ferramentas que seu servidor MCP publica, você também pode expor **Cortex Agents** e **ferramentas personalizadas** (funções definidas pelo usuário e stored procedures) para seus agentes CrewAI.
|
||||
|
||||
## Pré-requisitos
|
||||
|
||||
Antes de usar a integração com o Snowflake, certifique-se de que você tenha:
|
||||
|
||||
- Uma conta [CrewAI AMP](https://app.crewai.com) com assinatura ativa
|
||||
- Uma conta Snowflake com acesso aos recursos de Cortex AI
|
||||
- Um [servidor MCP gerenciado pelo Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp) configurado com as ferramentas que você deseja expor
|
||||
- Privilégios Snowflake apropriados (USAGE/SELECT) no servidor MCP e seus objetos subjacentes
|
||||
|
||||
## Configurando o Servidor Snowflake MCP
|
||||
|
||||
O servidor MCP gerenciado pelo Snowflake é executado dentro da sua conta Snowflake e define quais ferramentas estão disponíveis para clientes externos como o CrewAI. Crie um com o comando [`CREATE MCP SERVER`](https://docs.snowflake.com/en/sql-reference/sql/create-mcp-server), listando os serviços Cortex Search, visualizações semânticas do Cortex Analyst e ferramentas SQL que você deseja expor.
|
||||
|
||||
```sql
|
||||
CREATE MCP SERVER my_mcp_server
|
||||
FROM SPECIFICATION $$
|
||||
tools:
|
||||
- name: "sales_analyst"
|
||||
type: "CORTEX_ANALYST"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.sales_semantic_view"
|
||||
description: "Answer questions about sales metrics"
|
||||
- name: "docs_search"
|
||||
type: "CORTEX_SEARCH_SERVICE_QUERY"
|
||||
identifier: "MY_DATABASE.MY_SCHEMA.support_docs_search"
|
||||
description: "Search internal support documentation"
|
||||
- name: "run_sql"
|
||||
type: "SQL_EXECUTION"
|
||||
description: "Execute read-only SQL queries"
|
||||
$$;
|
||||
```
|
||||
|
||||
<Note>
|
||||
O endpoint MCP segue o formato `https://<account_URL>/api/v2/databases/{database}/schemas/{schema}/mcp-servers/{name}`. O CrewAI constrói esta URL automaticamente a partir do **URL da Conta**, **Banco de Dados**, **Schema** e **Nome do Servidor MCP** que você fornece ao configurar a integração.
|
||||
</Note>
|
||||
|
||||
Para a especificação completa — incluindo Cortex Agents, ferramentas personalizadas, limites de tamanho de resposta e opções de governança — consulte a [documentação do servidor MCP gerenciado pelo Snowflake](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp).
|
||||
|
||||
## Conectando o Snowflake no CrewAI AMP
|
||||
|
||||
<Frame>
|
||||
<img src="/images/enterprise/snowflake-configure.png" alt="Configurar integração Snowflake no CrewAI AMP" />
|
||||
</Frame>
|
||||
|
||||
<Steps>
|
||||
<Step title="Abrir Ferramentas e Integrações">
|
||||
Navegue até **Ferramentas e Integrações** na barra lateral esquerda do CrewAI AMP, encontre **Snowflake** na lista de aplicações e abra seu painel de configuração.
|
||||
</Step>
|
||||
|
||||
<Step title="Fornecer detalhes da conexão">
|
||||
Preencha os campos de conexão que o CrewAI usa para acessar seu servidor Snowflake MCP:
|
||||
|
||||
| Campo | Obrigatório | Descrição |
|
||||
|-------|-------------|-----------|
|
||||
| **Nome** | Sim | Um nome descritivo para esta conexão (padrão: `Snowflake`). |
|
||||
| **Descrição** | Não | Um resumo opcional do que esta conexão fornece. |
|
||||
| **URL da Conta** | Sim | A URL da sua conta Snowflake, ex.: `xy12345.us-east-1.snowflakecomputing.com`. |
|
||||
| **Banco de Dados** | Sim | O banco de dados que contém seu servidor MCP (ex.: `MY_DATABASE`). |
|
||||
| **Schema** | Sim | O schema que contém seu servidor MCP (ex.: `MY_SCHEMA`). |
|
||||
| **Nome do Servidor MCP** | Sim | O nome do objeto de servidor MCP que você criou no Snowflake (ex.: `MY_MCP_SERVER`). |
|
||||
</Step>
|
||||
|
||||
<Step title="Escolher um método de autenticação">
|
||||
Selecione como o CrewAI se autentica no Snowflake. **OAuth** é recomendado.
|
||||
|
||||
- **Usar OAuth** — Conecte-se de forma segura usando OAuth 2.0 para autenticação baseada em tokens sem compartilhar suas credenciais. O CrewAI gerencia todo o fluxo de autorização e renova os tokens automaticamente. Copie o **URI de Redirecionamento** mostrado no formulário (`https://oauth.crewai.com/oauth/add`) e registre-o como um URI de redirecionamento autorizado na sua [integração de segurança OAuth](https://docs.snowflake.com/en/user-guide/oauth-custom) do Snowflake.
|
||||
- **Usar token de acesso pessoal** — Autentique usando um [token de acesso programático](https://docs.snowflake.com/en/user-guide/programmatic-access-tokens) gerado nas configurações da sua conta Snowflake. Atribua uma role com privilégios mínimos ao token para limitar a exposição.
|
||||
</Step>
|
||||
|
||||
<Step title="Autenticar">
|
||||
Clique em **Autenticar**. Para OAuth, você será redirecionado ao Snowflake para autorizar o acesso. Após autenticado, o servidor Snowflake aparece na sua lista de Conexões e suas ferramentas ficam disponíveis para suas crews.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Tip>
|
||||
Com OAuth, cada usuário se autentica individualmente e as consultas são executadas com seu `DEFAULT_ROLE` do Snowflake. Certifique-se de que os usuários que se conectam tenham uma role e warehouse padrão definidos (`ALTER USER <username> SET DEFAULT_ROLE = '<role>' DEFAULT_WAREHOUSE = '<warehouse>'`) para que as ferramentas Cortex Analyst e SQL tenham capacidade de computação para execução.
|
||||
</Tip>
|
||||
|
||||
## Usando Ferramentas Snowflake nas Suas Crews
|
||||
|
||||
Uma vez conectado, as ferramentas que seu servidor MCP expõe aparecem junto com as conexões integradas na página **Ferramentas e Integrações**. Você pode:
|
||||
|
||||
- **Atribuir ferramentas a agentes** nas suas crews como qualquer outra ferramenta CrewAI.
|
||||
- **Gerenciar visibilidade** para controlar quais membros do time podem usar a conexão.
|
||||
- **Editar ou remover** a conexão a qualquer momento na lista de Conexões.
|
||||
|
||||
Seus agentes agora podem solicitar métricas ao Cortex Analyst, executar Cortex Search nos seus documentos e executar SQL — com os resultados fluindo automaticamente para o raciocínio deles.
|
||||
|
||||
<Warning>
|
||||
O Snowflake impõe governança no servidor MCP: o controle de acesso baseado em roles determina quais ferramentas um usuário pode descobrir e invocar, e limites se aplicam ao tamanho da resposta, contagem de ferramentas (máximo de 50 por servidor) e profundidade de recursão. Se uma chamada de ferramenta falhar, confirme que a role do usuário conectado possui os privilégios necessários no servidor MCP e seus objetos subjacentes.
|
||||
</Warning>
|
||||
|
||||
## Saiba Mais
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Servidor MCP Gerenciado pelo Snowflake" icon="snowflake" href="https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-mcp">
|
||||
Documentação oficial do Snowflake para criar e governar o servidor MCP.
|
||||
</Card>
|
||||
<Card title="Servidores Custom MCP no CrewAI" icon="plug" href="/pt-BR/enterprise/guides/custom-mcp-server">
|
||||
Saiba como o CrewAI se conecta a qualquer servidor MCP, a base sobre a qual a integração Snowflake é construída.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
<Card title="Precisa de Ajuda?" icon="headset" href="mailto:support@crewai.com">
|
||||
Entre em contato com nossa equipe de suporte para obter ajuda com a integração Snowflake ou solução de problemas.
|
||||
</Card>
|
||||
320
lib/crewai/src/crewai/flow/dsl.py
Normal file
320
lib/crewai/src/crewai/flow/dsl.py
Normal file
@@ -0,0 +1,320 @@
|
||||
"""Flow authoring DSL: the ``@start`` / ``@listen`` / ``@router`` decorators
|
||||
plus the ``or_`` / ``and_`` condition combinators.
|
||||
|
||||
These decorators wrap user methods into the typed wrappers defined in
|
||||
``flow_wrappers`` and record their trigger conditions. The structural model
|
||||
those conditions feed is built in ``flow_definition``; execution happens in
|
||||
``runtime``.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from typing import Any, ParamSpec, TypeVar
|
||||
|
||||
from crewai.flow.constants import AND_CONDITION, OR_CONDITION
|
||||
from crewai.flow.flow_definition import (
|
||||
_extract_all_methods,
|
||||
is_flow_condition_dict,
|
||||
is_flow_method_callable,
|
||||
is_flow_method_name,
|
||||
)
|
||||
from crewai.flow.flow_wrappers import (
|
||||
FlowCondition,
|
||||
FlowConditions,
|
||||
ListenMethod,
|
||||
RouterMethod,
|
||||
StartMethod,
|
||||
)
|
||||
|
||||
|
||||
P = ParamSpec("P")
|
||||
R = TypeVar("R")
|
||||
|
||||
|
||||
def start(
|
||||
condition: str | FlowCondition | Callable[..., Any] | None = None,
|
||||
) -> Callable[[Callable[P, R]], StartMethod[P, R]]:
|
||||
"""Marks a method as a flow's starting point.
|
||||
|
||||
This decorator designates a method as an entry point for the flow execution.
|
||||
It can optionally specify conditions that trigger the start based on other
|
||||
method executions.
|
||||
|
||||
Args:
|
||||
condition: Defines when the start method should execute. Can be:
|
||||
- str: Name of a method that triggers this start
|
||||
- FlowCondition: Result from or_() or and_(), including nested conditions
|
||||
- Callable[..., Any]: A method reference that triggers this start
|
||||
Default is None, meaning unconditional start.
|
||||
|
||||
Returns:
|
||||
A decorator function that wraps the method as a flow start point and preserves its signature.
|
||||
|
||||
Raises:
|
||||
ValueError: If the condition format is invalid.
|
||||
|
||||
Examples:
|
||||
>>> @start() # Unconditional start
|
||||
>>> def begin_flow(self):
|
||||
... pass
|
||||
|
||||
>>> @start("method_name") # Start after specific method
|
||||
>>> def conditional_start(self):
|
||||
... pass
|
||||
|
||||
>>> @start(and_("method1", "method2")) # Start after multiple methods
|
||||
>>> def complex_start(self):
|
||||
... pass
|
||||
"""
|
||||
|
||||
def decorator(func: Callable[P, R]) -> StartMethod[P, R]:
|
||||
"""Decorator that wraps a function as a start method.
|
||||
|
||||
Args:
|
||||
func: The function to wrap as a start method.
|
||||
|
||||
Returns:
|
||||
A StartMethod wrapper around the function.
|
||||
"""
|
||||
wrapper = StartMethod(func)
|
||||
|
||||
if condition is not None:
|
||||
if is_flow_method_name(condition):
|
||||
wrapper.__trigger_methods__ = [condition]
|
||||
wrapper.__condition_type__ = OR_CONDITION
|
||||
elif is_flow_condition_dict(condition):
|
||||
if "conditions" in condition:
|
||||
wrapper.__trigger_condition__ = condition
|
||||
wrapper.__trigger_methods__ = _extract_all_methods(condition)
|
||||
wrapper.__condition_type__ = condition["type"]
|
||||
elif "methods" in condition:
|
||||
wrapper.__trigger_methods__ = condition["methods"]
|
||||
wrapper.__condition_type__ = condition["type"]
|
||||
else:
|
||||
raise ValueError(
|
||||
"Condition dict must contain 'conditions' or 'methods'"
|
||||
)
|
||||
elif is_flow_method_callable(condition):
|
||||
wrapper.__trigger_methods__ = [condition.__name__]
|
||||
wrapper.__condition_type__ = OR_CONDITION
|
||||
else:
|
||||
raise ValueError(
|
||||
"Condition must be a method, string, or a result of or_() or and_()"
|
||||
)
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def listen(
|
||||
condition: str | FlowCondition | Callable[..., Any],
|
||||
) -> Callable[[Callable[P, R]], ListenMethod[P, R]]:
|
||||
"""Creates a listener that executes when specified conditions are met.
|
||||
|
||||
This decorator sets up a method to execute in response to other method
|
||||
executions in the flow. It supports both simple and complex triggering
|
||||
conditions.
|
||||
|
||||
Args:
|
||||
condition: Specifies when the listener should execute.
|
||||
|
||||
Returns:
|
||||
A decorator function that wraps the method as a flow listener and preserves its signature.
|
||||
|
||||
Raises:
|
||||
ValueError: If the condition format is invalid.
|
||||
|
||||
Examples:
|
||||
>>> @listen("process_data")
|
||||
>>> def handle_processed_data(self):
|
||||
... pass
|
||||
|
||||
>>> @listen("method_name")
|
||||
>>> def handle_completion(self):
|
||||
... pass
|
||||
"""
|
||||
|
||||
def decorator(func: Callable[P, R]) -> ListenMethod[P, R]:
|
||||
"""Decorator that wraps a function as a listener method.
|
||||
|
||||
Args:
|
||||
func: The function to wrap as a listener method.
|
||||
|
||||
Returns:
|
||||
A ListenMethod wrapper around the function.
|
||||
"""
|
||||
wrapper = ListenMethod(func)
|
||||
|
||||
if is_flow_method_name(condition):
|
||||
wrapper.__trigger_methods__ = [condition]
|
||||
wrapper.__condition_type__ = OR_CONDITION
|
||||
elif is_flow_condition_dict(condition):
|
||||
if "conditions" in condition:
|
||||
wrapper.__trigger_condition__ = condition
|
||||
wrapper.__trigger_methods__ = _extract_all_methods(condition)
|
||||
wrapper.__condition_type__ = condition["type"]
|
||||
elif "methods" in condition:
|
||||
wrapper.__trigger_methods__ = condition["methods"]
|
||||
wrapper.__condition_type__ = condition["type"]
|
||||
else:
|
||||
raise ValueError(
|
||||
"Condition dict must contain 'conditions' or 'methods'"
|
||||
)
|
||||
elif is_flow_method_callable(condition):
|
||||
wrapper.__trigger_methods__ = [condition.__name__]
|
||||
wrapper.__condition_type__ = OR_CONDITION
|
||||
else:
|
||||
raise ValueError(
|
||||
"Condition must be a method, string, or a result of or_() or and_()"
|
||||
)
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def router(
|
||||
condition: str | FlowCondition | Callable[..., Any],
|
||||
) -> Callable[[Callable[P, R]], RouterMethod[P, R]]:
|
||||
"""Creates a routing method that directs flow execution based on conditions.
|
||||
|
||||
This decorator marks a method as a router, which can dynamically determine
|
||||
the next steps in the flow based on its return value. Routers are triggered
|
||||
by specified conditions and can return constants that determine which path
|
||||
the flow should take.
|
||||
|
||||
Args:
|
||||
condition: Specifies when the router should execute. Can be:
|
||||
- str: Name of a method that triggers this router
|
||||
- FlowCondition: Result from or_() or and_(), including nested conditions
|
||||
- Callable[..., Any]: A method reference that triggers this router
|
||||
|
||||
Returns:
|
||||
A decorator function that wraps the method as a router and preserves its signature.
|
||||
|
||||
Raises:
|
||||
ValueError: If the condition format is invalid.
|
||||
|
||||
Examples:
|
||||
>>> @router("check_status")
|
||||
>>> def route_based_on_status(self):
|
||||
... if self.state.status == "success":
|
||||
... return "SUCCESS"
|
||||
... return "FAILURE"
|
||||
|
||||
>>> @router(and_("validate", "process"))
|
||||
>>> def complex_routing(self):
|
||||
... if all([self.state.valid, self.state.processed]):
|
||||
... return "CONTINUE"
|
||||
... return "STOP"
|
||||
"""
|
||||
|
||||
def decorator(func: Callable[P, R]) -> RouterMethod[P, R]:
|
||||
"""Decorator that wraps a function as a router method.
|
||||
|
||||
Args:
|
||||
func: The function to wrap as a router method.
|
||||
|
||||
Returns:
|
||||
A RouterMethod wrapper around the function.
|
||||
"""
|
||||
wrapper = RouterMethod(func)
|
||||
|
||||
if is_flow_method_name(condition):
|
||||
wrapper.__trigger_methods__ = [condition]
|
||||
wrapper.__condition_type__ = OR_CONDITION
|
||||
elif is_flow_condition_dict(condition):
|
||||
if "conditions" in condition:
|
||||
wrapper.__trigger_condition__ = condition
|
||||
wrapper.__trigger_methods__ = _extract_all_methods(condition)
|
||||
wrapper.__condition_type__ = condition["type"]
|
||||
elif "methods" in condition:
|
||||
wrapper.__trigger_methods__ = condition["methods"]
|
||||
wrapper.__condition_type__ = condition["type"]
|
||||
else:
|
||||
raise ValueError(
|
||||
"Condition dict must contain 'conditions' or 'methods'"
|
||||
)
|
||||
elif is_flow_method_callable(condition):
|
||||
wrapper.__trigger_methods__ = [condition.__name__]
|
||||
wrapper.__condition_type__ = OR_CONDITION
|
||||
else:
|
||||
raise ValueError(
|
||||
"Condition must be a method, string, or a result of or_() or and_()"
|
||||
)
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def or_(*conditions: str | FlowCondition | Callable[..., Any]) -> FlowCondition:
|
||||
"""Combines multiple conditions with OR logic for flow control.
|
||||
|
||||
Creates a condition that is satisfied when any of the specified conditions
|
||||
are met. This is used with @start, @listen, or @router decorators to create
|
||||
complex triggering conditions.
|
||||
|
||||
Args:
|
||||
conditions: Variable number of conditions that can be method names, existing condition dictionaries, or method references.
|
||||
|
||||
Returns:
|
||||
A condition dictionary with format {"type": "OR", "conditions": list_of_conditions} where each condition can be a string (method name) or a nested dict
|
||||
|
||||
Raises:
|
||||
ValueError: If condition format is invalid.
|
||||
|
||||
Examples:
|
||||
>>> @listen(or_("success", "timeout"))
|
||||
>>> def handle_completion(self):
|
||||
... pass
|
||||
|
||||
>>> @listen(or_(and_("step1", "step2"), "step3"))
|
||||
>>> def handle_nested(self):
|
||||
... pass
|
||||
"""
|
||||
processed_conditions: FlowConditions = []
|
||||
for condition in conditions:
|
||||
if is_flow_condition_dict(condition) or is_flow_method_name(condition):
|
||||
processed_conditions.append(condition)
|
||||
elif is_flow_method_callable(condition):
|
||||
processed_conditions.append(condition.__name__)
|
||||
else:
|
||||
raise ValueError("Invalid condition in or_()")
|
||||
return {"type": OR_CONDITION, "conditions": processed_conditions}
|
||||
|
||||
|
||||
def and_(*conditions: str | FlowCondition | Callable[..., Any]) -> FlowCondition:
|
||||
"""Combines multiple conditions with AND logic for flow control.
|
||||
|
||||
Creates a condition that is satisfied only when all specified conditions
|
||||
are met. This is used with @start, @listen, or @router decorators to create
|
||||
complex triggering conditions.
|
||||
|
||||
Args:
|
||||
*conditions: Variable number of conditions that can be method names, existing condition dictionaries, or method references.
|
||||
|
||||
Returns:
|
||||
A condition dictionary with format {"type": "AND", "conditions": list_of_conditions}
|
||||
where each condition can be a string (method name) or a nested dict
|
||||
|
||||
Raises:
|
||||
ValueError: If any condition is invalid.
|
||||
|
||||
Examples:
|
||||
>>> @listen(and_("validated", "processed"))
|
||||
>>> def handle_complete_data(self):
|
||||
... pass
|
||||
|
||||
>>> @listen(and_(or_("step1", "step2"), "step3"))
|
||||
>>> def handle_nested(self):
|
||||
... pass
|
||||
"""
|
||||
processed_conditions: FlowConditions = []
|
||||
for condition in conditions:
|
||||
if is_flow_condition_dict(condition) or is_flow_method_name(condition):
|
||||
processed_conditions.append(condition)
|
||||
elif is_flow_method_callable(condition):
|
||||
processed_conditions.append(condition.__name__)
|
||||
else:
|
||||
raise ValueError("Invalid condition in and_()")
|
||||
return {"type": AND_CONDITION, "conditions": processed_conditions}
|
||||
File diff suppressed because it is too large
Load Diff
1036
lib/crewai/src/crewai/flow/flow_definition.py
Normal file
1036
lib/crewai/src/crewai/flow/flow_definition.py
Normal file
File diff suppressed because it is too large
Load Diff
3320
lib/crewai/src/crewai/flow/runtime.py
Normal file
3320
lib/crewai/src/crewai/flow/runtime.py
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -569,13 +569,13 @@ class TestFlowResumeWithFeedback:
|
||||
|
||||
flow = TestFlow.from_pending("async-direct-test", persistence)
|
||||
|
||||
with patch("crewai.flow.flow.crewai_event_bus.emit"):
|
||||
with patch("crewai.flow.runtime.crewai_event_bus.emit"):
|
||||
result = await flow.resume_async("async feedback")
|
||||
|
||||
assert flow.last_human_feedback is not None
|
||||
assert flow.last_human_feedback.feedback == "async feedback"
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_resume_basic(self, mock_emit: MagicMock) -> None:
|
||||
"""Test basic resume functionality."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
@@ -615,7 +615,7 @@ class TestFlowResumeWithFeedback:
|
||||
|
||||
assert persistence.load_pending_feedback("resume-test-123") is None
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_resume_routing(self, mock_emit: MagicMock) -> None:
|
||||
"""Test resume with routing."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
@@ -697,7 +697,7 @@ class TestAsyncHumanFeedbackIntegration:
|
||||
assert hasattr(method, "__human_feedback_config__")
|
||||
assert method.__human_feedback_config__.provider is not None
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_async_provider_pauses_flow(self, mock_emit: MagicMock) -> None:
|
||||
"""Test that async provider pauses flow execution."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
@@ -743,7 +743,7 @@ class TestAsyncHumanFeedbackIntegration:
|
||||
persisted = persistence.load_pending_feedback(flow_id)
|
||||
assert persisted is not None
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_full_async_flow_cycle(self, mock_emit: MagicMock) -> None:
|
||||
"""Test complete async flow: start -> pause -> resume."""
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
@@ -804,7 +804,7 @@ class TestAsyncHumanFeedbackIntegration:
|
||||
class TestAutoPersistence:
|
||||
"""Tests for automatic persistence when no persistence is provided."""
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_auto_persistence_when_none_provided(self, mock_emit: MagicMock) -> None:
|
||||
"""Test that persistence is auto-created when HumanFeedbackPending is raised."""
|
||||
|
||||
@@ -925,7 +925,7 @@ class TestCollapseToOutcomeJsonParsing:
|
||||
class TestLLMObjectPreservedInContext:
|
||||
"""Tests that BaseLLM objects have their model string preserved in PendingFeedbackContext."""
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_basellm_object_model_string_survives_roundtrip(self, mock_emit: MagicMock) -> None:
|
||||
"""Test that when llm is a BaseLLM object, its model string is stored in context
|
||||
so that outcome collapsing works after async pause/resume.
|
||||
@@ -1125,7 +1125,7 @@ class TestAsyncHumanFeedbackEdgeCases:
|
||||
|
||||
flow = TestFlow.from_pending("default-test", persistence)
|
||||
|
||||
with patch("crewai.flow.flow.crewai_event_bus.emit"):
|
||||
with patch("crewai.flow.runtime.crewai_event_bus.emit"):
|
||||
result = flow.resume("")
|
||||
|
||||
assert flow.last_human_feedback.outcome == "approved"
|
||||
@@ -1159,7 +1159,7 @@ class TestAsyncHumanFeedbackEdgeCases:
|
||||
|
||||
flow = TestFlow.from_pending("no-feedback-test", persistence)
|
||||
|
||||
with patch("crewai.flow.flow.crewai_event_bus.emit"):
|
||||
with patch("crewai.flow.runtime.crewai_event_bus.emit"):
|
||||
result = flow.resume()
|
||||
|
||||
assert flow.last_human_feedback.outcome == "approved"
|
||||
@@ -1213,7 +1213,7 @@ class TestLiveLLMPreservationOnResume:
|
||||
assert hasattr(method, "_hf_llm")
|
||||
assert method._hf_llm == "gpt-4o-mini"
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_resume_async_uses_live_basellm_over_serialized_string(
|
||||
self, mock_emit: MagicMock
|
||||
) -> None:
|
||||
@@ -1286,7 +1286,7 @@ class TestLiveLLMPreservationOnResume:
|
||||
# And verify it's a BaseLLM instance, not a string
|
||||
assert isinstance(captured_llm[0], BaseLLM)
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_resume_async_falls_back_to_serialized_string_when_no_hf_llm(
|
||||
self, mock_emit: MagicMock
|
||||
) -> None:
|
||||
@@ -1344,7 +1344,7 @@ class TestLiveLLMPreservationOnResume:
|
||||
assert isinstance(captured_llm[0], BaseLLMClass)
|
||||
assert captured_llm[0].model == "gpt-4o-mini"
|
||||
|
||||
@patch("crewai.flow.flow.crewai_event_bus.emit")
|
||||
@patch("crewai.flow.runtime.crewai_event_bus.emit")
|
||||
def test_resume_async_uses_string_from_context_when_hf_llm_is_string(
|
||||
self, mock_emit: MagicMock
|
||||
) -> None:
|
||||
|
||||
@@ -161,6 +161,87 @@ def test_flow_with_or_condition():
|
||||
)
|
||||
|
||||
|
||||
def test_or_listener_fires_once_across_parallel_starts():
|
||||
"""Parallel ``@start`` paths feeding ``or_`` must not double-fire the listener."""
|
||||
fire_count = 0
|
||||
|
||||
class ParallelOrFlow(Flow):
|
||||
@start()
|
||||
async def fast_start(self):
|
||||
return "fast"
|
||||
|
||||
@start()
|
||||
async def slow_start(self):
|
||||
await asyncio.sleep(0.2)
|
||||
return "slow"
|
||||
|
||||
@listen(or_(fast_start, slow_start))
|
||||
def handler(self):
|
||||
nonlocal fire_count
|
||||
fire_count += 1
|
||||
|
||||
asyncio.run(ParallelOrFlow().kickoff_async())
|
||||
|
||||
assert fire_count == 1
|
||||
|
||||
|
||||
def test_or_listener_re_arms_across_router_loop():
|
||||
"""Regression for #5972: multi-source ``or_`` re-fires on each router emission."""
|
||||
fire_count = 0
|
||||
|
||||
class CyclicOrFlow(Flow):
|
||||
iteration = 0
|
||||
|
||||
@start()
|
||||
def kick(self):
|
||||
return "kick"
|
||||
|
||||
@router(kick)
|
||||
def initial_router(self):
|
||||
return "SignalA"
|
||||
|
||||
@listen(or_("SignalA", "SignalB"))
|
||||
def handler(self):
|
||||
nonlocal fire_count
|
||||
fire_count += 1
|
||||
|
||||
@router(handler)
|
||||
def loop_router(self):
|
||||
self.iteration += 1
|
||||
return "stop" if self.iteration >= 3 else "SignalB"
|
||||
|
||||
CyclicOrFlow().kickoff()
|
||||
|
||||
assert fire_count == 3
|
||||
|
||||
|
||||
def test_or_listener_does_not_double_fire_across_chained_routers():
|
||||
"""Chained routers within one dispatch wave must not re-fire the same ``or_`` listener."""
|
||||
fire_count = 0
|
||||
|
||||
class ChainedRouterOrFlow(Flow):
|
||||
@start()
|
||||
def kick(self):
|
||||
return "kick"
|
||||
|
||||
@router(kick)
|
||||
def router_a(self):
|
||||
return "SignalA"
|
||||
|
||||
@router("SignalA")
|
||||
def router_b(self):
|
||||
return "SignalB"
|
||||
|
||||
@listen(or_("SignalA", "SignalB"))
|
||||
def handler(self):
|
||||
nonlocal fire_count
|
||||
fire_count += 1
|
||||
|
||||
ChainedRouterOrFlow().kickoff()
|
||||
|
||||
assert fire_count == 1
|
||||
|
||||
|
||||
def test_flow_with_router():
|
||||
"""Test a flow that uses a router method to determine the next step."""
|
||||
execution_order = []
|
||||
|
||||
@@ -181,7 +181,7 @@ exclude-newer = "3 days"
|
||||
# transformers 4.57.6 has CVE-2026-1839; force 5.4+ (docling 2.84 allows huggingface-hub>=1).
|
||||
# cryptography 46.0.6 has CVE-2026-39892; force 46.0.7+.
|
||||
# pypdf <6.10.2 has GHSA-4pxv-j86v-mhcw, GHSA-7gw9-cf7v-778f, GHSA-x284-j5p8-9c5p; force 6.10.2+.
|
||||
# uv <0.11.6 has GHSA-pjjw-68hj-v9mw; force 0.11.6+.
|
||||
# uv <0.11.15 has GHSA-4gg8-gxpx-9rph (and earlier GHSA-pjjw-68hj-v9mw); force 0.11.15+.
|
||||
# python-multipart <0.0.27 has GHSA-pp6c-gr5w-3c5g (DoS via unbounded multipart headers).
|
||||
# gitpython <3.1.50 has GHSA-mv93-w799-cj2w (config_writer newline injection bypassing the 3.1.49 patch -> RCE via core.hooksPath).
|
||||
# urllib3 <2.7.0 has GHSA-qccp-gfcp-xxvc (ProxyManager cross-origin redirect leaks Authorization/Cookie) and GHSA-mf9v-mfxr-j63j (streaming decompression-bomb bypass); force 2.7.0+.
|
||||
@@ -203,7 +203,7 @@ override-dependencies = [
|
||||
"transformers>=5.4.0; python_version >= '3.10'",
|
||||
"cryptography>=46.0.7",
|
||||
"pypdf>=6.10.2,<7",
|
||||
"uv>=0.11.6,<1",
|
||||
"uv>=0.11.15,<1",
|
||||
"python-multipart>=0.0.27,<1",
|
||||
"gitpython>=3.1.50,<4",
|
||||
"langsmith>=0.8.0,<1",
|
||||
|
||||
47
uv.lock
generated
47
uv.lock
generated
@@ -13,12 +13,9 @@ resolution-markers = [
|
||||
]
|
||||
|
||||
[options]
|
||||
exclude-newer = "2026-05-19T15:27:50.647689Z"
|
||||
exclude-newer = "2026-05-29T06:38:49.259217Z"
|
||||
exclude-newer-span = "P3D"
|
||||
|
||||
[options.exclude-newer-package]
|
||||
starlette = "2026-05-22T16:00:00Z"
|
||||
|
||||
[manifest]
|
||||
members = [
|
||||
"crewai",
|
||||
@@ -46,7 +43,7 @@ overrides = [
|
||||
{ name = "starlette", specifier = ">=1.0.1" },
|
||||
{ name = "transformers", marker = "python_full_version >= '3.10'", specifier = ">=5.4.0" },
|
||||
{ name = "urllib3", specifier = ">=2.7.0" },
|
||||
{ name = "uv", specifier = ">=0.11.6,<1" },
|
||||
{ name = "uv", specifier = ">=0.11.15,<1" },
|
||||
]
|
||||
|
||||
[manifest.dependency-groups]
|
||||
@@ -9449,28 +9446,28 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "uv"
|
||||
version = "0.11.7"
|
||||
version = "0.11.17"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9b/7d/17750123a8c8e324627534fe1ae2e7a46689db8492f1a834ab4fd229a7d8/uv-0.11.7.tar.gz", hash = "sha256:46d971489b00bdb27e0aa715e4a5cd4ef2c28ea5b6ef78f2b67bf861eb44b405", size = 4083385, upload-time = "2026-04-15T21:42:55.474Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2c/8e/ec34c19d0f254fcbcc5c1ce8c7f06e47e0f69a7e1a0269c1d59cb0b0f279/uv-0.11.17.tar.gz", hash = "sha256:1d1be74deec997db1dda05a7e67541c904d65cbfd72e455d3c0a2a1e4bf2cddf", size = 4203607, upload-time = "2026-05-28T20:39:47.707Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/5b/2bb2ab6fe6c78c2be10852482ef0cae5f3171460a6e5e24c32c9a0843163/uv-0.11.7-py3-none-linux_armv6l.whl", hash = "sha256:f422d39530516b1dfb28bb6e90c32bb7dacd50f6a383cd6e40c1a859419fbc8c", size = 23757265, upload-time = "2026-04-15T21:43:14.494Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/f5/36ff27b01e60a88712628c8a5a6003b8e418883c24e084e506095844a797/uv-0.11.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:8b2fe1ec6775dad10183e3fdce430a5b37b7857d49763c884f3a67eaa8ca6f8a", size = 23184529, upload-time = "2026-04-15T21:42:30.225Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/fa/f379be661316698f877e78f4c51e5044be0b6f390803387237ad92c4057f/uv-0.11.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:162fa961a9a081dcea6e889c79f738a5ae56507047e4672964972e33c301bea9", size = 21780167, upload-time = "2026-04-15T21:42:44.942Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/7f/fbed29775b0612f4f5679d3226268f1a347161abc1727b4080fb41d9f46f/uv-0.11.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:5985a15a92bd9a170fc1947abb1fbc3e9828c5a430ad85b5bed8356c20b67a71", size = 23609640, upload-time = "2026-04-15T21:42:22.57Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/de/989a69634a869a22322770120557c2d8cbba5b77ec7cfad326b4ec0f0547/uv-0.11.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:fab0bb43fbbc0ee5b5fee212078d2300c371b725faff7cf72eeaafa0bff0606b", size = 23322484, upload-time = "2026-04-15T21:43:26.52Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/24/08/c1af05ea602eb4eb75d86badb6b0594cc104c3ca83ccf06d9ed4dd2186ad/uv-0.11.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:23d457d6731ebdb83f1bffebe4894edab2ef43c1ec5488433c74300db4958924", size = 23326385, upload-time = "2026-04-15T21:42:41.32Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/99/e246962da06383e992ecab55000c62a50fb36efef855ea7264fad4816bf4/uv-0.11.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d6a17507b8139b8803f445a03fd097f732ce8356b1b7b13cdb4dd8ef7f4b2e0", size = 24985751, upload-time = "2026-04-15T21:42:37.777Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/2d/b0b68083859579ce811996c1480765ec6a2442b44c451eaef53e6218fbae/uv-0.11.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd48823ca4b505124389f49ae50626ba9f57212b9047738efc95126ed5f3844d", size = 25724160, upload-time = "2026-04-15T21:43:18.762Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/19/5970e89d9e458fd3c4966bbc586a685a1c0ab0a8bf334503f63fa20b925b/uv-0.11.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb91f52ee67e10d5290f2c2897e2171357f1a10966de38d83eefa93d96843b0c", size = 25028512, upload-time = "2026-04-15T21:43:02.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/eb/4e1557daf6693cb446ed28185664ad6682fd98c6dbac9e433cbc35df450a/uv-0.11.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e4d5e31bea86e1b6e0f5a0f95e14e80018e6f6c0129256d2915a4b3d793644d", size = 24933975, upload-time = "2026-04-15T21:42:18.828Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/55/3b517ec8297f110d6981f525cccf26f86e30883fbb9c282769cffbcdcfca/uv-0.11.7-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:ceae53b202ea92bc954759bc7c7570cdcd5c3512fce15701198c19fd2dfb8605", size = 23706403, upload-time = "2026-04-15T21:43:10.664Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dc/30/7d93a0312d60e147722967036dc8ea37baab4802784bddc22464cb707deb/uv-0.11.7-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:f97e9f4e4d44fb5c4dfaa05e858ef3414a96416a2e4af270ecd88a3e5fb049a9", size = 24495797, upload-time = "2026-04-15T21:42:26.538Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/89/d49480bdab7725d36982793857e461d471bde8e1b7f438ffccee677a7bf8/uv-0.11.7-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:750ee5b96959b807cf442b73dd8b55111862d63f258f896787ea5f06b68aaca9", size = 24580471, upload-time = "2026-04-15T21:42:52.871Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/9f/c57dc03b48be17b564e304eb9ff982890c12dfb888b1ce370788733329ab/uv-0.11.7-py3-none-musllinux_1_1_i686.whl", hash = "sha256:f394331f0507e80ee732cb3df737589de53bed999dd02a6d24682f08c2f8ac4f", size = 24113637, upload-time = "2026-04-15T21:42:34.094Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/ba/b87e358b629a68258527e3490e73b7b148770f4d2257842dea3b7981d4e8/uv-0.11.7-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:0df59ab0c6a4b14a763e8445e1c303af9abeb53cdfa4428daf9ff9642c0a3cce", size = 25119850, upload-time = "2026-04-15T21:43:22.529Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/74/16d229e1d8574bcbafa6dc643ac20b70c3e581f42ac31a6f4fd53035ffe3/uv-0.11.7-py3-none-win32.whl", hash = "sha256:553e67cc766d013ce24353fecd4ea5533d2aedcfd35f9fac430e07b1d1f23ed4", size = 22918454, upload-time = "2026-04-15T21:42:58.702Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/1d/b73e473da616ac758b8918fb218febcc46ddf64cba9e03894dfa226b28bd/uv-0.11.7-py3-none-win_amd64.whl", hash = "sha256:5674dfb5944513f4b3735b05c2deba6b1b01151f46729d533d413a9a905f8c5d", size = 25447744, upload-time = "2026-04-15T21:42:48.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/bb/e6bfdea92ed270f3445a5a3c17599d041b3f2dbc5026c09e02830a03bbaf/uv-0.11.7-py3-none-win_arm64.whl", hash = "sha256:6158b7e39464f1aa1e040daa0186cae4749a78b5cd80ac769f32ca711b8976b1", size = 23941816, upload-time = "2026-04-15T21:43:06.732Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/2e/e6d42f9d39009eee976f1e5dfd31d3d1943e6e593ad7b191cf11e9744a36/uv-0.11.17-py3-none-linux_armv6l.whl", hash = "sha256:8426bfe315564d414cbc5ba5467595dc6348965e19acec742914f47da3ff269f", size = 23551216, upload-time = "2026-05-28T20:39:05.395Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/ee/d72bcc60f3585653a4b768425854d737d98d65c1765547d25c2999547ea9/uv-0.11.17-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6d1a033cc68cabb4141d6c1e3b66ffc6e970b98ba42e210f33270251e0bd8697", size = 22997377, upload-time = "2026-05-28T20:39:25.21Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/34/1bc69798d9ae998fbc42c61b02883f2ba00d04bdd858e589604d01846287/uv-0.11.17-py3-none-macosx_11_0_arm64.whl", hash = "sha256:58c07ffc272c847d29cd98ca5082fa4304a645f87c718ec900e3cca9026bd096", size = 21630197, upload-time = "2026-05-28T20:39:28.935Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/93/1be48ec6a8933d9a77d0ce5240ed63f68869f68517ccf5d62268ed03f3e8/uv-0.11.17-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:036d6e2940afe8b79637530b01b9241d8cfd174b07f1179a1ebbd42409c38ca3", size = 23414940, upload-time = "2026-05-28T20:39:55.015Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/31/b7488ff49d80090ea9d05d67a4d381a1b4479502e9853e654caa1c1c678e/uv-0.11.17-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:283186700c3e65a4644a73a917232da7d3e4a94d25ea0377a44f5b263fa49577", size = 23096330, upload-time = "2026-05-28T20:39:01.284Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/95/42b6137c5de06278d229c7eef2f314df2a738cd799795bbb44dace21bd6e/uv-0.11.17-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f2e44dfbfc7778d0d90edc6738f237c91e5e37e4e3cfe94c8a312cec56a41485", size = 23101906, upload-time = "2026-05-28T20:39:17.149Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/7c/0ca03b2d19965db6d5dfe0c8cf96a3d0b424503c8cbc3cd2ffdc5869a15d/uv-0.11.17-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a817eeb3026f27a53d3f4b7855a5105f6787dd192140e201eda4d2b9a11b72e", size = 24444409, upload-time = "2026-05-28T20:39:59.218Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/fb/179f55a3b19d47c30ec1f41b9b964da74dfa7053ff310a70a9c4d8cb998d/uv-0.11.17-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bf8f5ad959583dcd2c4ae445c754a97c05700246ff89259f3fd285c9c20f4c00", size = 25540153, upload-time = "2026-05-28T20:39:09.535Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/29/592f42012765c43ae45c112110e214bca7b0cfc08c4c1b52e1dfa47dedd5/uv-0.11.17-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce16892a45134d20165c1ceababe06f3e9ce6a58902db1eff812c8c93626823f", size = 24665906, upload-time = "2026-05-28T20:39:41.254Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/51/b75808766f895248553c6370968509cd4f726e6943e310a8f7a171036ad0/uv-0.11.17-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da839e5a491c9a701d7d327a199cafc76ac27a03ac84fd2a8d4bf32c3af2448", size = 24863325, upload-time = "2026-05-28T20:39:51.006Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/6a/6f27ee69e97f480104bb8ec335f04c2a12add98edfcc4844a68e9538b6e2/uv-0.11.17-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:ec004b3c9bf9cb7756067ad1bd0bf64eb843e6fa2edbfbb3135ee152c14cea91", size = 23521674, upload-time = "2026-05-28T20:38:55.869Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/11/1344aca7c710f794750f74de0e552a54ab24193ecc01fa3b3ae22ff822a1/uv-0.11.17-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:659227cac719b618cc91e02be9e274ad5bd72d74fa278123e6373537e9f28216", size = 24224725, upload-time = "2026-05-28T20:39:32.945Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/44/7b11550c1453ea13b81e549c83523e6ab6ed3231d09b2fd6b9eb19acceaf/uv-0.11.17-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:e301d844eed9401f0f0351de12c55f1306ca05372acb0f28d35717c8ba663a22", size = 24301643, upload-time = "2026-05-28T20:39:45.183Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/36/8f683bc60547b8f93d0e752a8574d13fad776999cb978482b360c053ca22/uv-0.11.17-py3-none-musllinux_1_1_i686.whl", hash = "sha256:f0bf483c0d9fa14283992d56061b498b9d3d4adebd285af8744dc33f64dadfba", size = 23786049, upload-time = "2026-05-28T20:39:20.999Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/dc/7a495db39c2970de4fa375c337dbd617b16780911f88f0511f8fe7f6747c/uv-0.11.17-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:2ccd5487a4a192bc832ea04c867a26883757db8fdfe88bed85d8129c82f9e505", size = 25049786, upload-time = "2026-05-28T20:40:03.292Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/dd/74eff72d749eaf7e19f489878e21a368a7fef58d26ea0c63ec044ecd78b1/uv-0.11.17-py3-none-win32.whl", hash = "sha256:12b701fa32c5be3691759a73956e4462f30fa7b0dfa52ec66cb305bbb6ea4129", size = 22479213, upload-time = "2026-05-28T20:39:13.316Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/99/8af4a92b99a8a4823297c26df727fe957267e03e1196e3caa803c3f6ccb2/uv-0.11.17-py3-none-win_amd64.whl", hash = "sha256:44ec1fe3af839f87370dcf0400c0cab917cc1ce697d563e860fc7d9ed72655e7", size = 25083161, upload-time = "2026-05-28T20:40:07.931Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/76/a689077832d585d29d87f9cd0d65eca1af58abd29a4eab004d0a8a858b9c/uv-0.11.17-py3-none-win_arm64.whl", hash = "sha256:37c915bfcf86f99c1c5be7c9ed21e0d80624067ba47bc8916a3cb0530bc94d27", size = 23544936, upload-time = "2026-05-28T20:39:37.137Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
Reference in New Issue
Block a user