mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-28 04:18:23 +00:00
Compare commits
1 Commits
main
...
add-claude
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07b48034ef |
13
CLAUDE.md
Normal file
13
CLAUDE.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# CLAUDE.md — AI-Assisted Development Guidelines
|
||||
|
||||
This file provides guidance for AI coding agents (Claude Code, Codex, etc.) working on the crewAI codebase.
|
||||
|
||||
## Dependency Management
|
||||
|
||||
**Do NOT use `override-dependencies`** (e.g. in `pyproject.toml` or similar) to resolve security audit or dependency issues.
|
||||
|
||||
This approach:
|
||||
- Does not carry over to downstream projects that depend on crewAI
|
||||
- Can cause dependency conflicts that are potentially unresolvable
|
||||
|
||||
**Instead:** Fix dependency issues by updating the actual dependency versions directly. Pin or bump the real dependency so the fix propagates correctly to all consumers.
|
||||
37
conftest.py
37
conftest.py
@@ -5,7 +5,6 @@ from collections.abc import Generator
|
||||
import gzip
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import tempfile
|
||||
from typing import Any
|
||||
|
||||
@@ -21,25 +20,8 @@ except ModuleNotFoundError:
|
||||
|
||||
|
||||
env_test_path = Path(__file__).parent / ".env.test"
|
||||
|
||||
load_dotenv(env_test_path, override=False)
|
||||
load_dotenv(override=False)
|
||||
|
||||
BEDROCK_HOST_PLACEHOLDER = "bedrock-runtime.vcr.amazonaws.com"
|
||||
_BEDROCK_HOST_RE = re.compile(r"^bedrock-runtime\.[a-z0-9-]+\.amazonaws\.com$")
|
||||
|
||||
|
||||
def _normalize_bedrock_host(host: str) -> str:
|
||||
if _BEDROCK_HOST_RE.match(host):
|
||||
return BEDROCK_HOST_PLACEHOLDER
|
||||
return host
|
||||
|
||||
|
||||
def bedrock_host_matcher(r1: Request, r2: Request) -> bool: # type: ignore[no-any-unimported]
|
||||
"""Match Bedrock requests across AWS regions (CI uses us-east-1, local may use us-west-2)."""
|
||||
return _normalize_bedrock_host(r1.host or "") == _normalize_bedrock_host(
|
||||
r2.host or ""
|
||||
)
|
||||
load_dotenv(env_test_path, override=True)
|
||||
load_dotenv(override=True)
|
||||
|
||||
|
||||
def _patched_make_vcr_request(httpx_request: Any, **kwargs: Any) -> Any:
|
||||
@@ -206,7 +188,6 @@ HEADERS_TO_FILTER = {
|
||||
"anthropic-ratelimit-tokens-remaining": "ANTHROPIC-RATELIMIT-TOKENS-REMAINING-XXX",
|
||||
"anthropic-ratelimit-tokens-reset": "ANTHROPIC-RATELIMIT-TOKENS-RESET-XXX",
|
||||
"x-amz-date": "X-AMZ-DATE-XXX",
|
||||
"x-amz-security-token": "X-AMZ-SECURITY-TOKEN-XXX",
|
||||
"amz-sdk-invocation-id": "AMZ-SDK-INVOCATION-ID-XXX",
|
||||
"accept-encoding": "ACCEPT-ENCODING-XXX",
|
||||
"x-amzn-requestid": "X-AMZN-REQUESTID-XXX",
|
||||
@@ -231,10 +212,6 @@ def _filter_request_headers(request: Request) -> Request: # type: ignore[no-any
|
||||
placeholder_host = "fake-azure-endpoint.openai.azure.com"
|
||||
request.uri = request.uri.replace(original_host, placeholder_host)
|
||||
|
||||
# Normalize Bedrock regional endpoints so cassettes work in any AWS region.
|
||||
if request.host and _BEDROCK_HOST_RE.match(request.host):
|
||||
request.uri = request.uri.replace(request.host, BEDROCK_HOST_PLACEHOLDER)
|
||||
|
||||
return request
|
||||
|
||||
|
||||
@@ -252,11 +229,6 @@ def _filter_response_headers(response: dict[str, Any]) -> dict[str, Any] | None:
|
||||
if body == "" or body == b"" or content_length == ["0"]:
|
||||
return None
|
||||
|
||||
status_code = response.get("status", {}).get("code")
|
||||
if isinstance(status_code, int) and status_code >= 400:
|
||||
# Avoid persisting auth/model errors when re-recording without valid AWS creds.
|
||||
return None
|
||||
|
||||
for encoding_header in ["Content-Encoding", "content-encoding"]:
|
||||
if encoding_header in headers:
|
||||
encoding = headers.pop(encoding_header)
|
||||
@@ -307,11 +279,6 @@ def vcr_cassette_dir(request: Any) -> str:
|
||||
return str(cassette_dir)
|
||||
|
||||
|
||||
def pytest_recording_configure(vcr: Any, config: Any) -> None:
|
||||
"""Register custom VCR matchers for each test cassette session."""
|
||||
vcr.register_matcher("bedrock_host", bedrock_host_matcher)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vcr_config(vcr_cassette_dir: str) -> dict[str, Any]:
|
||||
"""Configure VCR with organized cassette storage."""
|
||||
|
||||
@@ -4,39 +4,6 @@ description: "تحديثات المنتج والتحسينات وإصلاحات
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="27 مايو 2026">
|
||||
## v1.14.6a2
|
||||
|
||||
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
|
||||
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- تحسين `StdioTransport` لمنع تسرب متغيرات البيئة
|
||||
- تحسين تكوين التخطيط ومعالجة المراقبة
|
||||
- إعلان `env_vars` على `DatabricksQueryTool`
|
||||
- إضافة وثائق خطة التحكم بالوكيل
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
- إصلاح تسرب المخرجات المنظمة في حلقات استدعاء الأدوات
|
||||
- حذف الاستدعاءات غير القابلة للعودة وحالة المحول في نقاط التحقق
|
||||
- تسلسل حقول `type[BaseModel]` كـ JSON schema في نقاط التحقق
|
||||
- تجنب `task_started` اليتيمة عند استعادة نطاق الاستئناف
|
||||
- السماح لـ `AgentExecutor` بالاستعادة من نقطة تحقق
|
||||
- تصحيح خطأ مطبعي في MongoDB إلى `pymongo` في تبعيات الحزمة
|
||||
|
||||
### الوثائق
|
||||
- إعادة هيكلة صفحة نقاط التحقق
|
||||
- توثيق خطوة تثبيت حزمة الإدارة لمرة واحدة
|
||||
- نقل Secrets Manager / Workload Identity من replicated-config
|
||||
- إزالة إدخال Skills Repository من سجل التغييرات
|
||||
|
||||
## المساهمون
|
||||
|
||||
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="21 مايو 2026">
|
||||
## v1.14.6a1
|
||||
|
||||
@@ -45,6 +12,7 @@ mode: "wide"
|
||||
## ما الذي تغير
|
||||
|
||||
### الميزات
|
||||
- إضافة مستودع المهارات مع التسجيل، التخزين المؤقت، واجهة سطر الأوامر، وتكامل SDK
|
||||
- توليد ملاحظات إصدار مصنفة للمؤسسات
|
||||
|
||||
### إصلاحات الأخطاء
|
||||
|
||||
@@ -5,419 +5,225 @@ icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
الـ Checkpointing يحفظ لقطة من حالة التنفيذ أثناء التشغيل بحيث يمكن لطاقم أو تدفق أو وكيل الاستئناف بعد الفشل أو التفرع إلى فرع بديل.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="الشرح" icon="lightbulb" href="#الشرح">
|
||||
كيف يعمل الـ Checkpointing: الأحداث والتخزين والوراثة.
|
||||
</Card>
|
||||
<Card title="درس تطبيقي" icon="graduation-cap" href="#درس-تطبيقي-استئناف-طاقم-فاشل">
|
||||
دليل 5 دقائق: تشغيل، إيقاف، استئناف.
|
||||
</Card>
|
||||
<Card title="ادلة عملية" icon="screwdriver-wrench" href="#ادلة-عملية">
|
||||
وصفات مركزة على المهام لسير العمل الشائع.
|
||||
</Card>
|
||||
<Card title="المرجع" icon="book" href="#المرجع">
|
||||
`CheckpointConfig` والأحداث والمزودات وسطر الأوامر.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## الشرح
|
||||
|
||||
### ما هي نقطة الحفظ
|
||||
|
||||
تلتقط نقطة الحفظ كل ما يحتاجه CrewAI لإعادة إنشاء تشغيل أثناء سيره: الحالة الكاملة للطاقم أو التدفق أو الوكيل — التكوين، وذاكرة الوكلاء ومصادر المعرفة، وتقدم المهام، والمخرجات الوسيطة، والحالة الداخلية والسمات — إلى جانب مدخلات الـ kickoff، وسجل الأحداث حتى تلك النقطة، ومعرف نسب يربط نقطة الحفظ بالتشغيل الذي جاءت منه.
|
||||
|
||||
الاستعادة تعيد بناء تلك الحالة وتستمر. تتخطى المهام المكتملة، وتعاد ترطيب الذاكرة والمعرفة، ويعمل العمل التابع على نفس المخرجات التي أنتجها التشغيل الأصلي. التفرع يجري نفس الاستعادة تحت نسب جديد، بحيث يكتب الفرع الجديد والتشغيل الأصلي نقاط الحفظ جنبا إلى جنب دون أن يطمس أحدهما الآخر.
|
||||
|
||||
### متى تكتب نقاط الحفظ
|
||||
|
||||
الـ Checkpointing مدفوع بالأحداث. يشترك وقت التشغيل في الأحداث التي تحددها عبر `on_events` ويكتب نقطة حفظ عند إطلاق أحدها. الافتراضي `task_completed` ينتج نقطة حفظ لكل مهمة منتهية — توازن معقول بين الدقة واستخدام القرص. الأحداث عالية التردد مثل `llm_call_completed` متاحة للاستعادة الدقيقة لكنها تكتب ملفات أكثر بكثير.
|
||||
|
||||
### التخزين
|
||||
|
||||
يتضمن CrewAI مزودين:
|
||||
|
||||
- `JsonProvider` يكتب ملفا لكل نقطة حفظ. قابل للقراءة وسهل التفقد.
|
||||
- `SqliteProvider` يكتب إلى قاعدة بيانات SQLite واحدة. أفضل لنقاط الحفظ عالية التردد.
|
||||
|
||||
كلاهما يحذف أقدم نقاط الحفظ عند تحديد `max_checkpoints`.
|
||||
|
||||
<Note>
|
||||
كتابة نقاط الحفظ بأفضل جهد. فشل نقطة حفظ يسجل لكنه لا يقاطع التشغيل.
|
||||
</Note>
|
||||
|
||||
### نموذج الوراثة
|
||||
|
||||
`Crew` و`Flow` و`Agent` كلها تقبل وسيط `checkpoint`. يرث الأبناء من الأب ما لم يحددوا قيمتهم الخاصة أو يمرروا `False` للانسحاب. فعل الـ Checkpointing مرة واحدة على الطاقم وتشارك كل الوكلاء، أو استبعد وكيلا واحدا بشكل انتقائي.
|
||||
|
||||
## درس تطبيقي: استئناف طاقم فاشل
|
||||
|
||||
هذا الدليل يستغرق حوالي 5 دقائق. ستشغل طاقما بمهمتين، توقفه في المنتصف، ثم تستأنف من نقطة الحفظ المحفوظة.
|
||||
|
||||
<Steps>
|
||||
<Step title="أنشئ الطاقم مع تفعيل الـ Checkpointing">
|
||||
```python
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
|
||||
writer = Agent(role="Writer", goal="Write", backstory="Expert")
|
||||
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
|
||||
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
|
||||
],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
<Step title="شغله وأوقفه بعد المهمة الأولى">
|
||||
```python
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
اضغط `Ctrl+C` بعد انتهاء المهمة الأولى. في `./.checkpoints/`، الملف بصيغة `<timestamp>_<uuid>.json` هو نقطة الحفظ.
|
||||
</Step>
|
||||
<Step title="استأنف من نقطة الحفظ">
|
||||
```python
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
يتم تخطي مهمة البحث، ويعمل الكاتب على مخرجات البحث المحفوظة، وينتهي الطاقم.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## ادلة عملية
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="تفعيل الـ Checkpointing بالإعدادات الافتراضية" icon="play">
|
||||
```python
|
||||
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
|
||||
```
|
||||
|
||||
يكتب إلى `./.checkpoints/` عند كل `task_completed`.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="تخصيص التخزين والتردد" icon="sliders">
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="اختيار مزود التخزين" icon="database">
|
||||
<CodeGroup>
|
||||
```python JsonProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
```python SqliteProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Tip>
|
||||
SQLite يفعل وضع journal WAL للقراءات المتزامنة. يفضل لنقاط الحفظ عالية التردد.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="استبعاد وكيل واحد" icon="user-slash">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...),
|
||||
Agent(role="Writer", ..., checkpoint=False),
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="التفرع إلى فرع جديد" icon="code-branch">
|
||||
`fork()` يستعيد نقطة حفظ تحت نسب جديد بحيث لا يتصادم التشغيل الجديد مع الأصلي.
|
||||
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
|
||||
تسمية `branch` اختيارية؛ يتم إنشاء واحدة إذا أغفلت.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Checkpointing لـ Crew أو Flow أو Agent" icon="cubes">
|
||||
<Tabs>
|
||||
<Tab title="Crew">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
المشغل الافتراضي: `task_completed`.
|
||||
</Tab>
|
||||
<Tab title="Flow">
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Agent">
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="كتابة نقطة حفظ يدويا" icon="code">
|
||||
سجل معالجا على أي حدث واستدع `state.checkpoint()`.
|
||||
|
||||
<CodeGroup>
|
||||
```python Sync
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"تم حفظ نقطة الحفظ: {path}")
|
||||
```
|
||||
```python Async
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"تم حفظ نقطة الحفظ: {path}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
يتم تمرير وسيط `state` تلقائيا عندما يقبل المعالج ثلاثة معاملات. راجع [Event Listeners](/ar/concepts/event-listener) لقائمة الأحداث الكاملة.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="التصفح والاستئناف والتفرع من سطر الأوامر" icon="terminal">
|
||||
```bash
|
||||
crewai checkpoint
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
<Frame caption="شجرة نقاط الحفظ — الفروع والتفرعات تتداخل تحت أبيها.">
|
||||
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
|
||||
</Frame>
|
||||
|
||||
اللوحة اليسرى تجمع نقاط الحفظ حسب الفرع؛ التفرعات تتداخل تحت أبيها. اختيار نقطة حفظ يفتح لوحة التفاصيل مع بياناتها الوصفية وحالة الكيان وتقدم المهام. **Resume** يكمل التشغيل؛ **Fork** يبدأ فرعا جديدا.
|
||||
|
||||
<Frame caption="تبويب النظرة العامة — البيانات الوصفية وحالة الكيان وملخص التشغيل.">
|
||||
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
|
||||
</Frame>
|
||||
|
||||
لوحة التفاصيل تعرض منطقتين قابلتين للتحرير:
|
||||
|
||||
- **Inputs** — مدخلات الـ kickoff الأصلية، معبأة مسبقا وقابلة للتحرير.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
|
||||
</Frame>
|
||||
|
||||
- **مخرجات المهام** — مخرجات المهام المكتملة. تحرير مخرج والضغط على **Fork** يبطل المهام التابعة لتعاد بالسياق المعدل.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
|
||||
</Frame>
|
||||
|
||||
<Frame caption="عرض التفرع — تأكيد فرع جديد من نقطة الحفظ المختارة.">
|
||||
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
مفيد لاستكشاف "ماذا لو": تفرع، عدل، راقب.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="تفقد نقاط الحفظ بدون TUI" icon="magnifying-glass">
|
||||
```bash
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
crewai checkpoint info ./my_checkpoints/<file>.json
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## المرجع
|
||||
|
||||
### `CheckpointConfig`
|
||||
|
||||
<ParamField path="location" type="str" default='"./.checkpoints"'>
|
||||
وجهة التخزين. مجلد لـ `JsonProvider`، مسار ملف قاعدة بيانات لـ `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
|
||||
أنواع الأحداث التي تطلق نقطة حفظ. `CheckpointEventType` هو `Literal` — مدقق الأنواع يكمل تلقائيا ويرفض القيم غير المدعومة. راجع [أنواع الأحداث](#أنواع-الأحداث) للقائمة الكاملة.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
|
||||
واجهة التخزين. `JsonProvider` أو `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="max_checkpoints" type="int | None" default="None">
|
||||
الحد الاقصى لنقاط الحفظ المحتفظ بها. الأقدم تحذف بعد كل كتابة.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="restore_from" type="Path | str | None" default="None">
|
||||
نقطة الحفظ المراد استعادتها عند تمريرها عبر `from_checkpoint`.
|
||||
</ParamField>
|
||||
|
||||
### قيم حقل `checkpoint`
|
||||
|
||||
مقبولة في `Crew` و`Flow` و`Agent`.
|
||||
|
||||
<ParamField path="None" type="افتراضي">
|
||||
يرث من الأب.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="True" type="bool">
|
||||
تفعيل بالإعدادات الافتراضية.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="False" type="bool">
|
||||
انسحاب صريح. يوقف الوراثة.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
|
||||
إعدادات مخصصة.
|
||||
</ParamField>
|
||||
|
||||
### أنواع الأحداث
|
||||
|
||||
يقبل `on_events` أي مجموعة من قيم `CheckpointEventType`. الافتراضي `["task_completed"]` يكتب نقطة حفظ لكل مهمة منتهية، و`["*"]` يطابق جميع الأحداث.
|
||||
|
||||
<Warning>
|
||||
`["*"]` والأحداث عالية التردد مثل `llm_call_completed` تكتب نقاط حفظ كثيرة وقد تضر بالاداء. استخدمها مع `max_checkpoints`.
|
||||
الـ Checkpointing في اصدار مبكر. قد تتغير واجهات البرمجة في الاصدارات المستقبلية.
|
||||
</Warning>
|
||||
|
||||
<Expandable title="جميع الأحداث المدعومة">
|
||||
## نظرة عامة
|
||||
|
||||
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
|
||||
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
|
||||
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
|
||||
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
|
||||
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
|
||||
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
|
||||
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
|
||||
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
|
||||
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
|
||||
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
|
||||
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
|
||||
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
|
||||
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
|
||||
- **Logging** — `agent_logs_started`, `agent_logs_execution`
|
||||
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
|
||||
- **إشارات النظام** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
|
||||
- **حرف بدل** — `"*"` يطابق جميع الأحداث.
|
||||
يقوم الـ Checkpointing بحفظ حالة التنفيذ تلقائيا اثناء التشغيل. اذا فشل طاقم او تدفق او وكيل اثناء التنفيذ، يمكنك الاستعادة من اخر نقطة حفظ والاستئناف دون اعادة تنفيذ العمل المكتمل.
|
||||
|
||||
</Expandable>
|
||||
## البداية السريعة
|
||||
|
||||
### مزودات التخزين
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
<ParamField path="JsonProvider" type="provider">
|
||||
ملف واحد لكل نقطة حفظ بصيغة `<timestamp>_<uuid>.json` داخل `location`.
|
||||
</ParamField>
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # يستخدم الافتراضيات: ./.checkpoints, عند task_completed
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
<ParamField path="SqliteProvider" type="provider">
|
||||
ملف قاعدة بيانات واحد في `location` مع journaling WAL.
|
||||
</ParamField>
|
||||
تتم كتابة ملفات نقاط الحفظ في `./.checkpoints/` بعد اكتمال كل مهمة.
|
||||
|
||||
### سطر الأوامر
|
||||
## التكوين
|
||||
|
||||
| الامر | الغرض |
|
||||
|:------|:------|
|
||||
| `crewai checkpoint` | تشغيل TUI؛ كشف التخزين تلقائيا. |
|
||||
| `crewai checkpoint --location <path>` | تشغيل TUI على موقع محدد. |
|
||||
| `crewai checkpoint list <path>` | سرد نقاط الحفظ. |
|
||||
| `crewai checkpoint info <path>` | تفقد ملف نقطة حفظ أو آخر مدخل في قاعدة بيانات SQLite. |
|
||||
استخدم `CheckpointConfig` للتحكم الكامل:
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### حقول CheckpointConfig
|
||||
|
||||
| الحقل | النوع | الافتراضي | الوصف |
|
||||
|:------|:------|:----------|:------|
|
||||
| `location` | `str` | `"./.checkpoints"` | مسار ملفات نقاط الحفظ |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | انواع الاحداث التي تطلق نقطة حفظ |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | واجهة التخزين |
|
||||
| `max_checkpoints` | `int \| None` | `None` | الحد الاقصى للملفات؛ يتم حذف الاقدم اولا |
|
||||
|
||||
### الوراثة والانسحاب
|
||||
|
||||
يقبل حقل `checkpoint` في Crew و Flow و Agent قيم `CheckpointConfig` او `True` او `False` او `None`:
|
||||
|
||||
| القيمة | السلوك |
|
||||
|:-------|:-------|
|
||||
| `None` (افتراضي) | يرث من الاصل. الوكيل يرث اعدادات الطاقم. |
|
||||
| `True` | تفعيل بالاعدادات الافتراضية. |
|
||||
| `False` | انسحاب صريح. يوقف الوراثة من الاصل. |
|
||||
| `CheckpointConfig(...)` | اعدادات مخصصة. |
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # يرث checkpoint من الطاقم
|
||||
Agent(role="Writer", ..., checkpoint=False), # منسحب، بدون نقاط حفظ
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
|
||||
## الاستئناف من نقطة حفظ
|
||||
|
||||
```python
|
||||
# استعادة واستئناف
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # يستأنف من اخر مهمة مكتملة
|
||||
```
|
||||
|
||||
يتخطى الطاقم المستعاد المهام المكتملة ويستأنف من اول مهمة غير مكتملة.
|
||||
|
||||
## يعمل على Crew و Flow و Agent
|
||||
|
||||
### Crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
المشغل الافتراضي: `task_completed` (نقطة حفظ واحدة لكل مهمة مكتملة).
|
||||
|
||||
### Flow
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
|
||||
# استئناف
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
|
||||
## مزودات التخزين
|
||||
|
||||
يتضمن CrewAI مزودي تخزين لنقاط الحفظ.
|
||||
|
||||
### JsonProvider (افتراضي)
|
||||
|
||||
يكتب كل نقطة حفظ كملف JSON منفصل.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### SqliteProvider
|
||||
|
||||
يخزن جميع نقاط الحفظ في ملف قاعدة بيانات SQLite واحد.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
## انواع الاحداث
|
||||
|
||||
يقبل حقل `on_events` اي مجموعة من سلاسل انواع الاحداث. الخيارات الشائعة:
|
||||
|
||||
| حالة الاستخدام | الاحداث |
|
||||
|:---------------|:--------|
|
||||
| بعد كل مهمة (Crew) | `["task_completed"]` |
|
||||
| بعد كل طريقة في التدفق | `["method_execution_finished"]` |
|
||||
| بعد تنفيذ الوكيل | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| عند اكتمال الطاقم فقط | `["crew_kickoff_completed"]` |
|
||||
| بعد كل استدعاء LLM | `["llm_call_completed"]` |
|
||||
| على كل شيء | `["*"]` |
|
||||
|
||||
<Warning>
|
||||
استخدام `["*"]` او احداث عالية التردد مثل `llm_call_completed` سيكتب العديد من ملفات نقاط الحفظ وقد يؤثر على الاداء. استخدم `max_checkpoints` للحد من استخدام المساحة.
|
||||
</Warning>
|
||||
|
||||
## نقاط الحفظ اليدوية
|
||||
|
||||
للتحكم الكامل، سجل معالج الاحداث الخاص بك واستدع `state.checkpoint()` مباشرة:
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
# معالج متزامن
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"تم حفظ نقطة الحفظ: {path}")
|
||||
|
||||
# معالج غير متزامن
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source, event, state):
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"تم حفظ نقطة الحفظ: {path}")
|
||||
```
|
||||
|
||||
وسيط `state` هو `RuntimeState` الذي يتم تمريره تلقائيا بواسطة ناقل الاحداث عندما يقبل المعالج 3 معاملات. يمكنك تسجيل معالجات على اي نوع حدث مدرج في وثائق [Event Listeners](/ar/concepts/event-listener).
|
||||
|
||||
الـ Checkpointing يعمل بافضل جهد: اذا فشلت كتابة نقطة حفظ، يتم تسجيل الخطأ ولكن التنفيذ يستمر دون انقطاع.
|
||||
|
||||
@@ -16,6 +16,7 @@ mode: "wide"
|
||||
|
||||
- **تسلسلي**: ينفذ المهام بالتتابع، مما يضمن إكمال المهام بتقدم منظم.
|
||||
- **هرمي**: ينظم المهام في تسلسل إداري هرمي، حيث يتم تفويض المهام وتنفيذها بناءً على سلسلة أوامر منظمة. يجب تحديد نموذج لغة المدير (`manager_llm`) أو وكيل مدير مخصص (`manager_agent`) في الطاقم لتفعيل العملية الهرمية، مما يسهّل إنشاء وإدارة المهام من قبل المدير.
|
||||
- **العملية التوافقية (مخطط لها)**: تهدف إلى اتخاذ القرارات بشكل تعاوني بين الوكلاء حول تنفيذ المهام، وتقدم هذه العملية نهجًا ديمقراطيًا لإدارة المهام داخل CrewAI. وهي مخطط لها للتطوير المستقبلي وغير مطبقة حاليًا في قاعدة الكود.
|
||||
|
||||
## دور العمليات في العمل الجماعي
|
||||
تُمكّن العمليات الوكلاء الأفراد من العمل كوحدة متماسكة، مما يبسّط جهودهم لتحقيق أهداف مشتركة بكفاءة وتناسق.
|
||||
@@ -58,9 +59,9 @@ crew = Crew(
|
||||
|
||||
## فئة Process: نظرة عامة مفصلة
|
||||
|
||||
تم تنفيذ فئة `Process` كتعداد (`Enum`)، مما يضمن أمان الأنواع ويقيّد قيم العملية على الأنواع المحددة (`sequential`، `hierarchical`).
|
||||
تم تنفيذ فئة `Process` كتعداد (`Enum`)، مما يضمن أمان الأنواع ويقيّد قيم العملية على الأنواع المحددة (`sequential`، `hierarchical`). العملية التوافقية مخطط لإدراجها مستقبلاً، مما يؤكد التزامنا بالتطوير والابتكار المستمر.
|
||||
|
||||
## الخلاصة
|
||||
|
||||
التعاون المنظم الذي تسهّله العمليات داخل CrewAI ضروري لتمكين العمل الجماعي المنهجي بين الوكلاء.
|
||||
تم تحديث هذه الوثائق لتعكس أحدث الميزات والتحسينات، مما يضمن وصول المستخدمين إلى أحدث المعلومات وأكثرها شمولاً.
|
||||
تم تحديث هذه الوثائق لتعكس أحدث الميزات والتحسينات والتكامل المخطط للعملية التوافقية، مما يضمن وصول المستخدمين إلى أحدث المعلومات وأكثرها شمولاً.
|
||||
|
||||
@@ -4,39 +4,6 @@ description: "Product updates, improvements, and bug fixes for CrewAI"
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="May 27, 2026">
|
||||
## v1.14.6a2
|
||||
|
||||
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Enhance `StdioTransport` to prevent environment variable leakage
|
||||
- Enhance planning configuration and observation handling
|
||||
- Declare `env_vars` on `DatabricksQueryTool`
|
||||
- Add Agent Control Plane documentation
|
||||
|
||||
### Bug Fixes
|
||||
- Fix structured output leaks in tool-calling loops
|
||||
- Drop unroundtrippable callbacks and adapter state in checkpointing
|
||||
- Serialize `type[BaseModel]` fields as JSON schema in checkpointing
|
||||
- Avoid orphan `task_started` on resume scope restore
|
||||
- Allow `AgentExecutor` to restore from checkpoint
|
||||
- Correct MongoDB typo to `pymongo` in package dependencies
|
||||
|
||||
### Documentation
|
||||
- Restructure checkpointing page
|
||||
- Document one-time admin package install step
|
||||
- Migrate Secrets Manager / Workload Identity from replicated-config
|
||||
- Remove Skills Repository entry from changelog
|
||||
|
||||
## Contributors
|
||||
|
||||
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="May 21, 2026">
|
||||
## v1.14.6a1
|
||||
|
||||
@@ -45,6 +12,7 @@ mode: "wide"
|
||||
## What's Changed
|
||||
|
||||
### Features
|
||||
- Add Skills Repository with registry, cache, CLI, and SDK integration
|
||||
- Generate categorized release notes for enterprise
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -5,419 +5,301 @@ icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
Checkpointing saves a snapshot of execution state during a run so a crew, flow, or agent can resume after a failure or be forked into an alternate branch.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Explanation" icon="lightbulb" href="#explanation">
|
||||
How checkpointing works: events, storage, and inheritance.
|
||||
</Card>
|
||||
<Card title="Tutorial" icon="graduation-cap" href="#tutorial-resume-a-failing-crew">
|
||||
A 5-minute walkthrough: run, interrupt, resume.
|
||||
</Card>
|
||||
<Card title="How-to guides" icon="screwdriver-wrench" href="#how-to-guides">
|
||||
Task-focused recipes for common workflows.
|
||||
</Card>
|
||||
<Card title="Reference" icon="book" href="#reference">
|
||||
`CheckpointConfig`, events, providers, and CLI.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Explanation
|
||||
|
||||
### What a checkpoint is
|
||||
|
||||
A checkpoint captures everything CrewAI needs to recreate a run mid-flight: the full state of the crew, flow, or agent — configuration, agent memory and knowledge sources, task progress, intermediate outputs, internal state and attributes — alongside the kickoff inputs, the event history up to that point, and a lineage ID that ties the checkpoint to the run it came from.
|
||||
|
||||
Restoring rebuilds that state and continues. Completed tasks are skipped, memory and knowledge are rehydrated, and downstream work runs against the same outputs the original run produced. Forking does the same restore under a new lineage, so the new branch and the original run can write checkpoints side by side without overwriting each other.
|
||||
|
||||
### When checkpoints are written
|
||||
|
||||
Checkpointing is event-driven. The runtime subscribes to events you select via `on_events` and writes a checkpoint each time one fires. The default `task_completed` produces one checkpoint per finished task — a sensible tradeoff between granularity and disk use. Higher-frequency events like `llm_call_completed` are available for fine-grained recovery but write far more files.
|
||||
|
||||
### Storage
|
||||
|
||||
Two providers ship with CrewAI:
|
||||
|
||||
- `JsonProvider` writes one file per checkpoint. Human-readable and easy to inspect.
|
||||
- `SqliteProvider` writes to a single SQLite database. Better for high-frequency checkpointing.
|
||||
|
||||
Both prune oldest checkpoints when `max_checkpoints` is set.
|
||||
|
||||
<Note>
|
||||
Auto-checkpoint writes (event-driven) are best-effort: a failed write is logged and the run continues. Manual `state.checkpoint()` and `state.acheckpoint()` calls re-raise on failure.
|
||||
</Note>
|
||||
|
||||
### Inheritance model
|
||||
|
||||
`Crew`, `Flow`, and `Agent` all accept a `checkpoint` argument. Children inherit from their parent unless they set their own value or pass `False` to opt out. Enable checkpointing once on the crew and every agent participates, or selectively exclude one agent.
|
||||
|
||||
## Tutorial: Resume a failing crew
|
||||
|
||||
This walkthrough takes ~5 minutes. You will run a two-task crew, kill it midway, and resume from the saved checkpoint.
|
||||
|
||||
<Steps>
|
||||
<Step title="Create the crew with checkpointing enabled">
|
||||
```python
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
|
||||
writer = Agent(role="Writer", goal="Write", backstory="Expert")
|
||||
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
|
||||
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
|
||||
],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
<Step title="Run it and interrupt after the first task">
|
||||
```python
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
Press `Ctrl+C` after the first task finishes. Look in `./.checkpoints/` — a file named `<timestamp>_<uuid>.json` is the checkpoint.
|
||||
</Step>
|
||||
<Step title="Resume from the checkpoint">
|
||||
```python
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
The research task is skipped, the writer runs against the saved research output, and the crew finishes.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## How-to guides
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Enable checkpointing with defaults" icon="play">
|
||||
```python
|
||||
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
|
||||
```
|
||||
|
||||
Writes to `./.checkpoints/` on every `task_completed`.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Customize storage and frequency" icon="sliders">
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Choose a storage provider" icon="database">
|
||||
<CodeGroup>
|
||||
```python JsonProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
```python SqliteProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Tip>
|
||||
SQLite enables WAL journal mode for concurrent reads. Prefer it for high-frequency checkpointing.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Opt one agent out" icon="user-slash">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...),
|
||||
Agent(role="Writer", ..., checkpoint=False),
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Fork into a new branch" icon="code-branch">
|
||||
`fork()` restores a checkpoint under a fresh lineage so the new run does not collide with the original.
|
||||
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
|
||||
The `branch` label is optional; one is generated if omitted.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Checkpoint a Crew, Flow, or Agent" icon="cubes">
|
||||
<Tabs>
|
||||
<Tab title="Crew">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
Default trigger: `task_completed`.
|
||||
</Tab>
|
||||
<Tab title="Flow">
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Agent">
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Write a checkpoint manually" icon="code">
|
||||
Register a handler on any event and call `state.checkpoint()`.
|
||||
|
||||
<CodeGroup>
|
||||
```python Sync
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
```
|
||||
```python Async
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
A `state` argument is supplied automatically when the handler takes three parameters. See [Event Listeners](/en/concepts/event-listener) for the full event catalog.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Browse, resume, and fork from the CLI" icon="terminal">
|
||||
```bash
|
||||
crewai checkpoint
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
<Frame caption="Checkpoint tree — branches and forks nest under their parent.">
|
||||
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
|
||||
</Frame>
|
||||
|
||||
The left panel groups checkpoints by branch; forks nest under their parent. Selecting a checkpoint opens the detail panel with metadata, entity state, and task progress. **Resume** continues the run; **Fork** starts a new branch.
|
||||
|
||||
<Frame caption="Overview tab — metadata, entity state, and run summary.">
|
||||
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
|
||||
</Frame>
|
||||
|
||||
The detail panel exposes two editable areas:
|
||||
|
||||
- **Inputs** — original kickoff inputs, pre-filled and editable.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
|
||||
</Frame>
|
||||
|
||||
- **Task outputs** — outputs of completed tasks. Editing an output and hitting **Fork** invalidates downstream tasks so they re-run against the modified context.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
|
||||
</Frame>
|
||||
|
||||
<Frame caption="Fork view — confirm a new branch from the selected checkpoint.">
|
||||
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
Useful for "what if" exploration: fork, tweak, observe.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Inspect checkpoints without the TUI" icon="magnifying-glass">
|
||||
```bash
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
crewai checkpoint info ./my_checkpoints/<file>.json
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Reference
|
||||
|
||||
### `CheckpointConfig`
|
||||
|
||||
<ParamField path="location" type="str" default='"./.checkpoints"'>
|
||||
Storage destination. A directory for `JsonProvider`, a database file path for `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
|
||||
Event types that trigger a checkpoint. `CheckpointEventType` is a `Literal` — your type checker will autocomplete and reject unsupported values. See [event types](#event-types) for the full list.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
|
||||
Storage backend. Either `JsonProvider` or `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="max_checkpoints" type="int | None" default="None">
|
||||
Maximum checkpoints to retain. Oldest are pruned after each write.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="restore_from" type="Path | str | None" default="None">
|
||||
Checkpoint to restore from when passed via `from_checkpoint`.
|
||||
</ParamField>
|
||||
|
||||
### `checkpoint` field values
|
||||
|
||||
Accepted by `Crew`, `Flow`, and `Agent`.
|
||||
|
||||
<ParamField path="None" type="default">
|
||||
Inherit from parent.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="True" type="bool">
|
||||
Enable with defaults.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="False" type="bool">
|
||||
Explicit opt-out. Stops inheritance.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
|
||||
Custom configuration.
|
||||
</ParamField>
|
||||
|
||||
### Event types
|
||||
|
||||
`on_events` accepts any combination of `CheckpointEventType` values. The default `["task_completed"]` writes one checkpoint per finished task; `["*"]` matches every event.
|
||||
|
||||
<Warning>
|
||||
`["*"]` and high-frequency events like `llm_call_completed` write many checkpoints and can degrade performance. Pair them with `max_checkpoints`.
|
||||
Checkpointing is in early release. APIs may change in future versions.
|
||||
</Warning>
|
||||
|
||||
<Expandable title="All supported events">
|
||||
## Overview
|
||||
|
||||
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
|
||||
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
|
||||
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
|
||||
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
|
||||
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
|
||||
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
|
||||
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
|
||||
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
|
||||
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
|
||||
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
|
||||
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
|
||||
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
|
||||
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
|
||||
- **Logging** — `agent_logs_started`, `agent_logs_execution`
|
||||
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
|
||||
- **System signals** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
|
||||
- **Wildcard** — `"*"` matches every event.
|
||||
Checkpointing automatically saves execution state during a run. If a crew, flow, or agent fails mid-execution, you can restore from the last checkpoint and resume without re-running completed work.
|
||||
|
||||
</Expandable>
|
||||
## Quick Start
|
||||
|
||||
### Storage providers
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
<ParamField path="JsonProvider" type="provider">
|
||||
One file per checkpoint, named `<timestamp>_<uuid>.json` inside `location`.
|
||||
</ParamField>
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # uses defaults: ./.checkpoints, on task_completed
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
<ParamField path="SqliteProvider" type="provider">
|
||||
Single database file at `location` with WAL journaling.
|
||||
</ParamField>
|
||||
Checkpoint files are written to `./.checkpoints/` after each completed task.
|
||||
|
||||
### CLI
|
||||
## Configuration
|
||||
|
||||
| Command | Purpose |
|
||||
|:--------|:--------|
|
||||
| `crewai checkpoint` | Launch the TUI; auto-detect storage. |
|
||||
| `crewai checkpoint --location <path>` | Launch the TUI against a specific location. |
|
||||
| `crewai checkpoint list <path>` | List checkpoints. |
|
||||
| `crewai checkpoint info <path>` | Inspect a checkpoint file or the latest entry in a SQLite database. |
|
||||
Use `CheckpointConfig` for full control:
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### CheckpointConfig Fields
|
||||
|
||||
| Field | Type | Default | Description |
|
||||
|:------|:-----|:--------|:------------|
|
||||
| `location` | `str` | `"./.checkpoints"` | Storage destination — a directory for `JsonProvider`, a database file path for `SqliteProvider` |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | Event types that trigger a checkpoint |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | Storage backend |
|
||||
| `max_checkpoints` | `int \| None` | `None` | Max checkpoints to keep. Oldest are pruned after each write. Pruning is handled by the provider. |
|
||||
| `restore_from` | `Path \| str \| None` | `None` | Path to a checkpoint to restore from. Used when passing config via a kickoff method's `from_checkpoint` parameter. |
|
||||
|
||||
### Inheritance and Opt-Out
|
||||
|
||||
The `checkpoint` field on Crew, Flow, and Agent accepts `CheckpointConfig`, `True`, `False`, or `None`:
|
||||
|
||||
| Value | Behavior |
|
||||
|:------|:---------|
|
||||
| `None` (default) | Inherit from parent. An agent inherits its crew's config. |
|
||||
| `True` | Enable with defaults. |
|
||||
| `False` | Explicit opt-out. Stops inheritance from parent. |
|
||||
| `CheckpointConfig(...)` | Custom configuration. |
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # inherits crew's checkpoint
|
||||
Agent(role="Writer", ..., checkpoint=False), # opted out, no checkpoints
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
|
||||
## Resuming from a Checkpoint
|
||||
|
||||
Pass a `CheckpointConfig` with `restore_from` to any kickoff method. The crew restores from that checkpoint, skips completed tasks, and resumes.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(agents=[...], tasks=[...])
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./my_checkpoints/20260407T120000_abc123.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
Remaining `CheckpointConfig` fields apply to the new run, so checkpointing continues after the restore.
|
||||
|
||||
You can also use the classmethod directly:
|
||||
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/20260407T120000_abc123.json")
|
||||
crew = Crew.from_checkpoint(config)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
## Forking from a Checkpoint
|
||||
|
||||
`fork()` restores a checkpoint and starts a new execution branch. Useful for exploring alternative paths from the same point.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/20260407T120000_abc123.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
|
||||
Each fork gets a unique lineage ID so checkpoints from different branches don't collide. The `branch` label is optional and auto-generated if omitted.
|
||||
|
||||
## Works on Crew, Flow, and Agent
|
||||
|
||||
### Crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
Default trigger: `task_completed` (one checkpoint per finished task).
|
||||
|
||||
### Flow
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
|
||||
# Resume
|
||||
config = CheckpointConfig(restore_from="./flow_cp/20260407T120000_abc123.json")
|
||||
flow = MyFlow.from_checkpoint(config)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
|
||||
## Storage Providers
|
||||
|
||||
CrewAI ships with two checkpoint storage providers.
|
||||
|
||||
### JsonProvider (default)
|
||||
|
||||
Writes each checkpoint as a separate JSON file. Simple, human-readable, easy to inspect.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(), # this is the default
|
||||
max_checkpoints=5, # prunes oldest files
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
Files are named `<timestamp>_<uuid>.json` inside the location directory.
|
||||
|
||||
### SqliteProvider
|
||||
|
||||
Stores all checkpoints in a single SQLite database file. Better for high-frequency checkpointing and avoids many small files.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
WAL journal mode is enabled for concurrent read access.
|
||||
|
||||
## Event Types
|
||||
|
||||
The `on_events` field accepts any combination of event type strings. Common choices:
|
||||
|
||||
| Use Case | Events |
|
||||
|:---------|:-------|
|
||||
| After each task (Crew) | `["task_completed"]` |
|
||||
| After each flow method | `["method_execution_finished"]` |
|
||||
| After agent execution | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| On crew completion only | `["crew_kickoff_completed"]` |
|
||||
| After every LLM call | `["llm_call_completed"]` |
|
||||
| On everything | `["*"]` |
|
||||
|
||||
<Warning>
|
||||
Using `["*"]` or high-frequency events like `llm_call_completed` will write many checkpoint files and may impact performance. Use `max_checkpoints` to limit disk usage.
|
||||
</Warning>
|
||||
|
||||
## Manual Checkpointing
|
||||
|
||||
For full control, register your own event handler and call `state.checkpoint()` directly:
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
# Sync handler
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
|
||||
# Async handler
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source, event, state):
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"Saved checkpoint: {path}")
|
||||
```
|
||||
|
||||
The `state` argument is the `RuntimeState` passed automatically by the event bus when your handler accepts 3 parameters. You can register handlers on any event type listed in the [Event Listeners](/en/concepts/event-listener) documentation.
|
||||
|
||||
Checkpointing is best-effort: if a checkpoint write fails, the error is logged but execution continues uninterrupted.
|
||||
|
||||
## CLI
|
||||
|
||||
The `crewai checkpoint` command gives you a TUI for browsing, inspecting, resuming, and forking checkpoints. It auto-detects whether your checkpoints are JSON files or a SQLite database.
|
||||
|
||||
```bash
|
||||
# Launch the TUI — auto-detects .checkpoints/ or .checkpoints.db
|
||||
crewai checkpoint
|
||||
|
||||
# Point at a specific location
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpointing.png" alt="Checkpoint TUI" />
|
||||
</Frame>
|
||||
|
||||
The left panel is a tree view. Checkpoints are grouped by branch, and forks nest under the checkpoint they diverged from. Select a checkpoint to see its metadata, entity state, and task progress in the detail panel. Hit **Resume** to pick up where it left off, or **Fork** to start a new branch from that point.
|
||||
|
||||
### Editing inputs and task outputs
|
||||
|
||||
When a checkpoint is selected, the detail panel shows:
|
||||
|
||||
- **Inputs** — if the original kickoff had inputs (e.g. `{topic}`), they appear as editable fields pre-filled with the original values. Change them before resuming or forking.
|
||||
- **Task outputs** — completed tasks show their output in editable text areas. Edit a task's output to change the context that downstream tasks receive. When you modify a task output and hit Fork, all subsequent tasks are invalidated and re-run with the new context.
|
||||
|
||||
This is useful for "what if" exploration — fork from a checkpoint, tweak a task's result, and see how it changes downstream behavior.
|
||||
|
||||
### Subcommands
|
||||
|
||||
```bash
|
||||
# List all checkpoints
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
|
||||
# Inspect a specific checkpoint
|
||||
crewai checkpoint info ./my_checkpoints/20260407T120000_abc123.json
|
||||
|
||||
# Inspect latest in a SQLite database
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
|
||||
@@ -16,6 +16,7 @@ mode: "wide"
|
||||
|
||||
- **Sequential**: Executes tasks sequentially, ensuring tasks are completed in an orderly progression.
|
||||
- **Hierarchical**: Organizes tasks in a managerial hierarchy, where tasks are delegated and executed based on a structured chain of command. A manager language model (`manager_llm`) or a custom manager agent (`manager_agent`) must be specified in the crew to enable the hierarchical process, facilitating the creation and management of tasks by the manager.
|
||||
- **Consensual Process (Planned)**: Aiming for collaborative decision-making among agents on task execution, this process type introduces a democratic approach to task management within CrewAI. It is planned for future development and is not currently implemented in the codebase.
|
||||
|
||||
## The Role of Processes in Teamwork
|
||||
Processes enable individual agents to operate as a cohesive unit, streamlining their efforts to achieve common objectives with efficiency and coherence.
|
||||
@@ -58,9 +59,9 @@ Emulates a corporate hierarchy, CrewAI allows specifying a custom manager agent
|
||||
|
||||
## Process Class: Detailed Overview
|
||||
|
||||
The `Process` class is implemented as an enumeration (`Enum`), ensuring type safety and restricting process values to the defined types (`sequential`, `hierarchical`).
|
||||
The `Process` class is implemented as an enumeration (`Enum`), ensuring type safety and restricting process values to the defined types (`sequential`, `hierarchical`). The consensual process is planned for future inclusion, emphasizing our commitment to continuous development and innovation.
|
||||
|
||||
## Conclusion
|
||||
|
||||
The structured collaboration facilitated by processes within CrewAI is crucial for enabling systematic teamwork among agents.
|
||||
This documentation has been updated to reflect the latest features and enhancements, ensuring users have access to the most current and comprehensive information.
|
||||
This documentation has been updated to reflect the latest features, enhancements, and the planned integration of the Consensual Process, ensuring users have access to the most current and comprehensive information.
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 169 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 200 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 189 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 235 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 156 KiB |
@@ -4,39 +4,6 @@ description: "CrewAI의 제품 업데이트, 개선 사항 및 버그 수정"
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="2026년 5월 27일">
|
||||
## v1.14.6a2
|
||||
|
||||
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
|
||||
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 환경 변수 유출을 방지하기 위해 `StdioTransport` 개선
|
||||
- 계획 구성 및 관찰 처리 개선
|
||||
- `DatabricksQueryTool`에서 `env_vars` 선언
|
||||
- 에이전트 제어 평면 문서 추가
|
||||
|
||||
### 버그 수정
|
||||
- 도구 호출 루프에서 구조화된 출력 유출 수정
|
||||
- 체크포인팅에서 원형으로 돌아갈 수 없는 콜백 및 어댑터 상태 제거
|
||||
- 체크포인팅에서 `type[BaseModel]` 필드를 JSON 스키마로 직렬화
|
||||
- 복원 범위 복원 시 고아 `task_started` 방지
|
||||
- `AgentExecutor`가 체크포인트에서 복원할 수 있도록 허용
|
||||
- 패키지 종속성에서 MongoDB 오타를 `pymongo`로 수정
|
||||
|
||||
### 문서
|
||||
- 체크포인팅 페이지 구조 재편성
|
||||
- 일회성 관리자 패키지 설치 단계 문서화
|
||||
- 복제된 구성에서 비밀 관리자 / 작업 부하 ID 마이그레이션
|
||||
- 변경 로그에서 기술 리포지토리 항목 제거
|
||||
|
||||
## 기여자
|
||||
|
||||
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026년 5월 21일">
|
||||
## v1.14.6a1
|
||||
|
||||
@@ -45,6 +12,7 @@ mode: "wide"
|
||||
## 변경 사항
|
||||
|
||||
### 기능
|
||||
- 레지스트리, 캐시, CLI 및 SDK 통합이 포함된 기술 저장소 추가
|
||||
- 기업용으로 분류된 릴리스 노트 생성
|
||||
|
||||
### 버그 수정
|
||||
|
||||
@@ -5,419 +5,225 @@ icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
체크포인팅은 실행 중 실행 상태의 스냅샷을 저장하여 크루, 플로우, 에이전트가 실패 후 재개하거나 대체 브랜치로 분기될 수 있도록 합니다.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="설명" icon="lightbulb" href="#설명">
|
||||
체크포인팅의 작동 방식: 이벤트, 스토리지, 상속.
|
||||
</Card>
|
||||
<Card title="튜토리얼" icon="graduation-cap" href="#튜토리얼-실패한-크루-재개하기">
|
||||
5분 가이드: 실행, 중단, 재개.
|
||||
</Card>
|
||||
<Card title="사용 방법" icon="screwdriver-wrench" href="#사용-방법">
|
||||
일반적인 워크플로우를 위한 작업 중심 레시피.
|
||||
</Card>
|
||||
<Card title="레퍼런스" icon="book" href="#레퍼런스">
|
||||
`CheckpointConfig`, 이벤트, 프로바이더, CLI.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## 설명
|
||||
|
||||
### 체크포인트란
|
||||
|
||||
체크포인트는 실행 중인 작업을 재현하기 위해 CrewAI가 필요한 모든 것을 캡처합니다: 크루, 플로우 또는 에이전트의 전체 상태 — 구성, 에이전트의 메모리 및 지식 소스, 태스크 진행 상황, 중간 출력값, 내부 상태 및 속성 — 그리고 kickoff 입력, 해당 시점까지의 이벤트 기록, 그리고 체크포인트를 원본 실행에 연결하는 lineage ID를 포함합니다.
|
||||
|
||||
복원하면 해당 상태를 재구성하고 계속 진행합니다. 완료된 태스크는 건너뛰고, 메모리와 지식은 재수화되며, 다운스트림 작업은 원본 실행이 생성한 동일한 출력을 기반으로 실행됩니다. 포크하면 새 lineage 아래에서 동일한 복원을 수행하여 새 브랜치와 원본 실행이 서로 덮어쓰지 않고 나란히 체크포인트를 기록할 수 있습니다.
|
||||
|
||||
### 체크포인트가 기록되는 시점
|
||||
|
||||
체크포인팅은 이벤트 기반입니다. 런타임은 `on_events`로 선택한 이벤트를 구독하고, 이벤트가 발생할 때마다 체크포인트를 기록합니다. 기본값 `task_completed`는 완료된 태스크당 하나의 체크포인트를 생성합니다 — 세분화와 디스크 사용의 합리적인 균형입니다. `llm_call_completed`와 같은 고빈도 이벤트는 더 세밀한 복구를 위해 사용 가능하지만 훨씬 많은 파일을 기록합니다.
|
||||
|
||||
### 스토리지
|
||||
|
||||
CrewAI에는 두 가지 프로바이더가 포함되어 있습니다:
|
||||
|
||||
- `JsonProvider`는 체크포인트당 하나의 파일을 기록합니다. 사람이 읽기 쉽고 검사하기 편리합니다.
|
||||
- `SqliteProvider`는 단일 SQLite 데이터베이스에 기록합니다. 고빈도 체크포인팅에 적합합니다.
|
||||
|
||||
`max_checkpoints`가 설정되면 두 프로바이더 모두 가장 오래된 체크포인트를 자동으로 제거합니다.
|
||||
|
||||
<Note>
|
||||
체크포인트 기록은 best-effort 방식입니다. 실패한 체크포인트는 로그에 기록되지만 실행을 중단시키지 않습니다.
|
||||
</Note>
|
||||
|
||||
### 상속 모델
|
||||
|
||||
`Crew`, `Flow`, `Agent` 모두 `checkpoint` 인수를 받습니다. 자식은 자체 값을 설정하거나 `False`를 전달하여 옵트아웃하지 않는 한 부모로부터 상속합니다. 크루에서 체크포인팅을 한 번 활성화하면 모든 에이전트가 참여하거나, 특정 에이전트만 선택적으로 제외할 수 있습니다.
|
||||
|
||||
## 튜토리얼: 실패한 크루 재개하기
|
||||
|
||||
이 가이드는 약 5분이 소요됩니다. 두 개의 태스크가 있는 크루를 실행하고 중간에 종료한 다음, 저장된 체크포인트에서 재개합니다.
|
||||
|
||||
<Steps>
|
||||
<Step title="체크포인팅이 활성화된 크루를 생성합니다">
|
||||
```python
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
|
||||
writer = Agent(role="Writer", goal="Write", backstory="Expert")
|
||||
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
|
||||
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
|
||||
],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
<Step title="실행하고 첫 번째 태스크 후에 중단합니다">
|
||||
```python
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
첫 번째 태스크가 완료된 후 `Ctrl+C`를 누릅니다. `./.checkpoints/` 디렉토리에서 `<timestamp>_<uuid>.json` 형식의 파일이 체크포인트입니다.
|
||||
</Step>
|
||||
<Step title="체크포인트에서 재개합니다">
|
||||
```python
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
연구 태스크는 건너뛰고, 작성자는 저장된 연구 출력에 대해 실행되며, 크루가 완료됩니다.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## 사용 방법
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="기본값으로 체크포인팅 활성화" icon="play">
|
||||
```python
|
||||
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
|
||||
```
|
||||
|
||||
`task_completed` 이벤트마다 `./.checkpoints/`에 기록합니다.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="스토리지와 빈도 사용자 정의" icon="sliders">
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="스토리지 프로바이더 선택" icon="database">
|
||||
<CodeGroup>
|
||||
```python JsonProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
```python SqliteProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Tip>
|
||||
SQLite는 동시 읽기를 위해 WAL 저널 모드를 활성화합니다. 고빈도 체크포인팅에는 SQLite를 선호하세요.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="특정 에이전트 옵트아웃" icon="user-slash">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...),
|
||||
Agent(role="Writer", ..., checkpoint=False),
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="새 브랜치로 포크" icon="code-branch">
|
||||
`fork()`는 새 lineage 아래에 체크포인트를 복원하여 새 실행이 원본과 충돌하지 않도록 합니다.
|
||||
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
|
||||
`branch` 레이블은 선택 사항이며, 생략하면 자동 생성됩니다.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Crew, Flow, Agent 체크포인트" icon="cubes">
|
||||
<Tabs>
|
||||
<Tab title="Crew">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
기본 트리거: `task_completed`.
|
||||
</Tab>
|
||||
<Tab title="Flow">
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Agent">
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="수동으로 체크포인트 기록" icon="code">
|
||||
모든 이벤트에 핸들러를 등록하고 `state.checkpoint()`를 호출합니다.
|
||||
|
||||
<CodeGroup>
|
||||
```python Sync
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"체크포인트 저장: {path}")
|
||||
```
|
||||
```python Async
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"체크포인트 저장: {path}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
핸들러가 세 개의 매개변수를 받을 때 `state` 인수가 자동으로 제공됩니다. 전체 이벤트 카탈로그는 [Event Listeners](/ko/concepts/event-listener) 문서를 참조하세요.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="CLI에서 탐색, 재개, 포크" icon="terminal">
|
||||
```bash
|
||||
crewai checkpoint
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
<Frame caption="체크포인트 트리 — 브랜치와 포크가 부모 아래에 중첩됩니다.">
|
||||
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
|
||||
</Frame>
|
||||
|
||||
왼쪽 패널은 체크포인트를 브랜치별로 그룹화하며, 포크는 부모 아래에 중첩됩니다. 체크포인트를 선택하면 메타데이터, 엔티티 상태, 태스크 진행 상황이 있는 세부 정보 패널이 열립니다. **Resume**은 실행을 계속하고, **Fork**는 새 브랜치를 시작합니다.
|
||||
|
||||
<Frame caption="개요 탭 — 메타데이터, 엔티티 상태, 실행 요약.">
|
||||
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
|
||||
</Frame>
|
||||
|
||||
세부 정보 패널에는 두 개의 편집 가능한 영역이 있습니다:
|
||||
|
||||
- **Inputs** — 원래 kickoff의 입력으로, 미리 채워져 있으며 편집 가능합니다.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
|
||||
</Frame>
|
||||
|
||||
- **태스크 출력** — 완료된 태스크의 출력. 출력을 편집하고 **Fork**를 누르면 다운스트림 태스크가 무효화되어 수정된 컨텍스트로 다시 실행됩니다.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
|
||||
</Frame>
|
||||
|
||||
<Frame caption="포크 화면 — 선택한 체크포인트에서 새 브랜치를 확인합니다.">
|
||||
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
"what if" 탐색에 유용합니다: 포크, 조정, 관찰.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="TUI 없이 체크포인트 검사" icon="magnifying-glass">
|
||||
```bash
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
crewai checkpoint info ./my_checkpoints/<file>.json
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 레퍼런스
|
||||
|
||||
### `CheckpointConfig`
|
||||
|
||||
<ParamField path="location" type="str" default='"./.checkpoints"'>
|
||||
스토리지 대상. `JsonProvider`는 디렉토리, `SqliteProvider`는 데이터베이스 파일 경로.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
|
||||
체크포인트를 트리거하는 이벤트 타입. `CheckpointEventType`은 `Literal`이므로 타입 체커가 자동 완성하고 지원되지 않는 값을 거부합니다. 전체 목록은 [이벤트 타입](#이벤트-타입) 참조.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
|
||||
스토리지 백엔드. `JsonProvider` 또는 `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="max_checkpoints" type="int | None" default="None">
|
||||
보관할 최대 체크포인트 수. 각 기록 후 가장 오래된 것이 제거됩니다.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="restore_from" type="Path | str | None" default="None">
|
||||
`from_checkpoint`를 통해 전달될 때 복원할 체크포인트.
|
||||
</ParamField>
|
||||
|
||||
### `checkpoint` 필드 값
|
||||
|
||||
`Crew`, `Flow`, `Agent`에서 사용 가능.
|
||||
|
||||
<ParamField path="None" type="기본값">
|
||||
부모에서 상속.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="True" type="bool">
|
||||
기본값으로 활성화.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="False" type="bool">
|
||||
명시적 옵트아웃. 상속을 중단합니다.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
|
||||
사용자 정의 설정.
|
||||
</ParamField>
|
||||
|
||||
### 이벤트 타입
|
||||
|
||||
`on_events`는 `CheckpointEventType` 값의 임의 조합을 받습니다. 기본값 `["task_completed"]`는 완료된 태스크당 하나의 체크포인트를 기록하며, `["*"]`는 모든 이벤트와 일치합니다.
|
||||
|
||||
<Warning>
|
||||
`["*"]` 및 `llm_call_completed`와 같은 고빈도 이벤트는 많은 체크포인트를 기록하고 성능을 저하시킬 수 있습니다. `max_checkpoints`와 함께 사용하세요.
|
||||
체크포인팅은 초기 릴리스 단계입니다. API는 향후 버전에서 변경될 수 있습니다.
|
||||
</Warning>
|
||||
|
||||
<Expandable title="지원되는 모든 이벤트">
|
||||
## 개요
|
||||
|
||||
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
|
||||
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
|
||||
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
|
||||
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
|
||||
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
|
||||
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
|
||||
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
|
||||
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
|
||||
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
|
||||
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
|
||||
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
|
||||
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
|
||||
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
|
||||
- **Logging** — `agent_logs_started`, `agent_logs_execution`
|
||||
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
|
||||
- **시스템 시그널** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
|
||||
- **와일드카드** — `"*"`는 모든 이벤트와 일치합니다.
|
||||
체크포인팅은 실행 중 자동으로 실행 상태를 저장합니다. 크루, 플로우 또는 에이전트가 실행 도중 실패하면 마지막 체크포인트에서 복원하여 이미 완료된 작업을 다시 실행하지 않고 재개할 수 있습니다.
|
||||
|
||||
</Expandable>
|
||||
## 빠른 시작
|
||||
|
||||
### 스토리지 프로바이더
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
<ParamField path="JsonProvider" type="provider">
|
||||
체크포인트당 하나의 파일, `location` 내부에 `<timestamp>_<uuid>.json` 형식으로 명명.
|
||||
</ParamField>
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # 기본값 사용: ./.checkpoints, task_completed 이벤트
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
<ParamField path="SqliteProvider" type="provider">
|
||||
WAL 저널링이 있는 `location`의 단일 데이터베이스 파일.
|
||||
</ParamField>
|
||||
각 태스크가 완료된 후 `./.checkpoints/`에 체크포인트 파일이 기록됩니다.
|
||||
|
||||
### CLI
|
||||
## 설정
|
||||
|
||||
| 명령 | 목적 |
|
||||
|:-----|:-----|
|
||||
| `crewai checkpoint` | TUI 실행; 스토리지 자동 감지. |
|
||||
| `crewai checkpoint --location <path>` | 특정 위치에 대해 TUI 실행. |
|
||||
| `crewai checkpoint list <path>` | 체크포인트 나열. |
|
||||
| `crewai checkpoint info <path>` | 체크포인트 파일 또는 SQLite 데이터베이스의 최신 항목 검사. |
|
||||
`CheckpointConfig`를 사용하여 세부 설정을 제어합니다:
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### CheckpointConfig 필드
|
||||
|
||||
| 필드 | 타입 | 기본값 | 설명 |
|
||||
|:-----|:-----|:-------|:-----|
|
||||
| `location` | `str` | `"./.checkpoints"` | 체크포인트 파일 경로 |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | 체크포인트를 트리거하는 이벤트 타입 |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | 스토리지 백엔드 |
|
||||
| `max_checkpoints` | `int \| None` | `None` | 보관할 최대 파일 수; 오래된 것부터 삭제 |
|
||||
|
||||
### 상속 및 옵트아웃
|
||||
|
||||
Crew, Flow, Agent의 `checkpoint` 필드는 `CheckpointConfig`, `True`, `False`, `None`을 받습니다:
|
||||
|
||||
| 값 | 동작 |
|
||||
|:---|:-----|
|
||||
| `None` (기본값) | 부모에서 상속. 에이전트는 크루의 설정을 상속합니다. |
|
||||
| `True` | 기본값으로 활성화. |
|
||||
| `False` | 명시적 옵트아웃. 부모 상속을 중단합니다. |
|
||||
| `CheckpointConfig(...)` | 사용자 정의 설정. |
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # 크루의 checkpoint 상속
|
||||
Agent(role="Writer", ..., checkpoint=False), # 옵트아웃, 체크포인트 없음
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
|
||||
## 체크포인트에서 재개
|
||||
|
||||
```python
|
||||
# 복원 및 재개
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # 마지막으로 완료된 태스크부터 재개
|
||||
```
|
||||
|
||||
복원된 크루는 이미 완료된 태스크를 건너뛰고 첫 번째 미완료 태스크부터 재개합니다.
|
||||
|
||||
## Crew, Flow, Agent에서 사용 가능
|
||||
|
||||
### Crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
기본 트리거: `task_completed` (완료된 태스크당 하나의 체크포인트).
|
||||
|
||||
### Flow
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
|
||||
# 재개
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
|
||||
## 스토리지 프로바이더
|
||||
|
||||
CrewAI는 두 가지 체크포인트 스토리지 프로바이더를 제공합니다.
|
||||
|
||||
### JsonProvider (기본값)
|
||||
|
||||
각 체크포인트를 별도의 JSON 파일로 저장합니다.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### SqliteProvider
|
||||
|
||||
모든 체크포인트를 단일 SQLite 데이터베이스 파일에 저장합니다.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
## 이벤트 타입
|
||||
|
||||
`on_events` 필드는 이벤트 타입 문자열의 조합을 받습니다. 일반적인 선택:
|
||||
|
||||
| 사용 사례 | 이벤트 |
|
||||
|:----------|:-------|
|
||||
| 각 태스크 완료 후 (Crew) | `["task_completed"]` |
|
||||
| 각 플로우 메서드 완료 후 | `["method_execution_finished"]` |
|
||||
| 에이전트 실행 완료 후 | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| 크루 완료 시에만 | `["crew_kickoff_completed"]` |
|
||||
| 모든 LLM 호출 후 | `["llm_call_completed"]` |
|
||||
| 모든 이벤트 | `["*"]` |
|
||||
|
||||
<Warning>
|
||||
`["*"]` 또는 `llm_call_completed`와 같은 고빈도 이벤트를 사용하면 많은 체크포인트 파일이 생성되어 성능에 영향을 줄 수 있습니다. `max_checkpoints`를 사용하여 디스크 사용량을 제한하세요.
|
||||
</Warning>
|
||||
|
||||
## 수동 체크포인팅
|
||||
|
||||
완전한 제어를 위해 자체 이벤트 핸들러를 등록하고 `state.checkpoint()`를 직접 호출할 수 있습니다:
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
# 동기 핸들러
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"체크포인트 저장: {path}")
|
||||
|
||||
# 비동기 핸들러
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source, event, state):
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"체크포인트 저장: {path}")
|
||||
```
|
||||
|
||||
`state` 인수는 핸들러가 3개의 매개변수를 받을 때 이벤트 버스가 자동으로 전달하는 `RuntimeState`입니다. [Event Listeners](/ko/concepts/event-listener) 문서에 나열된 모든 이벤트 타입에 핸들러를 등록할 수 있습니다.
|
||||
|
||||
체크포인팅은 best-effort입니다: 체크포인트 기록이 실패하면 오류가 로그에 기록되지만 실행은 중단 없이 계속됩니다.
|
||||
|
||||
@@ -16,6 +16,7 @@ mode: "wide"
|
||||
|
||||
- **순차적(Sequential)**: 작업을 순차적으로 실행하여 작업이 질서 있게 진행되도록 보장합니다.
|
||||
- **계층적(Hierarchical)**: 작업을 관리 계층 구조로 조직하며, 작업은 체계적인 명령 체계를 기반으로 위임 및 실행됩니다. 계층적 프로세스를 활성화하려면 매니저 언어 모델(`manager_llm`) 또는 커스텀 매니저 에이전트(`manager_agent`)를 crew에서 지정해야 하며, 이를 통해 매니저가 작업을 생성하고 관리할 수 있도록 지원합니다.
|
||||
- **합의 프로세스(Consensual Process, 계획됨)**: 에이전트들 간에 작업 실행에 대한 협력적 의사결정을 목표로 하며, 이 프로세스 유형은 CrewAI 내에서 작업 관리를 민주적으로 접근하도록 도입됩니다. 앞으로 개발될 예정이며, 현재 코드베이스에는 구현되어 있지 않습니다.
|
||||
|
||||
## 팀워크에서 프로세스의 역할
|
||||
프로세스는 개별 에이전트가 통합된 단위로 작동할 수 있도록 하여, 공통된 목표를 효율적이고 일관성 있게 달성하도록 노력하는 과정을 간소화합니다.
|
||||
@@ -58,9 +59,9 @@ crew = Crew(
|
||||
|
||||
## Process 클래스: 상세 개요
|
||||
|
||||
`Process` 클래스는 열거형(`Enum`)으로 구현되어 타입 안전성을 보장하며, 프로세스 값을 정의된 타입(`sequential`, `hierarchical`)으로 제한합니다.
|
||||
`Process` 클래스는 열거형(`Enum`)으로 구현되어 타입 안전성을 보장하며, 프로세스 값을 정의된 타입(`sequential`, `hierarchical`)으로 제한합니다. 합의 기반(consensual) 프로세스는 향후 추가될 예정이며, 이는 지속적인 개발과 혁신에 대한 우리의 의지를 강조합니다.
|
||||
|
||||
## 결론
|
||||
|
||||
CrewAI 내의 프로세스를 통해 촉진되는 구조화된 협업은 에이전트 간 체계적인 팀워크를 가능하게 하는 데 매우 중요합니다.
|
||||
이 문서는 최신 기능과 향상 사항을 반영하도록 업데이트되었으며, 사용자가 가장 최신이고 포괄적인 정보를 이용할 수 있도록 보장합니다.
|
||||
이 문서는 최신 기능, 향상 사항, 그리고 예정된 Consensual Process 통합을 반영하도록 업데이트되었으며, 사용자가 가장 최신이고 포괄적인 정보를 이용할 수 있도록 보장합니다.
|
||||
@@ -4,39 +4,6 @@ description: "Atualizações de produto, melhorias e correções do CrewAI"
|
||||
icon: "clock"
|
||||
mode: "wide"
|
||||
---
|
||||
<Update label="27 mai 2026">
|
||||
## v1.14.6a2
|
||||
|
||||
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.14.6a2)
|
||||
|
||||
## O que Mudou
|
||||
|
||||
### Recursos
|
||||
- Aprimorar `StdioTransport` para evitar vazamento de variáveis de ambiente
|
||||
- Aprimorar a configuração de planejamento e o manuseio de observações
|
||||
- Declarar `env_vars` em `DatabricksQueryTool`
|
||||
- Adicionar documentação do Controle de Agentes
|
||||
|
||||
### Correções de Bugs
|
||||
- Corrigir vazamentos de saída estruturada em loops de chamada de ferramentas
|
||||
- Remover callbacks e estado de adaptadores que não podem ser revertidos em checkpoints
|
||||
- Serializar campos `type[BaseModel]` como esquema JSON em checkpoints
|
||||
- Evitar `task_started` órfão na restauração do escopo de retomar
|
||||
- Permitir que `AgentExecutor` restaure a partir de checkpoints
|
||||
- Corrigir erro de digitação do MongoDB para `pymongo` nas dependências do pacote
|
||||
|
||||
### Documentação
|
||||
- Reestruturar a página de checkpoints
|
||||
- Documentar o passo de instalação do pacote administrativo único
|
||||
- Migrar Secrets Manager / Workload Identity de replicated-config
|
||||
- Remover a entrada do Repositório de Habilidades do changelog
|
||||
|
||||
## Contribuidores
|
||||
|
||||
@github-actions[bot], @greysonlalonde, @heitorado, @iris-clawd, @lorenzejay, @lucasgomide, @mattatcha, @thiagomoretto, @vinibrsl
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="21 mai 2026">
|
||||
## v1.14.6a1
|
||||
|
||||
@@ -45,6 +12,7 @@ mode: "wide"
|
||||
## O que Mudou
|
||||
|
||||
### Recursos
|
||||
- Adicionar Repositório de Habilidades com registro, cache, CLI e integração SDK
|
||||
- Gerar notas de versão categorizadas para empresas
|
||||
|
||||
### Correções de Bugs
|
||||
|
||||
@@ -1,423 +1,229 @@
|
||||
---
|
||||
title: Checkpointing
|
||||
description: Salve automaticamente o estado de execução para que crews, flows e agentes possam retomar após falhas.
|
||||
description: Salve automaticamente o estado de execucao para que crews, flows e agentes possam retomar apos falhas.
|
||||
icon: floppy-disk
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
O checkpointing salva um snapshot do estado de execução durante uma execução para que uma crew, flow ou agente possa retomar após uma falha ou ser bifurcado em uma branch alternativa.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Explicação" icon="lightbulb" href="#explicacao">
|
||||
Como o checkpointing funciona: eventos, armazenamento e herança.
|
||||
</Card>
|
||||
<Card title="Tutorial" icon="graduation-cap" href="#tutorial-retomar-uma-crew-com-falha">
|
||||
Um passo a passo de 5 minutos: executar, interromper, retomar.
|
||||
</Card>
|
||||
<Card title="Guias de uso" icon="screwdriver-wrench" href="#guias-de-uso">
|
||||
Receitas focadas em tarefas para fluxos comuns.
|
||||
</Card>
|
||||
<Card title="Referência" icon="book" href="#referencia">
|
||||
`CheckpointConfig`, eventos, provedores e CLI.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Explicação
|
||||
|
||||
### O que é um checkpoint
|
||||
|
||||
Um checkpoint captura tudo o que o CrewAI precisa para recriar uma execução em andamento: o estado completo da crew, flow ou agente — configuração, memória e fontes de conhecimento dos agentes, progresso das tarefas, saídas intermediárias, estado interno e atributos — junto com os inputs do kickoff, o histórico de eventos até aquele ponto e um ID de linhagem que liga o checkpoint à execução de origem.
|
||||
|
||||
Restaurar reconstrói esse estado e continua. Tarefas concluídas são puladas, memória e conhecimento são reidratados, e o trabalho downstream roda contra as mesmas saídas que a execução original produziu. Fazer fork executa a mesma restauração sob uma nova linhagem, para que a nova branch e a execução original gravem checkpoints lado a lado sem sobrescrever uma a outra.
|
||||
|
||||
### Quando os checkpoints são gravados
|
||||
|
||||
O checkpointing é orientado a eventos. O runtime se inscreve nos eventos selecionados em `on_events` e grava um checkpoint sempre que um é disparado. O padrão `task_completed` produz um checkpoint por tarefa finalizada — um equilíbrio razoável entre granularidade e uso de disco. Eventos de alta frequência como `llm_call_completed` estão disponíveis para recuperação mais granular, mas gravam muito mais arquivos.
|
||||
|
||||
### Armazenamento
|
||||
|
||||
Dois provedores acompanham o CrewAI:
|
||||
|
||||
- `JsonProvider` grava um arquivo por checkpoint. Legível e fácil de inspecionar.
|
||||
- `SqliteProvider` grava em um único banco SQLite. Melhor para checkpointing de alta frequência.
|
||||
|
||||
Ambos removem os checkpoints mais antigos quando `max_checkpoints` está definido.
|
||||
|
||||
<Note>
|
||||
Gravações de checkpoint automáticas (acionadas por evento) são best-effort: uma falha é registrada em log e a execução continua. Chamadas manuais a `state.checkpoint()` e `state.acheckpoint()` relançam a exceção.
|
||||
</Note>
|
||||
|
||||
### Modelo de herança
|
||||
|
||||
`Crew`, `Flow` e `Agent` aceitam um argumento `checkpoint`. Filhos herdam do pai a menos que definam seu próprio valor ou passem `False` para desativar. Ative o checkpointing uma vez na crew e todos os agentes participam, ou exclua um agente seletivamente.
|
||||
|
||||
## Tutorial: Retomar uma crew com falha
|
||||
|
||||
Este passo a passo leva cerca de 5 minutos. Você executará uma crew de duas tarefas, a interromperá no meio e a retomará a partir do checkpoint salvo.
|
||||
|
||||
<Steps>
|
||||
<Step title="Crie a crew com checkpointing ativado">
|
||||
```python
|
||||
from crewai import Agent, Crew, Task
|
||||
|
||||
researcher = Agent(role="Researcher", goal="Research", backstory="Expert")
|
||||
writer = Agent(role="Writer", goal="Write", backstory="Expert")
|
||||
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[
|
||||
Task(description="Research AI trends", agent=researcher, expected_output="bullets"),
|
||||
Task(description="Write a summary", agent=writer, expected_output="paragraph"),
|
||||
],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
<Step title="Execute e interrompa após a primeira tarefa">
|
||||
```python
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
Pressione `Ctrl+C` após a primeira tarefa concluir. Em `./.checkpoints/`, um arquivo `<timestamp>_<uuid>.json` é o checkpoint.
|
||||
</Step>
|
||||
<Step title="Retome a partir do checkpoint">
|
||||
```python
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
result = crew.kickoff(
|
||||
from_checkpoint=CheckpointConfig(
|
||||
restore_from="./.checkpoints/<timestamp>_<uuid>.json",
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
A tarefa de pesquisa é pulada, o escritor executa contra a saída de pesquisa salva e a crew finaliza.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Guias de uso
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Ativar checkpointing com padrões" icon="play">
|
||||
```python
|
||||
crew = Crew(agents=[...], tasks=[...], checkpoint=True)
|
||||
```
|
||||
|
||||
Grava em `./.checkpoints/` em cada `task_completed`.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Personalizar armazenamento e frequência" icon="sliders">
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Escolher um provedor de armazenamento" icon="database">
|
||||
<CodeGroup>
|
||||
```python JsonProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
```python SqliteProvider
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
max_checkpoints=50,
|
||||
),
|
||||
)
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Tip>
|
||||
O SQLite ativa o modo journal WAL para leituras concorrentes. Prefira-o para checkpointing de alta frequência.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Desativar um agente específico" icon="user-slash">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...),
|
||||
Agent(role="Writer", ..., checkpoint=False),
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Fazer fork em uma nova branch" icon="code-branch">
|
||||
`fork()` restaura um checkpoint sob uma nova linhagem para que a nova execução não colida com a original.
|
||||
|
||||
```python
|
||||
config = CheckpointConfig(restore_from="./my_checkpoints/<file>.json")
|
||||
crew = Crew.fork(config, branch="experiment-a")
|
||||
result = crew.kickoff(inputs={"strategy": "aggressive"})
|
||||
```
|
||||
|
||||
O label `branch` é opcional; um é gerado se omitido.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Checkpoint em Crew, Flow ou Agent" icon="cubes">
|
||||
<Tabs>
|
||||
<Tab title="Crew">
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
Gatilho padrão: `task_completed`.
|
||||
</Tab>
|
||||
<Tab title="Flow">
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Agent">
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Gravar um checkpoint manualmente" icon="code">
|
||||
Registre um handler em qualquer evento e chame `state.checkpoint()`.
|
||||
|
||||
<CodeGroup>
|
||||
```python Sync
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"Checkpoint salvo: {path}")
|
||||
```
|
||||
```python Async
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from crewai.state.runtime import RuntimeState
|
||||
|
||||
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source: Any, event: LLMCallCompletedEvent, state: RuntimeState) -> None:
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"Checkpoint salvo: {path}")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Um argumento `state` é fornecido automaticamente quando o handler recebe três parâmetros. Veja [Event Listeners](/pt-BR/concepts/event-listener) para o catálogo completo de eventos.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Navegar, retomar e fazer fork pela CLI" icon="terminal">
|
||||
```bash
|
||||
crewai checkpoint
|
||||
crewai checkpoint --location ./my_checkpoints
|
||||
crewai checkpoint --location ./.checkpoints.db
|
||||
```
|
||||
|
||||
<Frame caption="Árvore de checkpoints — branches e forks aninham sob seu pai.">
|
||||
<img src="/images/checkpoint-tui-tree.png" alt="Checkpoint TUI tree view" />
|
||||
</Frame>
|
||||
|
||||
O painel esquerdo agrupa checkpoints por branch; forks aninham sob seu pai. Selecionar um checkpoint abre o painel de detalhes com metadados, estado da entidade e progresso das tarefas. **Resume** continua a execução; **Fork** inicia uma nova branch.
|
||||
|
||||
<Frame caption="Aba de visão geral — metadados, estado da entidade e resumo da execução.">
|
||||
<img src="/images/checkpoint-tui-detail-overview.png" alt="Checkpoint detail overview tab" />
|
||||
</Frame>
|
||||
|
||||
O painel de detalhes expõe duas áreas editáveis:
|
||||
|
||||
- **Inputs** — os inputs originais do kickoff, preenchidos e editáveis.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-inputs.png" alt="Editable kickoff inputs" />
|
||||
</Frame>
|
||||
|
||||
- **Saídas das tarefas** — saídas das tarefas concluídas. Editar uma saída e pressionar **Fork** invalida tarefas downstream para que sejam reexecutadas com o contexto modificado.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/checkpoint-tui-detail-tasks.png" alt="Editable task outputs" />
|
||||
</Frame>
|
||||
|
||||
<Frame caption="Tela de fork — confirme uma nova branch a partir do checkpoint selecionado.">
|
||||
<img src="/images/checkpoint-tui-details-fork.png" alt="Fork confirmation panel" />
|
||||
</Frame>
|
||||
|
||||
<Tip>
|
||||
Útil para exploração de cenários: fork, ajuste, observe.
|
||||
</Tip>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Inspecionar checkpoints sem a TUI" icon="magnifying-glass">
|
||||
```bash
|
||||
crewai checkpoint list ./my_checkpoints
|
||||
crewai checkpoint info ./my_checkpoints/<file>.json
|
||||
crewai checkpoint info ./.checkpoints.db
|
||||
```
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## Referência
|
||||
|
||||
### `CheckpointConfig`
|
||||
|
||||
<ParamField path="location" type="str" default='"./.checkpoints"'>
|
||||
Destino do armazenamento. Diretório para `JsonProvider`, caminho de arquivo de banco para `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="on_events" type='list[CheckpointEventType | Literal["*"]]' default='["task_completed"]'>
|
||||
Tipos de evento que disparam um checkpoint. `CheckpointEventType` é um `Literal` — seu type checker autocompleta e rejeita valores não suportados. Veja [tipos de evento](#tipos-de-evento) para a lista completa.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="provider" type="BaseProvider" default="JsonProvider()">
|
||||
Backend de armazenamento. `JsonProvider` ou `SqliteProvider`.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="max_checkpoints" type="int | None" default="None">
|
||||
Máximo de checkpoints a reter. Os mais antigos são removidos após cada gravação.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="restore_from" type="Path | str | None" default="None">
|
||||
Checkpoint a restaurar quando passado via `from_checkpoint`.
|
||||
</ParamField>
|
||||
|
||||
### Valores do campo `checkpoint`
|
||||
|
||||
Aceito por `Crew`, `Flow` e `Agent`.
|
||||
|
||||
<ParamField path="None" type="padrão">
|
||||
Herda do pai.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="True" type="bool">
|
||||
Ativa com padrões.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="False" type="bool">
|
||||
Desativação explícita. Interrompe a herança.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="CheckpointConfig(...)" type="CheckpointConfig">
|
||||
Configuração personalizada.
|
||||
</ParamField>
|
||||
|
||||
### Tipos de evento
|
||||
|
||||
`on_events` aceita qualquer combinação de valores `CheckpointEventType`. O padrão `["task_completed"]` grava um checkpoint por tarefa finalizada; `["*"]` corresponde a todos os eventos.
|
||||
|
||||
<Warning>
|
||||
`["*"]` e eventos de alta frequência como `llm_call_completed` gravam muitos checkpoints e podem degradar o desempenho. Combine com `max_checkpoints`.
|
||||
O checkpointing esta em versao inicial. As APIs podem mudar em versoes futuras.
|
||||
</Warning>
|
||||
|
||||
<Expandable title="Todos os eventos suportados">
|
||||
## Visao Geral
|
||||
|
||||
- **Task** — `task_started`, `task_completed`, `task_failed`, `task_evaluation`
|
||||
- **Crew** — `crew_kickoff_started`, `crew_kickoff_completed`, `crew_kickoff_failed`, `crew_train_started`, `crew_train_completed`, `crew_train_failed`, `crew_test_started`, `crew_test_completed`, `crew_test_failed`, `crew_test_result`
|
||||
- **Agent** — `agent_execution_started`, `agent_execution_completed`, `agent_execution_error`, `lite_agent_execution_started`, `lite_agent_execution_completed`, `lite_agent_execution_error`, `agent_evaluation_started`, `agent_evaluation_completed`, `agent_evaluation_failed`
|
||||
- **Flow** — `flow_created`, `flow_started`, `flow_finished`, `flow_paused`, `method_execution_started`, `method_execution_finished`, `method_execution_failed`, `method_execution_paused`, `human_feedback_requested`, `human_feedback_received`, `flow_input_requested`, `flow_input_received`
|
||||
- **LLM** — `llm_call_started`, `llm_call_completed`, `llm_call_failed`, `llm_stream_chunk`, `llm_thinking_chunk`
|
||||
- **LLM Guardrail** — `llm_guardrail_started`, `llm_guardrail_completed`, `llm_guardrail_failed`
|
||||
- **Tool** — `tool_usage_started`, `tool_usage_finished`, `tool_usage_error`, `tool_validate_input_error`, `tool_selection_error`, `tool_execution_error`
|
||||
- **Memory** — `memory_save_started`, `memory_save_completed`, `memory_save_failed`, `memory_query_started`, `memory_query_completed`, `memory_query_failed`, `memory_retrieval_started`, `memory_retrieval_completed`, `memory_retrieval_failed`
|
||||
- **Knowledge** — `knowledge_search_query_started`, `knowledge_search_query_completed`, `knowledge_query_started`, `knowledge_query_completed`, `knowledge_query_failed`, `knowledge_search_query_failed`
|
||||
- **Reasoning** — `agent_reasoning_started`, `agent_reasoning_completed`, `agent_reasoning_failed`
|
||||
- **MCP** — `mcp_connection_started`, `mcp_connection_completed`, `mcp_connection_failed`, `mcp_tool_execution_started`, `mcp_tool_execution_completed`, `mcp_tool_execution_failed`, `mcp_config_fetch_failed`
|
||||
- **Observation** — `step_observation_started`, `step_observation_completed`, `step_observation_failed`, `plan_refinement`, `plan_replan_triggered`, `goal_achieved_early`
|
||||
- **Skill** — `skill_discovery_started`, `skill_discovery_completed`, `skill_loaded`, `skill_activated`, `skill_load_failed`
|
||||
- **Logging** — `agent_logs_started`, `agent_logs_execution`
|
||||
- **A2A** — `a2a_delegation_started`, `a2a_delegation_completed`, `a2a_conversation_started`, `a2a_conversation_completed`, `a2a_message_sent`, `a2a_response_received`, `a2a_polling_started`, `a2a_polling_status`, `a2a_push_notification_registered`, `a2a_push_notification_received`, `a2a_push_notification_sent`, `a2a_push_notification_timeout`, `a2a_streaming_started`, `a2a_streaming_chunk`, `a2a_agent_card_fetched`, `a2a_authentication_failed`, `a2a_artifact_received`, `a2a_connection_error`, `a2a_server_task_started`, `a2a_server_task_completed`, `a2a_server_task_canceled`, `a2a_server_task_failed`, `a2a_parallel_delegation_started`, `a2a_parallel_delegation_completed`, `a2a_transport_negotiated`, `a2a_content_type_negotiated`, `a2a_context_created`, `a2a_context_expired`, `a2a_context_idle`, `a2a_context_completed`, `a2a_context_pruned`
|
||||
- **Sinais de sistema** — `SIGTERM`, `SIGINT`, `SIGHUP`, `SIGTSTP`, `SIGCONT`
|
||||
- **Wildcard** — `"*"` corresponde a todos os eventos.
|
||||
O checkpointing salva automaticamente o estado de execucao durante uma execucao. Se uma crew, flow ou agente falhar no meio da execucao, voce pode restaurar a partir do ultimo checkpoint e retomar sem reexecutar o trabalho ja concluido.
|
||||
|
||||
</Expandable>
|
||||
## Inicio Rapido
|
||||
|
||||
### Provedores de armazenamento
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
<ParamField path="JsonProvider" type="provider">
|
||||
Um arquivo por checkpoint, nomeado `<timestamp>_<uuid>.json` dentro de `location`.
|
||||
</ParamField>
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=True, # usa padroes: ./.checkpoints, em task_completed
|
||||
)
|
||||
result = crew.kickoff()
|
||||
```
|
||||
|
||||
<ParamField path="SqliteProvider" type="provider">
|
||||
Arquivo de banco único em `location` com journaling WAL.
|
||||
</ParamField>
|
||||
Os arquivos de checkpoint sao gravados em `./.checkpoints/` apos cada tarefa concluida.
|
||||
|
||||
### CLI
|
||||
## Configuracao
|
||||
|
||||
| Comando | Propósito |
|
||||
|:--------|:----------|
|
||||
| `crewai checkpoint` | Inicia a TUI; detecta o armazenamento automaticamente. |
|
||||
| `crewai checkpoint --location <path>` | Inicia a TUI em uma localização específica. |
|
||||
| `crewai checkpoint list <path>` | Lista checkpoints. |
|
||||
| `crewai checkpoint info <path>` | Inspeciona um arquivo de checkpoint ou a entrada mais recente em um banco SQLite. |
|
||||
Use `CheckpointConfig` para controle total:
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
on_events=["task_completed", "crew_kickoff_completed"],
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### Campos do CheckpointConfig
|
||||
|
||||
| Campo | Tipo | Padrao | Descricao |
|
||||
|:------|:-----|:-------|:----------|
|
||||
| `location` | `str` | `"./.checkpoints"` | Caminho para os arquivos de checkpoint |
|
||||
| `on_events` | `list[str]` | `["task_completed"]` | Tipos de evento que acionam um checkpoint |
|
||||
| `provider` | `BaseProvider` | `JsonProvider()` | Backend de armazenamento |
|
||||
| `max_checkpoints` | `int \| None` | `None` | Maximo de arquivos a manter; os mais antigos sao removidos primeiro |
|
||||
|
||||
### Heranca e Desativacao
|
||||
|
||||
O campo `checkpoint` em Crew, Flow e Agent aceita `CheckpointConfig`, `True`, `False` ou `None`:
|
||||
|
||||
| Valor | Comportamento |
|
||||
|:------|:--------------|
|
||||
| `None` (padrao) | Herda do pai. Um agente herda a configuracao da crew. |
|
||||
| `True` | Ativa com padroes. |
|
||||
| `False` | Desativacao explicita. Interrompe a heranca do pai. |
|
||||
| `CheckpointConfig(...)` | Configuracao personalizada. |
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[
|
||||
Agent(role="Researcher", ...), # herda checkpoint da crew
|
||||
Agent(role="Writer", ..., checkpoint=False), # desativado, sem checkpoints
|
||||
],
|
||||
tasks=[...],
|
||||
checkpoint=True,
|
||||
)
|
||||
```
|
||||
|
||||
## Retomando a partir de um Checkpoint
|
||||
|
||||
```python
|
||||
# Restaurar e retomar
|
||||
crew = Crew.from_checkpoint("./my_checkpoints/20260407T120000_abc123.json")
|
||||
result = crew.kickoff() # retoma a partir da ultima tarefa concluida
|
||||
```
|
||||
|
||||
A crew restaurada pula tarefas ja concluidas e retoma a partir da primeira incompleta.
|
||||
|
||||
## Funciona em Crew, Flow e Agent
|
||||
|
||||
### Crew
|
||||
|
||||
```python
|
||||
crew = Crew(
|
||||
agents=[researcher, writer],
|
||||
tasks=[research_task, write_task, review_task],
|
||||
checkpoint=CheckpointConfig(location="./crew_cp"),
|
||||
)
|
||||
```
|
||||
|
||||
Gatilho padrao: `task_completed` (um checkpoint por tarefa finalizada).
|
||||
|
||||
### Flow
|
||||
|
||||
```python
|
||||
from crewai.flow.flow import Flow, start, listen
|
||||
from crewai import CheckpointConfig
|
||||
|
||||
class MyFlow(Flow):
|
||||
@start()
|
||||
def step_one(self):
|
||||
return "data"
|
||||
|
||||
@listen(step_one)
|
||||
def step_two(self, data):
|
||||
return process(data)
|
||||
|
||||
flow = MyFlow(
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./flow_cp",
|
||||
on_events=["method_execution_finished"],
|
||||
),
|
||||
)
|
||||
result = flow.kickoff()
|
||||
|
||||
# Retomar
|
||||
flow = MyFlow.from_checkpoint("./flow_cp/20260407T120000_abc123.json")
|
||||
result = flow.kickoff()
|
||||
```
|
||||
|
||||
### Agent
|
||||
|
||||
```python
|
||||
agent = Agent(
|
||||
role="Researcher",
|
||||
goal="Research topics",
|
||||
backstory="Expert researcher",
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./agent_cp",
|
||||
on_events=["lite_agent_execution_completed"],
|
||||
),
|
||||
)
|
||||
result = agent.kickoff(messages=[{"role": "user", "content": "Research AI trends"}])
|
||||
```
|
||||
|
||||
## Provedores de Armazenamento
|
||||
|
||||
O CrewAI inclui dois provedores de armazenamento para checkpoints.
|
||||
|
||||
### JsonProvider (padrao)
|
||||
|
||||
Grava cada checkpoint como um arquivo JSON separado.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import JsonProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./my_checkpoints",
|
||||
provider=JsonProvider(),
|
||||
max_checkpoints=5,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
### SqliteProvider
|
||||
|
||||
Armazena todos os checkpoints em um unico arquivo SQLite.
|
||||
|
||||
```python
|
||||
from crewai import Crew, CheckpointConfig
|
||||
from crewai.state import SqliteProvider
|
||||
|
||||
crew = Crew(
|
||||
agents=[...],
|
||||
tasks=[...],
|
||||
checkpoint=CheckpointConfig(
|
||||
location="./.checkpoints.db",
|
||||
provider=SqliteProvider(),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
## Tipos de Evento
|
||||
|
||||
O campo `on_events` aceita qualquer combinacao de strings de tipo de evento. Escolhas comuns:
|
||||
|
||||
| Caso de Uso | Eventos |
|
||||
|:------------|:--------|
|
||||
| Apos cada tarefa (Crew) | `["task_completed"]` |
|
||||
| Apos cada metodo do flow | `["method_execution_finished"]` |
|
||||
| Apos execucao do agente | `["agent_execution_completed"]`, `["lite_agent_execution_completed"]` |
|
||||
| Apenas na conclusao da crew | `["crew_kickoff_completed"]` |
|
||||
| Apos cada chamada LLM | `["llm_call_completed"]` |
|
||||
| Em tudo | `["*"]` |
|
||||
|
||||
<Warning>
|
||||
Usar `["*"]` ou eventos de alta frequencia como `llm_call_completed` gravara muitos arquivos de checkpoint e pode impactar o desempenho. Use `max_checkpoints` para limitar o uso de disco.
|
||||
</Warning>
|
||||
|
||||
## Checkpointing Manual
|
||||
|
||||
Para controle total, registre seu proprio handler de evento e chame `state.checkpoint()` diretamente:
|
||||
|
||||
```python
|
||||
from crewai.events.event_bus import crewai_event_bus
|
||||
from crewai.events.types.llm_events import LLMCallCompletedEvent
|
||||
|
||||
# Handler sincrono
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
def on_llm_done(source, event, state):
|
||||
path = state.checkpoint("./my_checkpoints")
|
||||
print(f"Checkpoint salvo: {path}")
|
||||
|
||||
# Handler assincrono
|
||||
@crewai_event_bus.on(LLMCallCompletedEvent)
|
||||
async def on_llm_done_async(source, event, state):
|
||||
path = await state.acheckpoint("./my_checkpoints")
|
||||
print(f"Checkpoint salvo: {path}")
|
||||
```
|
||||
|
||||
O argumento `state` e o `RuntimeState` passado automaticamente pelo barramento de eventos quando seu handler aceita 3 parametros. Voce pode registrar handlers em qualquer tipo de evento listado na documentacao de [Event Listeners](/pt-BR/concepts/event-listener).
|
||||
|
||||
O checkpointing e best-effort: se uma gravacao de checkpoint falhar, o erro e registrado no log, mas a execucao continua sem interrupcao.
|
||||
|
||||
@@ -16,6 +16,7 @@ mode: "wide"
|
||||
|
||||
- **Sequencial**: Executa tarefas de forma sequencial, garantindo que as tarefas sejam concluídas em uma progressão ordenada.
|
||||
- **Hierárquico**: Organiza tarefas em uma hierarquia gerencial, onde as tarefas são delegadas e executadas com base numa cadeia de comando estruturada. Um modelo de linguagem de gerente (`manager_llm`) ou um agente gerente personalizado (`manager_agent`) deve ser especificado na crew para habilitar o processo hierárquico, facilitando a criação e o gerenciamento de tarefas pelo gerente.
|
||||
- **Processo Consensual (Planejado)**: Visando a tomada de decisão colaborativa entre agentes para execução de tarefas, esse tipo de processo introduz uma abordagem democrática ao gerenciamento de tarefas dentro do CrewAI. Está planejado para desenvolvimento futuro e ainda não está implementado no código-fonte.
|
||||
|
||||
## O Papel dos Processos no Trabalho em Equipe
|
||||
Os processos permitem que agentes individuais atuem como uma unidade coesa, otimizando seus esforços para atingir objetivos comuns com eficiência e coerência.
|
||||
@@ -58,9 +59,9 @@ Emulando uma hierarquia corporativa, o CrewAI permite especificar um agente gere
|
||||
|
||||
## Classe Process: Visão Detalhada
|
||||
|
||||
A classe `Process` é implementada como uma enumeração (`Enum`), garantindo segurança de tipo e restringindo os valores de processos aos tipos definidos (`sequential`, `hierarchical`).
|
||||
A classe `Process` é implementada como uma enumeração (`Enum`), garantindo segurança de tipo e restringindo os valores de processos aos tipos definidos (`sequential`, `hierarchical`). O processo consensual está planejado para inclusão futura, reforçando nosso compromisso com o desenvolvimento contínuo e a inovação.
|
||||
|
||||
## Conclusão
|
||||
|
||||
A colaboração estruturada possibilitada pelos processos dentro do CrewAI é fundamental para permitir o trabalho em equipe sistemático entre agentes.
|
||||
Esta documentação foi atualizada para refletir os mais recentes recursos e melhorias, garantindo que os usuários tenham acesso às informações mais atuais e abrangentes.
|
||||
Esta documentação foi atualizada para refletir os mais recentes recursos, melhorias e a planejada integração do Processo Consensual, garantindo que os usuários tenham acesso às informações mais atuais e abrangentes.
|
||||
@@ -8,7 +8,7 @@ authors = [
|
||||
]
|
||||
requires-python = ">=3.10, <3.14"
|
||||
dependencies = [
|
||||
"crewai-core==1.14.6a2",
|
||||
"crewai-core==1.14.6a1",
|
||||
"click~=8.1.7",
|
||||
"pydantic>=2.11.9,<2.13",
|
||||
"pydantic-settings~=2.10.1",
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "1.14.6a2"
|
||||
__version__ = "1.14.6a1"
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "1.14.6a2"
|
||||
__version__ = "1.14.6a1"
|
||||
|
||||
@@ -152,4 +152,4 @@ __all__ = [
|
||||
"wrap_file_source",
|
||||
]
|
||||
|
||||
__version__ = "1.14.6a2"
|
||||
__version__ = "1.14.6a1"
|
||||
|
||||
@@ -10,7 +10,7 @@ requires-python = ">=3.10, <3.14"
|
||||
dependencies = [
|
||||
"pytube~=15.0.0",
|
||||
"requests>=2.33.0,<3",
|
||||
"crewai==1.14.6a2",
|
||||
"crewai==1.14.6a1",
|
||||
"tiktoken>=0.8.0,<0.13",
|
||||
"beautifulsoup4~=4.13.4",
|
||||
"python-docx~=1.2.0",
|
||||
|
||||
@@ -330,4 +330,4 @@ __all__ = [
|
||||
"ZapierActionTools",
|
||||
]
|
||||
|
||||
__version__ = "1.14.6a2"
|
||||
__version__ = "1.14.6a1"
|
||||
|
||||
@@ -8,8 +8,8 @@ authors = [
|
||||
]
|
||||
requires-python = ">=3.10, <3.14"
|
||||
dependencies = [
|
||||
"crewai-core==1.14.6a2",
|
||||
"crewai-cli==1.14.6a2",
|
||||
"crewai-core==1.14.6a1",
|
||||
"crewai-cli==1.14.6a1",
|
||||
# Core Dependencies
|
||||
"pydantic>=2.11.9,<2.13",
|
||||
"openai>=2.30.0,<3",
|
||||
@@ -54,7 +54,7 @@ Repository = "https://github.com/crewAIInc/crewAI"
|
||||
|
||||
[project.optional-dependencies]
|
||||
tools = [
|
||||
"crewai-tools==1.14.6a2",
|
||||
"crewai-tools==1.14.6a1",
|
||||
]
|
||||
embeddings = [
|
||||
"tiktoken>=0.8.0,<0.13"
|
||||
|
||||
@@ -48,7 +48,7 @@ def _suppress_pydantic_deprecation_warnings() -> None:
|
||||
|
||||
_suppress_pydantic_deprecation_warnings()
|
||||
|
||||
__version__ = "1.14.6a2"
|
||||
__version__ = "1.14.6a1"
|
||||
|
||||
_LAZY_IMPORTS: dict[str, tuple[str, str]] = {
|
||||
"Memory": ("crewai.memory.unified_memory", "Memory"),
|
||||
|
||||
@@ -28,7 +28,6 @@ from pydantic import (
|
||||
ConfigDict,
|
||||
Field,
|
||||
PrivateAttr,
|
||||
ValidationError,
|
||||
model_validator,
|
||||
)
|
||||
from pydantic.functional_serializers import PlainSerializer
|
||||
@@ -1711,32 +1710,24 @@ class Agent(BaseAgent):
|
||||
elif response_format:
|
||||
raw_output = str(output) if not isinstance(output, str) else output
|
||||
try:
|
||||
formatted_result = response_format.model_validate_json(raw_output)
|
||||
except ValidationError:
|
||||
# Direct JSON validation failed; fall back to converter-based parsing below.
|
||||
formatted_result = None
|
||||
model_schema = generate_model_description(response_format)
|
||||
schema = json.dumps(model_schema, indent=2)
|
||||
instructions = I18N_DEFAULT.slice("formatted_task_instructions").format(
|
||||
output_format=schema
|
||||
)
|
||||
|
||||
if formatted_result is None:
|
||||
try:
|
||||
model_schema = generate_model_description(response_format)
|
||||
schema = json.dumps(model_schema, indent=2)
|
||||
instructions = I18N_DEFAULT.slice(
|
||||
"formatted_task_instructions"
|
||||
).format(output_format=schema)
|
||||
converter = Converter(
|
||||
llm=cast(BaseLLM, self.llm),
|
||||
text=raw_output,
|
||||
model=response_format,
|
||||
instructions=instructions,
|
||||
)
|
||||
|
||||
converter = Converter(
|
||||
llm=cast(BaseLLM, self.llm),
|
||||
text=raw_output,
|
||||
model=response_format,
|
||||
instructions=instructions,
|
||||
)
|
||||
|
||||
conversion_result = converter.to_pydantic()
|
||||
if isinstance(conversion_result, BaseModel):
|
||||
formatted_result = conversion_result
|
||||
except ConverterError:
|
||||
# Conversion failure is non-fatal; raw output is preserved below.
|
||||
pass
|
||||
conversion_result = converter.to_pydantic()
|
||||
if isinstance(conversion_result, BaseModel):
|
||||
formatted_result = conversion_result
|
||||
except ConverterError:
|
||||
pass
|
||||
else:
|
||||
raw_output = str(output) if not isinstance(output, str) else output
|
||||
|
||||
|
||||
@@ -350,10 +350,6 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
|
||||
enforce_rpm_limit(self.request_within_rpm_limit)
|
||||
|
||||
effective_response_model = (
|
||||
None if self.original_tools else self.response_model
|
||||
)
|
||||
|
||||
answer = get_llm_response(
|
||||
llm=cast("BaseLLM", self.llm),
|
||||
messages=self.messages,
|
||||
@@ -361,11 +357,11 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=effective_response_model,
|
||||
response_model=self.response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
if effective_response_model is not None:
|
||||
if self.response_model is not None:
|
||||
try:
|
||||
if isinstance(answer, BaseModel):
|
||||
output_json = answer.model_dump_json()
|
||||
@@ -506,7 +502,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=None,
|
||||
response_model=self.response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
@@ -1163,10 +1159,6 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
|
||||
enforce_rpm_limit(self.request_within_rpm_limit)
|
||||
|
||||
effective_response_model = (
|
||||
None if self.original_tools else self.response_model
|
||||
)
|
||||
|
||||
answer = await aget_llm_response(
|
||||
llm=cast("BaseLLM", self.llm),
|
||||
messages=self.messages,
|
||||
@@ -1174,12 +1166,12 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=effective_response_model,
|
||||
response_model=self.response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
if effective_response_model is not None:
|
||||
if self.response_model is not None:
|
||||
try:
|
||||
if isinstance(answer, BaseModel):
|
||||
output_json = answer.model_dump_json()
|
||||
@@ -1319,7 +1311,7 @@ class CrewAgentExecutor(BaseAgentExecutor):
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=None,
|
||||
response_model=self.response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
@@ -1273,10 +1273,6 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor):
|
||||
try:
|
||||
enforce_rpm_limit(self.request_within_rpm_limit)
|
||||
|
||||
effective_response_model = (
|
||||
None if self.original_tools else self.response_model
|
||||
)
|
||||
|
||||
answer = get_llm_response(
|
||||
llm=self.llm,
|
||||
messages=list(self.state.messages),
|
||||
@@ -1284,7 +1280,7 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor):
|
||||
printer=PRINTER,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=effective_response_model,
|
||||
response_model=self.response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
@@ -1372,7 +1368,7 @@ class AgentExecutor(Flow[AgentExecutorState], BaseAgentExecutor):
|
||||
available_functions=None,
|
||||
from_task=self.task,
|
||||
from_agent=self.agent,
|
||||
response_model=None,
|
||||
response_model=self.response_model,
|
||||
executor_context=self,
|
||||
verbose=self.agent.verbose,
|
||||
)
|
||||
|
||||
@@ -23,7 +23,6 @@ from pydantic import (
|
||||
BaseModel,
|
||||
Field,
|
||||
PrivateAttr,
|
||||
ValidationError,
|
||||
field_serializer,
|
||||
field_validator,
|
||||
model_validator,
|
||||
@@ -640,38 +639,29 @@ class LiteAgent(FlowTrackable, BaseModel):
|
||||
formatted_result = agent_finish.output
|
||||
elif active_response_format:
|
||||
try:
|
||||
formatted_result = active_response_format.model_validate_json(
|
||||
str(agent_finish.output)
|
||||
model_schema = generate_model_description(active_response_format)
|
||||
schema = json.dumps(model_schema, indent=2)
|
||||
instructions = I18N_DEFAULT.slice("formatted_task_instructions").format(
|
||||
output_format=schema
|
||||
)
|
||||
except ValidationError:
|
||||
# Direct JSON validation failed; fall back to converter-based parsing below.
|
||||
formatted_result = None
|
||||
|
||||
if formatted_result is None:
|
||||
try:
|
||||
model_schema = generate_model_description(active_response_format)
|
||||
schema = json.dumps(model_schema, indent=2)
|
||||
instructions = I18N_DEFAULT.slice(
|
||||
"formatted_task_instructions"
|
||||
).format(output_format=schema)
|
||||
converter = Converter(
|
||||
llm=self.llm,
|
||||
text=agent_finish.output,
|
||||
model=active_response_format,
|
||||
instructions=instructions,
|
||||
)
|
||||
|
||||
converter = Converter(
|
||||
llm=self.llm,
|
||||
text=agent_finish.output,
|
||||
model=active_response_format,
|
||||
instructions=instructions,
|
||||
result = converter.to_pydantic()
|
||||
if isinstance(result, BaseModel):
|
||||
formatted_result = result
|
||||
except ConverterError as e:
|
||||
if self.verbose:
|
||||
PRINTER.print(
|
||||
content=f"Failed to parse output into response format after retries: {e.message}",
|
||||
color="yellow",
|
||||
)
|
||||
|
||||
result = converter.to_pydantic()
|
||||
if isinstance(result, BaseModel):
|
||||
formatted_result = result
|
||||
except ConverterError as e:
|
||||
if self.verbose:
|
||||
PRINTER.print(
|
||||
content=f"Failed to parse output into response format after retries: {e.message}",
|
||||
color="yellow",
|
||||
)
|
||||
|
||||
if isinstance(self.llm, BaseLLM):
|
||||
usage_metrics = self.llm.get_token_usage_summary()
|
||||
else:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Stdio transport for MCP servers running as local processes."""
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Callable
|
||||
import os
|
||||
import subprocess
|
||||
from typing import Any
|
||||
|
||||
@@ -10,16 +10,6 @@ from typing_extensions import Self
|
||||
from crewai.mcp.transports.base import BaseTransport, TransportType
|
||||
|
||||
|
||||
_env_filter_hook: Callable[[dict[str, str]], dict[str, str]] | None = None
|
||||
"""Optional hook to post-process the environment passed to stdio MCP servers.
|
||||
|
||||
Extensions (e.g., enterprise policy) can set this to enforce org-wide rules such
|
||||
as stripping credentials from `env` before the subprocess is spawned. The hook
|
||||
receives the merged env (SDK defaults + user-supplied `env=`) and returns the
|
||||
filtered env. Set to None to disable.
|
||||
"""
|
||||
|
||||
|
||||
class StdioTransport(BaseTransport):
|
||||
"""Stdio transport for connecting to local MCP servers.
|
||||
|
||||
@@ -81,18 +71,15 @@ class StdioTransport(BaseTransport):
|
||||
|
||||
try:
|
||||
from mcp import StdioServerParameters
|
||||
from mcp.client.stdio import get_default_environment, stdio_client
|
||||
from mcp.client.stdio import stdio_client
|
||||
|
||||
process_env = get_default_environment()
|
||||
process_env = os.environ.copy()
|
||||
process_env.update(self.env)
|
||||
|
||||
if _env_filter_hook is not None:
|
||||
process_env = _env_filter_hook(process_env)
|
||||
|
||||
server_params = StdioServerParameters(
|
||||
command=self.command,
|
||||
args=self.args,
|
||||
env=process_env,
|
||||
env=process_env if process_env else None,
|
||||
)
|
||||
self._transport_context = stdio_client(server_params)
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ from typing import Any
|
||||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
from crewai.agents.tools_handler import ToolsHandler as _ToolsHandler
|
||||
from crewai.agents.step_executor import StepExecutor
|
||||
@@ -109,9 +108,6 @@ class TestAgentExecutorState:
|
||||
class TestAgentExecutor:
|
||||
"""Test AgentExecutor class."""
|
||||
|
||||
class StructuredResult(BaseModel):
|
||||
value: str
|
||||
|
||||
@pytest.fixture
|
||||
def mock_dependencies(self):
|
||||
"""Create mock dependencies for executor."""
|
||||
@@ -219,49 +215,6 @@ class TestAgentExecutor:
|
||||
|
||||
assert result == "check_iteration"
|
||||
|
||||
def test_call_llm_and_parse_does_not_pass_response_model_with_tools(
|
||||
self, mock_dependencies
|
||||
):
|
||||
"""Structured output should not be requested during ReAct tool loops."""
|
||||
executor = _build_executor(
|
||||
**mock_dependencies,
|
||||
original_tools=[Mock()],
|
||||
response_model=self.StructuredResult,
|
||||
callbacks=[],
|
||||
)
|
||||
executor.state.messages = [{"role": "user", "content": "Use a tool"}]
|
||||
|
||||
with patch(
|
||||
"crewai.experimental.agent_executor.get_llm_response",
|
||||
return_value="Thought: done\nFinal Answer: complete",
|
||||
) as get_llm_response_mock:
|
||||
result = executor.call_llm_and_parse()
|
||||
|
||||
assert result == "parsed"
|
||||
assert get_llm_response_mock.call_args.kwargs["response_model"] is None
|
||||
|
||||
def test_call_llm_native_tools_does_not_pass_response_model_with_tools(
|
||||
self, mock_dependencies
|
||||
):
|
||||
"""Structured output should not be requested during native tool calls."""
|
||||
executor = _build_executor(
|
||||
**mock_dependencies,
|
||||
original_tools=[Mock()],
|
||||
response_model=self.StructuredResult,
|
||||
callbacks=[],
|
||||
)
|
||||
executor._openai_tools = [{"type": "function", "function": {"name": "lookup"}}]
|
||||
executor.state.messages = [{"role": "user", "content": "Use a tool"}]
|
||||
|
||||
with patch(
|
||||
"crewai.experimental.agent_executor.get_llm_response",
|
||||
return_value="complete",
|
||||
) as get_llm_response_mock:
|
||||
result = executor.call_llm_native_tools()
|
||||
|
||||
assert result == "native_finished"
|
||||
assert get_llm_response_mock.call_args.kwargs["response_model"] is None
|
||||
|
||||
def test_finalize_success(self, mock_dependencies):
|
||||
"""Test finalize with valid AgentFinish."""
|
||||
with patch.object(AgentExecutor, "_show_logs") as mock_show_logs:
|
||||
|
||||
@@ -824,7 +824,7 @@ class TestBedrockNativeToolCalling:
|
||||
self, calculator_tool: CalculatorTool
|
||||
) -> None:
|
||||
"""Test Bedrock agent kickoff with mocked LLM call."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6")
|
||||
llm = LLM(model="bedrock/anthropic.claude-3-haiku-20240307-v1:0")
|
||||
|
||||
agent = Agent(
|
||||
role="Math Assistant",
|
||||
@@ -858,7 +858,7 @@ class TestBedrockNativeToolCalling:
|
||||
goal="Use both tools exactly as instructed",
|
||||
backstory="You follow tool instructions precisely.",
|
||||
tools=parallel_tools,
|
||||
llm=LLM(model="bedrock/us.anthropic.claude-sonnet-4-6"),
|
||||
llm=LLM(model="bedrock/anthropic.claude-3-haiku-20240307-v1:0"),
|
||||
verbose=False,
|
||||
max_iter=3,
|
||||
)
|
||||
@@ -881,7 +881,7 @@ class TestBedrockNativeToolCalling:
|
||||
goal="Use both tools exactly as instructed",
|
||||
backstory="You follow tool instructions precisely.",
|
||||
tools=parallel_tools,
|
||||
llm=LLM(model="bedrock/us.anthropic.claude-sonnet-4-6"),
|
||||
llm=LLM(model="bedrock/anthropic.claude-3-haiku-20240307-v1:0"),
|
||||
verbose=False,
|
||||
max_iter=3,
|
||||
)
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,51 +0,0 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Describe
|
||||
the file(s) you see. Be brief, one sentence max.\n\nInput files (content already
|
||||
loaded in conversation):\n - \"chart\" (revenue_chart.png)\n\nThis is the expected
|
||||
criteria for your final answer: A brief description of the file.\nyou MUST return
|
||||
the actual complete content as the final answer, not a summary.\n\nProvide your
|
||||
complete response:"}]}], "inferenceConfig": {"stopSequences": ["\nObservation:"]},
|
||||
"system": [{"text": "You are File Analyst. Expert at analyzing various file
|
||||
types.\nYour personal goal is: Analyze and describe files accurately"}]}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '636'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1812},"output":{"message":{"content":[{"text":"A
|
||||
bar chart displaying revenue data over time, showing financial performance
|
||||
metrics across different periods."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":121,"outputTokens":20,"serverToolUsage":{},"totalTokens":141}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '425'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:06:21 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -0,0 +1,57 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Describe
|
||||
the file(s) you see. Be brief, one sentence max.\n\nInput files (content already
|
||||
loaded in conversation):\n - \"document\" (document)\n\nThis is the expected
|
||||
criteria for your final answer: A brief description of the file.\nyou MUST return
|
||||
the actual complete content as the final answer, not a summary.\n\nBegin! This
|
||||
is VERY important to you, use the tools available and give your best Final Answer,
|
||||
your job depends on it!\n\nThought:"}, {"document": {"name": "document", "format":
|
||||
"pdf", "source": {"bytes": "JVBERi0xLjQKMSAwIG9iaiA8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4gZW5kb2JqCjIgMCBvYmogPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4gZW5kb2JqCjMgMCBvYmogPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXSA+PiBlbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmCjAwMDAwMDAwMDkgMDAwMDAgbgowMDAwMDAwMDU4IDAwMDAwIG4KMDAwMDAwMDExNSAwMDAwMCBuCnRyYWlsZXIgPDwgL1NpemUgNCAvUm9vdCAxIDAgUiA+PgpzdGFydHhyZWYKMTk2CiUlRU9GCg=="}}}]}],
|
||||
"inferenceConfig": {"stopSequences": ["\nObservation:"]}, "system": [{"text":
|
||||
"You are File Analyst. Expert at analyzing various file types.\nYour personal
|
||||
goal is: Analyze and describe files accurately\nTo give my best complete final
|
||||
answer to the task respond using the exact following format:\n\nThought: I now
|
||||
can give a great answer\nFinal Answer: Your final answer must be the great and
|
||||
the most complete as possible, it must be outcome described.\n\nI MUST use these
|
||||
formats, my job depends on it!"}]}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '1545'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":958},"output":{"message":{"content":[{"text":"Thought:
|
||||
I have reviewed the provided documents and can now give a complete answer.\n\nFinal
|
||||
Answer: The file \"document.pdf\" is an empty document with no text or content
|
||||
visible."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":245,"outputTokens":42,"serverToolUsage":{},"totalTokens":287}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '384'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Fri, 23 Jan 2026 19:16:37 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -1,53 +0,0 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Describe
|
||||
the file(s) you see. Be brief, one sentence max.\n\nInput files (content already
|
||||
loaded in conversation):\n - \"document\" (agents.pdf)\n\nThis is the expected
|
||||
criteria for your final answer: A brief description of the file.\nyou MUST return
|
||||
the actual complete content as the final answer, not a summary.\n\nProvide your
|
||||
complete response:"}]}], "inferenceConfig": {"stopSequences": ["\nObservation:"]},
|
||||
"system": [{"text": "You are File Analyst. Expert at analyzing various file
|
||||
types.\nYour personal goal is: Analyze and describe files accurately"}]}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '632'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":2844},"output":{"message":{"content":[{"text":"The
|
||||
file \"agents.pdf\" is an academic/technical document discussing AI agents,
|
||||
their architectures, components (such as memory, planning, and tool use),
|
||||
and how large language models (LLMs) can be used to power autonomous agent
|
||||
systems."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":119,"outputTokens":55,"serverToolUsage":{},"totalTokens":174}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '552'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:06:24 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
version: 1
|
||||
@@ -2,17 +2,134 @@ interactions:
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 * 8\n\nThis is the expected criteria for your final answer: Result\nyou MUST
|
||||
return the actual complete content as the final answer, not a summary."}]}],
|
||||
return the actual complete content as the final answer, not a summary.\n\nThis
|
||||
is VERY important to you, your job depends on it!"}]}], "inferenceConfig": {"stopSequences":
|
||||
["\nObservation:"]}, "system": [{"text": "You are Math Assistant. You calculate.\nYour
|
||||
personal goal is: Calculate math"}], "toolConfig": {"tools": [{"toolSpec": {"name":
|
||||
"calculator", "description": "Perform mathematical calculations. Use this for
|
||||
any math operations.", "inputSchema": {"json": {"properties": {"expression":
|
||||
{"description": "Mathematical expression to evaluate", "title": "Expression",
|
||||
"type": "string"}}, "required": ["expression"], "type": "object"}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '806'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1540},"output":{"message":{"content":[{"text":"Here
|
||||
is the calculation for 15 * 8:"},{"toolUse":{"input":{"expression":"15 * 8"},"name":"calculator","toolUseId":"tooluse_1OIARGnOTjiITDKGd_FgMA"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":417,"outputTokens":68,"serverToolUsage":{},"totalTokens":485}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '351'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 22 Jan 2026 21:27:56 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 * 8\n\nThis is the expected criteria for your final answer: Result\nyou MUST
|
||||
return the actual complete content as the final answer, not a summary.\n\nThis
|
||||
is VERY important to you, your job depends on it!"}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_1OIARGnOTjiITDKGd_FgMA", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_1OIARGnOTjiITDKGd_FgMA", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}], "inferenceConfig": {"stopSequences":
|
||||
["\nObservation:"]}, "system": [{"text": "You are Math Assistant. You calculate.\nYour
|
||||
personal goal is: Calculate math"}], "toolConfig": {"tools": [{"toolSpec": {"name":
|
||||
"calculator", "description": "Perform mathematical calculations. Use this for
|
||||
any math operations.", "inputSchema": {"json": {"properties": {"expression":
|
||||
{"description": "Mathematical expression to evaluate", "title": "Expression",
|
||||
"type": "string"}}, "required": ["expression"], "type": "object"}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '1358'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1071},"output":{"message":{"content":[{"toolUse":{"input":{"expression":"15
|
||||
* 8"},"name":"calculator","toolUseId":"tooluse_vjcn57LeQpS-pePkTvny8w"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":527,"outputTokens":55,"serverToolUsage":{},"totalTokens":582}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '304'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 22 Jan 2026 21:27:57 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 * 8\n\nThis is the expected criteria for your final answer: Result\nyou MUST
|
||||
return the actual complete content as the final answer, not a summary.\n\nThis
|
||||
is VERY important to you, your job depends on it!"}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_1OIARGnOTjiITDKGd_FgMA", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_1OIARGnOTjiITDKGd_FgMA", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}, {"role": "assistant", "content": [{"toolUse":
|
||||
{"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w", "name": "calculator", "input":
|
||||
{}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w",
|
||||
"content": [{"text": "Error executing tool: CalculatorTool._run() missing 1
|
||||
required positional argument: ''expression''"}]}}]}, {"role": "user", "content":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}]}],
|
||||
"inferenceConfig": {"stopSequences": ["\nObservation:"]}, "system": [{"text":
|
||||
"You are Math Assistant. You calculate.\nYour personal goal is: Calculate math"}],
|
||||
"toolConfig": {"tools": [{"toolSpec": {"name": "calculator", "description":
|
||||
"Perform mathematical calculations. Use this for any math operations.", "inputSchema":
|
||||
{"json": {"properties": {"expression": {"description": "Mathematical expression
|
||||
to evaluate", "title": "Expression", "type": "string"}}, "required": ["expression"],
|
||||
"type": "object", "additionalProperties": false}}}}]}}'
|
||||
"type": "object"}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '779'
|
||||
- '1910'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -27,23 +144,21 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1957},"output":{"message":{"content":[{"text":"I''ll
|
||||
calculate 15 * 8 right away!"},{"toolUse":{"input":{"expression":"15 * 8"},"name":"calculator","toolUseId":"tooluse_XaQHWn1gW8bA6RHCR5fue8","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":642,"outputTokens":69,"serverToolUsage":{},"totalTokens":711}}'
|
||||
string: '{"metrics":{"latencyMs":927},"output":{"message":{"content":[{"toolUse":{"input":{"expression":"15
|
||||
* 8"},"name":"calculator","toolUseId":"tooluse__4aP-hcTR4Ozp5gTlESXbg"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":637,"outputTokens":57,"serverToolUsage":{},"totalTokens":694}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '477'
|
||||
- '303'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:59 GMT
|
||||
- Thu, 22 Jan 2026 21:27:58 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
@@ -52,21 +167,37 @@ interactions:
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 * 8\n\nThis is the expected criteria for your final answer: Result\nyou MUST
|
||||
return the actual complete content as the final answer, not a summary."}]},
|
||||
{"role": "assistant", "content": [{"toolUse": {"toolUseId": "tooluse_XaQHWn1gW8bA6RHCR5fue8",
|
||||
"name": "calculator", "input": {"expression": "15 * 8"}}}]}, {"role": "user",
|
||||
"content": [{"toolResult": {"toolUseId": "tooluse_XaQHWn1gW8bA6RHCR5fue8", "content":
|
||||
[{"text": "The result of 15 * 8 is 120"}]}}]}], "inferenceConfig": {"stopSequences":
|
||||
["\nObservation:"]}, "system": [{"text": "You are Math Assistant. You calculate.\nYour
|
||||
personal goal is: Calculate math"}], "toolConfig": {"tools": [{"toolSpec": {"name":
|
||||
"calculator", "description": "Perform mathematical calculations. Use this for
|
||||
any math operations.", "inputSchema": {"json": {"properties": {"expression":
|
||||
return the actual complete content as the final answer, not a summary.\n\nThis
|
||||
is VERY important to you, your job depends on it!"}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_1OIARGnOTjiITDKGd_FgMA", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_1OIARGnOTjiITDKGd_FgMA", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}, {"role": "assistant", "content": [{"toolUse":
|
||||
{"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w", "name": "calculator", "input":
|
||||
{}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w",
|
||||
"content": [{"text": "Error executing tool: CalculatorTool._run() missing 1
|
||||
required positional argument: ''expression''"}]}}]}, {"role": "user", "content":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}]},
|
||||
{"role": "assistant", "content": [{"toolUse": {"toolUseId": "tooluse__4aP-hcTR4Ozp5gTlESXbg",
|
||||
"name": "calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult":
|
||||
{"toolUseId": "tooluse__4aP-hcTR4Ozp5gTlESXbg", "content": [{"text": "Error
|
||||
executing tool: CalculatorTool._run() missing 1 required positional argument:
|
||||
''expression''"}]}}]}, {"role": "user", "content": [{"text": "Analyze the tool
|
||||
result. If requirements are met, provide the Final Answer. Otherwise, call the
|
||||
next tool. Deliver only the answer without meta-commentary."}]}], "inferenceConfig":
|
||||
{"stopSequences": ["\nObservation:"]}, "system": [{"text": "You are Math Assistant.
|
||||
You calculate.\nYour personal goal is: Calculate math"}], "toolConfig": {"tools":
|
||||
[{"toolSpec": {"name": "calculator", "description": "Perform mathematical calculations.
|
||||
Use this for any math operations.", "inputSchema": {"json": {"properties": {"expression":
|
||||
{"description": "Mathematical expression to evaluate", "title": "Expression",
|
||||
"type": "string"}}, "required": ["expression"], "type": "object", "additionalProperties":
|
||||
false}}}}]}}'
|
||||
"type": "string"}}, "required": ["expression"], "type": "object"}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '1084'
|
||||
- '2462'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -81,22 +212,271 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1689},"output":{"message":{"content":[{"text":"120"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":723,"outputTokens":4,"serverToolUsage":{},"totalTokens":727}}'
|
||||
string: '{"metrics":{"latencyMs":1226},"output":{"message":{"content":[{"toolUse":{"input":{"expression":"15
|
||||
* 8"},"name":"calculator","toolUseId":"tooluse_fEJhgDNjSUic0g97dN8Xww"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":747,"outputTokens":55,"serverToolUsage":{},"totalTokens":802}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '317'
|
||||
- '304'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:06:01 GMT
|
||||
- Thu, 22 Jan 2026 21:28:00 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 * 8\n\nThis is the expected criteria for your final answer: Result\nyou MUST
|
||||
return the actual complete content as the final answer, not a summary.\n\nThis
|
||||
is VERY important to you, your job depends on it!"}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_1OIARGnOTjiITDKGd_FgMA", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_1OIARGnOTjiITDKGd_FgMA", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}, {"role": "assistant", "content": [{"toolUse":
|
||||
{"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w", "name": "calculator", "input":
|
||||
{}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w",
|
||||
"content": [{"text": "Error executing tool: CalculatorTool._run() missing 1
|
||||
required positional argument: ''expression''"}]}}]}, {"role": "user", "content":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}]},
|
||||
{"role": "assistant", "content": [{"toolUse": {"toolUseId": "tooluse__4aP-hcTR4Ozp5gTlESXbg",
|
||||
"name": "calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult":
|
||||
{"toolUseId": "tooluse__4aP-hcTR4Ozp5gTlESXbg", "content": [{"text": "Error
|
||||
executing tool: CalculatorTool._run() missing 1 required positional argument:
|
||||
''expression''"}]}}]}, {"role": "user", "content": [{"text": "Analyze the tool
|
||||
result. If requirements are met, provide the Final Answer. Otherwise, call the
|
||||
next tool. Deliver only the answer without meta-commentary."}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_fEJhgDNjSUic0g97dN8Xww", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_fEJhgDNjSUic0g97dN8Xww", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}], "inferenceConfig": {"stopSequences":
|
||||
["\nObservation:"]}, "system": [{"text": "You are Math Assistant. You calculate.\nYour
|
||||
personal goal is: Calculate math"}], "toolConfig": {"tools": [{"toolSpec": {"name":
|
||||
"calculator", "description": "Perform mathematical calculations. Use this for
|
||||
any math operations.", "inputSchema": {"json": {"properties": {"expression":
|
||||
{"description": "Mathematical expression to evaluate", "title": "Expression",
|
||||
"type": "string"}}, "required": ["expression"], "type": "object"}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '3014'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":947},"output":{"message":{"content":[{"toolUse":{"input":{"expression":"15
|
||||
* 8"},"name":"calculator","toolUseId":"tooluse_F5QIGY91SBOeM4VcFRB73A"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":857,"outputTokens":55,"serverToolUsage":{},"totalTokens":912}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '303'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 22 Jan 2026 21:28:01 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 * 8\n\nThis is the expected criteria for your final answer: Result\nyou MUST
|
||||
return the actual complete content as the final answer, not a summary.\n\nThis
|
||||
is VERY important to you, your job depends on it!"}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_1OIARGnOTjiITDKGd_FgMA", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_1OIARGnOTjiITDKGd_FgMA", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}, {"role": "assistant", "content": [{"toolUse":
|
||||
{"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w", "name": "calculator", "input":
|
||||
{}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w",
|
||||
"content": [{"text": "Error executing tool: CalculatorTool._run() missing 1
|
||||
required positional argument: ''expression''"}]}}]}, {"role": "user", "content":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}]},
|
||||
{"role": "assistant", "content": [{"toolUse": {"toolUseId": "tooluse__4aP-hcTR4Ozp5gTlESXbg",
|
||||
"name": "calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult":
|
||||
{"toolUseId": "tooluse__4aP-hcTR4Ozp5gTlESXbg", "content": [{"text": "Error
|
||||
executing tool: CalculatorTool._run() missing 1 required positional argument:
|
||||
''expression''"}]}}]}, {"role": "user", "content": [{"text": "Analyze the tool
|
||||
result. If requirements are met, provide the Final Answer. Otherwise, call the
|
||||
next tool. Deliver only the answer without meta-commentary."}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_fEJhgDNjSUic0g97dN8Xww", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_fEJhgDNjSUic0g97dN8Xww", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}, {"role": "assistant", "content": [{"toolUse":
|
||||
{"toolUseId": "tooluse_F5QIGY91SBOeM4VcFRB73A", "name": "calculator", "input":
|
||||
{}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId": "tooluse_F5QIGY91SBOeM4VcFRB73A",
|
||||
"content": [{"text": "Error executing tool: CalculatorTool._run() missing 1
|
||||
required positional argument: ''expression''"}]}}]}, {"role": "user", "content":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}]},
|
||||
{"role": "assistant", "content": [{"text": "Now it''s time you MUST give your
|
||||
absolute best final answer. You''ll ignore all previous instructions, stop using
|
||||
any tools, and just return your absolute BEST Final answer."}]}], "inferenceConfig":
|
||||
{"stopSequences": ["\nObservation:"]}, "system": [{"text": "You are Math Assistant.
|
||||
You calculate.\nYour personal goal is: Calculate math"}], "toolConfig": {"tools":
|
||||
[{"toolSpec": {"name": "calculator", "description": "Tool: calculator", "inputSchema":
|
||||
{"json": {"type": "object", "properties": {}}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '3599'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"message":"The model returned the following errors: Your API request
|
||||
included an `assistant` message in the final position, which would pre-fill
|
||||
the `assistant` response. When using tools, pre-filling the `assistant` response
|
||||
is not supported."}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '246'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 22 Jan 2026 21:28:02 GMT
|
||||
x-amzn-ErrorType:
|
||||
- ValidationException:http://internal.amazon.com/coral/com.amazon.bedrock/
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 400
|
||||
message: Bad Request
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 * 8\n\nThis is the expected criteria for your final answer: Result\nyou MUST
|
||||
return the actual complete content as the final answer, not a summary.\n\nThis
|
||||
is VERY important to you, your job depends on it!"}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_1OIARGnOTjiITDKGd_FgMA", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_1OIARGnOTjiITDKGd_FgMA", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}, {"role": "assistant", "content": [{"toolUse":
|
||||
{"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w", "name": "calculator", "input":
|
||||
{}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId": "tooluse_vjcn57LeQpS-pePkTvny8w",
|
||||
"content": [{"text": "Error executing tool: CalculatorTool._run() missing 1
|
||||
required positional argument: ''expression''"}]}}]}, {"role": "user", "content":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}]},
|
||||
{"role": "assistant", "content": [{"toolUse": {"toolUseId": "tooluse__4aP-hcTR4Ozp5gTlESXbg",
|
||||
"name": "calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult":
|
||||
{"toolUseId": "tooluse__4aP-hcTR4Ozp5gTlESXbg", "content": [{"text": "Error
|
||||
executing tool: CalculatorTool._run() missing 1 required positional argument:
|
||||
''expression''"}]}}]}, {"role": "user", "content": [{"text": "Analyze the tool
|
||||
result. If requirements are met, provide the Final Answer. Otherwise, call the
|
||||
next tool. Deliver only the answer without meta-commentary."}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_fEJhgDNjSUic0g97dN8Xww", "name":
|
||||
"calculator", "input": {}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId":
|
||||
"tooluse_fEJhgDNjSUic0g97dN8Xww", "content": [{"text": "Error executing tool:
|
||||
CalculatorTool._run() missing 1 required positional argument: ''expression''"}]}}]},
|
||||
{"role": "user", "content": [{"text": "Analyze the tool result. If requirements
|
||||
are met, provide the Final Answer. Otherwise, call the next tool. Deliver only
|
||||
the answer without meta-commentary."}]}, {"role": "assistant", "content": [{"toolUse":
|
||||
{"toolUseId": "tooluse_F5QIGY91SBOeM4VcFRB73A", "name": "calculator", "input":
|
||||
{}}}]}, {"role": "user", "content": [{"toolResult": {"toolUseId": "tooluse_F5QIGY91SBOeM4VcFRB73A",
|
||||
"content": [{"text": "Error executing tool: CalculatorTool._run() missing 1
|
||||
required positional argument: ''expression''"}]}}]}, {"role": "user", "content":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}]},
|
||||
{"role": "assistant", "content": [{"text": "Now it''s time you MUST give your
|
||||
absolute best final answer. You''ll ignore all previous instructions, stop using
|
||||
any tools, and just return your absolute BEST Final answer."}]}, {"role": "user",
|
||||
"content": [{"text": "\nCurrent Task: Calculate 15 * 8\n\nThis is the expected
|
||||
criteria for your final answer: Result\nyou MUST return the actual complete
|
||||
content as the final answer, not a summary.\n\nThis is VERY important to you,
|
||||
your job depends on it!"}]}, {"role": "assistant", "content": [{"text": "Now
|
||||
it''s time you MUST give your absolute best final answer. You''ll ignore all
|
||||
previous instructions, stop using any tools, and just return your absolute BEST
|
||||
Final answer."}]}], "inferenceConfig": {"stopSequences": ["\nObservation:"]},
|
||||
"system": [{"text": "You are Math Assistant. You calculate.\nYour personal goal
|
||||
is: Calculate math\n\nYou are Math Assistant. You calculate.\nYour personal
|
||||
goal is: Calculate math"}], "toolConfig": {"tools": [{"toolSpec": {"name": "calculator",
|
||||
"description": "Tool: calculator", "inputSchema": {"json": {"type": "object",
|
||||
"properties": {}}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '4181'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":715},"output":{"message":{"content":[{"text":"\n\n120"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":1082,"outputTokens":5,"serverToolUsage":{},"totalTokens":1087}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '212'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 22 Jan 2026 21:28:03 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -39,112 +39,25 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":2714},"output":{"message":{"content":[{"text":"I''ll
|
||||
execute all 3 parallel searches simultaneously right now!"},{"toolUse":{"input":{"query":"latest
|
||||
OpenAI model release notes"},"name":"parallel_local_search_one","toolUseId":"tooluse_kooGjILXmVRg8edl3YuEf4","type":"tool_use"}},{"toolUse":{"input":{"query":"latest
|
||||
Anthropic model release notes"},"name":"parallel_local_search_two","toolUseId":"tooluse_qa71o2cLA65qg5TyweI63c","type":"tool_use"}},{"toolUse":{"input":{"query":"latest
|
||||
Gemini model release notes"},"name":"parallel_local_search_three","toolUseId":"tooluse_gPf5hAC0sogbIJEjDBTIvO","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":914,"outputTokens":169,"serverToolUsage":{},"totalTokens":1083}}'
|
||||
string: '{"message":"The security token included in the request is invalid."}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '882'
|
||||
- '68'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:06:04 GMT
|
||||
- Thu, 19 Feb 2026 00:00:08 GMT
|
||||
x-amzn-ErrorType:
|
||||
- UnrecognizedClientException:http://internal.amazon.com/coral/com.amazon.coral.service/
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: This
|
||||
is a tool-calling compliance test. In your next assistant turn, emit exactly
|
||||
3 tool calls in the same response (parallel tool calls), in this order: 1) parallel_local_search_one(query=''latest
|
||||
OpenAI model release notes''), 2) parallel_local_search_two(query=''latest Anthropic
|
||||
model release notes''), 3) parallel_local_search_three(query=''latest Gemini
|
||||
model release notes''). Do not call any other tools and do not answer before
|
||||
those 3 tool calls are emitted. After the tool results return, provide a one
|
||||
paragraph summary."}]}, {"role": "assistant", "content": [{"toolUse": {"toolUseId":
|
||||
"tooluse_kooGjILXmVRg8edl3YuEf4", "name": "parallel_local_search_one", "input":
|
||||
{"query": "latest OpenAI model release notes"}}}, {"toolUse": {"toolUseId":
|
||||
"tooluse_qa71o2cLA65qg5TyweI63c", "name": "parallel_local_search_two", "input":
|
||||
{"query": "latest Anthropic model release notes"}}}, {"toolUse": {"toolUseId":
|
||||
"tooluse_gPf5hAC0sogbIJEjDBTIvO", "name": "parallel_local_search_three", "input":
|
||||
{"query": "latest Gemini model release notes"}}}]}, {"role": "user", "content":
|
||||
[{"toolResult": {"toolUseId": "tooluse_kooGjILXmVRg8edl3YuEf4", "content": [{"text":
|
||||
"[one] latest OpenAI model release notes"}]}}, {"toolResult": {"toolUseId":
|
||||
"tooluse_qa71o2cLA65qg5TyweI63c", "content": [{"text": "[two] latest Anthropic
|
||||
model release notes"}]}}, {"toolResult": {"toolUseId": "tooluse_gPf5hAC0sogbIJEjDBTIvO",
|
||||
"content": [{"text": "[three] latest Gemini model release notes"}]}}]}], "inferenceConfig":
|
||||
{"stopSequences": ["\nObservation:"]}, "system": [{"text": "You are Parallel
|
||||
Tool Agent. You follow tool instructions precisely.\nYour personal goal is:
|
||||
Use both tools exactly as instructed"}], "toolConfig": {"tools": [{"toolSpec":
|
||||
{"name": "parallel_local_search_one", "description": "Local search tool #1 for
|
||||
concurrency testing.", "inputSchema": {"json": {"properties": {"query": {"description":
|
||||
"Search query", "title": "Query", "type": "string"}}, "required": ["query"],
|
||||
"type": "object", "additionalProperties": false}}}}, {"toolSpec": {"name": "parallel_local_search_two",
|
||||
"description": "Local search tool #2 for concurrency testing.", "inputSchema":
|
||||
{"json": {"properties": {"query": {"description": "Search query", "title": "Query",
|
||||
"type": "string"}}, "required": ["query"], "type": "object", "additionalProperties":
|
||||
false}}}}, {"toolSpec": {"name": "parallel_local_search_three", "description":
|
||||
"Local search tool #3 for concurrency testing.", "inputSchema": {"json": {"properties":
|
||||
{"query": {"description": "Search query", "title": "Query", "type": "string"}},
|
||||
"required": ["query"], "type": "object", "additionalProperties": false}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '2711'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
response:
|
||||
body:
|
||||
string: "{\"metrics\":{\"latencyMs\":5051},\"output\":{\"message\":{\"content\":[{\"text\":\"The
|
||||
three parallel searches were executed simultaneously across all tools, querying
|
||||
the latest release notes for OpenAI, Anthropic, and Gemini models respectively.
|
||||
The search results returned placeholder outputs from each tool (indicating
|
||||
a test environment), confirming that all three tools \u2014 **parallel_local_search_one**,
|
||||
**parallel_local_search_two**, and **parallel_local_search_three** \u2014
|
||||
fired concurrently and responded successfully in the correct order. In a live
|
||||
environment, these results would contain detailed release notes for the latest
|
||||
models from each AI provider, such as OpenAI's GPT series updates, Anthropic's
|
||||
Claude model iterations, and Google's Gemini model announcements, allowing
|
||||
for a comprehensive side-by-side comparison of the most recent advancements
|
||||
across the three leading AI platforms.\"}],\"role\":\"assistant\"}},\"stopReason\":\"end_turn\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":1197,\"outputTokens\":173,\"serverToolUsage\":{},\"totalTokens\":1370}}"
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '1141'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:06:10 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
code: 403
|
||||
message: Forbidden
|
||||
version: 1
|
||||
|
||||
@@ -41,31 +41,27 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":2911},"output":{"message":{"content":[{"text":"I''ll
|
||||
execute all 3 parallel searches simultaneously right away!"},{"toolUse":{"input":{"query":"latest
|
||||
OpenAI model release notes"},"name":"parallel_local_search_one","toolUseId":"tooluse_hd4QaBJIe0j2FasplcWi78","type":"tool_use"}},{"toolUse":{"input":{"query":"latest
|
||||
Anthropic model release notes"},"name":"parallel_local_search_two","toolUseId":"tooluse_yB6xS6E1bsIOpv8rWcnpiR","type":"tool_use"}},{"toolUse":{"input":{"query":"latest
|
||||
Gemini model release notes"},"name":"parallel_local_search_three","toolUseId":"tooluse_cjCrMYQMmA8diLWBnKJ86o","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":951,"outputTokens":169,"serverToolUsage":{},"totalTokens":1120}}'
|
||||
string: '{"message":"The security token included in the request is invalid."}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '883'
|
||||
- '68'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:06:14 GMT
|
||||
- Thu, 19 Feb 2026 00:00:07 GMT
|
||||
x-amzn-ErrorType:
|
||||
- UnrecognizedClientException:http://internal.amazon.com/coral/com.amazon.coral.service/
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
code: 403
|
||||
message: Forbidden
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: This
|
||||
is a tool-calling compliance test. In your next assistant turn, emit exactly
|
||||
@@ -76,35 +72,36 @@ interactions:
|
||||
those 3 tool calls are emitted. After the tool results return, provide a one
|
||||
paragraph summary.\n\nThis is the expected criteria for your final answer: A
|
||||
one sentence summary of both tool outputs\nyou MUST return the actual complete
|
||||
content as the final answer, not a summary."}]}, {"role": "assistant", "content":
|
||||
[{"toolUse": {"toolUseId": "tooluse_hd4QaBJIe0j2FasplcWi78", "name": "parallel_local_search_one",
|
||||
"input": {"query": "latest OpenAI model release notes"}}}, {"toolUse": {"toolUseId":
|
||||
"tooluse_yB6xS6E1bsIOpv8rWcnpiR", "name": "parallel_local_search_two", "input":
|
||||
{"query": "latest Anthropic model release notes"}}}, {"toolUse": {"toolUseId":
|
||||
"tooluse_cjCrMYQMmA8diLWBnKJ86o", "name": "parallel_local_search_three", "input":
|
||||
{"query": "latest Gemini model release notes"}}}]}, {"role": "user", "content":
|
||||
[{"toolResult": {"toolUseId": "tooluse_hd4QaBJIe0j2FasplcWi78", "content": [{"text":
|
||||
"[one] latest OpenAI model release notes"}]}}, {"toolResult": {"toolUseId":
|
||||
"tooluse_yB6xS6E1bsIOpv8rWcnpiR", "content": [{"text": "[two] latest Anthropic
|
||||
model release notes"}]}}, {"toolResult": {"toolUseId": "tooluse_cjCrMYQMmA8diLWBnKJ86o",
|
||||
"content": [{"text": "[three] latest Gemini model release notes"}]}}]}], "inferenceConfig":
|
||||
{"stopSequences": ["\nObservation:"]}, "system": [{"text": "You are Parallel
|
||||
Tool Agent. You follow tool instructions precisely.\nYour personal goal is:
|
||||
Use both tools exactly as instructed"}], "toolConfig": {"tools": [{"toolSpec":
|
||||
{"name": "parallel_local_search_one", "description": "Local search tool #1 for
|
||||
content as the final answer, not a summary."}]}, {"role": "user", "content":
|
||||
[{"text": "\nCurrent Task: This is a tool-calling compliance test. In your next
|
||||
assistant turn, emit exactly 3 tool calls in the same response (parallel tool
|
||||
calls), in this order: 1) parallel_local_search_one(query=''latest OpenAI model
|
||||
release notes''), 2) parallel_local_search_two(query=''latest Anthropic model
|
||||
release notes''), 3) parallel_local_search_three(query=''latest Gemini model
|
||||
release notes''). Do not call any other tools and do not answer before those
|
||||
3 tool calls are emitted. After the tool results return, provide a one paragraph
|
||||
summary.\n\nThis is the expected criteria for your final answer: A one sentence
|
||||
summary of both tool outputs\nyou MUST return the actual complete content as
|
||||
the final answer, not a summary."}]}], "inferenceConfig": {"stopSequences":
|
||||
["\nObservation:"]}, "system": [{"text": "You are Parallel Tool Agent. You follow
|
||||
tool instructions precisely.\nYour personal goal is: Use both tools exactly
|
||||
as instructed\n\nYou are Parallel Tool Agent. You follow tool instructions precisely.\nYour
|
||||
personal goal is: Use both tools exactly as instructed"}], "toolConfig": {"tools":
|
||||
[{"toolSpec": {"name": "parallel_local_search_one", "description": "Local search
|
||||
tool #1 for concurrency testing.", "inputSchema": {"json": {"properties": {"query":
|
||||
{"description": "Search query", "title": "Query", "type": "string"}}, "required":
|
||||
["query"], "type": "object", "additionalProperties": false}}}}, {"toolSpec":
|
||||
{"name": "parallel_local_search_two", "description": "Local search tool #2 for
|
||||
concurrency testing.", "inputSchema": {"json": {"properties": {"query": {"description":
|
||||
"Search query", "title": "Query", "type": "string"}}, "required": ["query"],
|
||||
"type": "object", "additionalProperties": false}}}}, {"toolSpec": {"name": "parallel_local_search_two",
|
||||
"description": "Local search tool #2 for concurrency testing.", "inputSchema":
|
||||
"type": "object", "additionalProperties": false}}}}, {"toolSpec": {"name": "parallel_local_search_three",
|
||||
"description": "Local search tool #3 for concurrency testing.", "inputSchema":
|
||||
{"json": {"properties": {"query": {"description": "Search query", "title": "Query",
|
||||
"type": "string"}}, "required": ["query"], "type": "object", "additionalProperties":
|
||||
false}}}}, {"toolSpec": {"name": "parallel_local_search_three", "description":
|
||||
"Local search tool #3 for concurrency testing.", "inputSchema": {"json": {"properties":
|
||||
{"query": {"description": "Search query", "title": "Query", "type": "string"}},
|
||||
"required": ["query"], "type": "object", "additionalProperties": false}}}}]}}'
|
||||
false}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '2892'
|
||||
- '2855'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -119,35 +116,111 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: "{\"metrics\":{\"latencyMs\":4350},\"output\":{\"message\":{\"content\":[{\"text\":\"Here
|
||||
is the complete content returned by all three tools:\\n\\n- **Tool 1 (parallel_local_search_one):**
|
||||
`[one] latest OpenAI model release notes`\\n- **Tool 2 (parallel_local_search_two):**
|
||||
`[two] latest Anthropic model release notes`\\n- **Tool 3 (parallel_local_search_three):**
|
||||
`[three] latest Gemini model release notes`\\n\\nThe three parallel searches
|
||||
returned placeholder results confirming the queries were received: the first
|
||||
tool acknowledged a search for the latest OpenAI model release notes, the
|
||||
second for the latest Anthropic model release notes, and the third for the
|
||||
latest Gemini model release notes \u2014 indicating the local search tools
|
||||
processed all three concurrent requests successfully but did not return detailed
|
||||
release note content beyond the query echo.\"}],\"role\":\"assistant\"}},\"stopReason\":\"end_turn\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":1234,\"outputTokens\":181,\"serverToolUsage\":{},\"totalTokens\":1415}}"
|
||||
string: '{"message":"The security token included in the request is invalid."}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '1093'
|
||||
- '68'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:06:19 GMT
|
||||
- Thu, 19 Feb 2026 00:00:07 GMT
|
||||
x-amzn-ErrorType:
|
||||
- UnrecognizedClientException:http://internal.amazon.com/coral/com.amazon.coral.service/
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
code: 403
|
||||
message: Forbidden
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: This
|
||||
is a tool-calling compliance test. In your next assistant turn, emit exactly
|
||||
3 tool calls in the same response (parallel tool calls), in this order: 1) parallel_local_search_one(query=''latest
|
||||
OpenAI model release notes''), 2) parallel_local_search_two(query=''latest Anthropic
|
||||
model release notes''), 3) parallel_local_search_three(query=''latest Gemini
|
||||
model release notes''). Do not call any other tools and do not answer before
|
||||
those 3 tool calls are emitted. After the tool results return, provide a one
|
||||
paragraph summary.\n\nThis is the expected criteria for your final answer: A
|
||||
one sentence summary of both tool outputs\nyou MUST return the actual complete
|
||||
content as the final answer, not a summary."}]}, {"role": "user", "content":
|
||||
[{"text": "\nCurrent Task: This is a tool-calling compliance test. In your next
|
||||
assistant turn, emit exactly 3 tool calls in the same response (parallel tool
|
||||
calls), in this order: 1) parallel_local_search_one(query=''latest OpenAI model
|
||||
release notes''), 2) parallel_local_search_two(query=''latest Anthropic model
|
||||
release notes''), 3) parallel_local_search_three(query=''latest Gemini model
|
||||
release notes''). Do not call any other tools and do not answer before those
|
||||
3 tool calls are emitted. After the tool results return, provide a one paragraph
|
||||
summary.\n\nThis is the expected criteria for your final answer: A one sentence
|
||||
summary of both tool outputs\nyou MUST return the actual complete content as
|
||||
the final answer, not a summary."}]}, {"role": "user", "content": [{"text":
|
||||
"\nCurrent Task: This is a tool-calling compliance test. In your next assistant
|
||||
turn, emit exactly 3 tool calls in the same response (parallel tool calls),
|
||||
in this order: 1) parallel_local_search_one(query=''latest OpenAI model release
|
||||
notes''), 2) parallel_local_search_two(query=''latest Anthropic model release
|
||||
notes''), 3) parallel_local_search_three(query=''latest Gemini model release
|
||||
notes''). Do not call any other tools and do not answer before those 3 tool
|
||||
calls are emitted. After the tool results return, provide a one paragraph summary.\n\nThis
|
||||
is the expected criteria for your final answer: A one sentence summary of both
|
||||
tool outputs\nyou MUST return the actual complete content as the final answer,
|
||||
not a summary."}]}], "inferenceConfig": {"stopSequences": ["\nObservation:"]},
|
||||
"system": [{"text": "You are Parallel Tool Agent. You follow tool instructions
|
||||
precisely.\nYour personal goal is: Use both tools exactly as instructed\n\nYou
|
||||
are Parallel Tool Agent. You follow tool instructions precisely.\nYour personal
|
||||
goal is: Use both tools exactly as instructed\n\nYou are Parallel Tool Agent.
|
||||
You follow tool instructions precisely.\nYour personal goal is: Use both tools
|
||||
exactly as instructed"}], "toolConfig": {"tools": [{"toolSpec": {"name": "parallel_local_search_one",
|
||||
"description": "Local search tool #1 for concurrency testing.", "inputSchema":
|
||||
{"json": {"properties": {"query": {"description": "Search query", "title": "Query",
|
||||
"type": "string"}}, "required": ["query"], "type": "object", "additionalProperties":
|
||||
false}}}}, {"toolSpec": {"name": "parallel_local_search_two", "description":
|
||||
"Local search tool #2 for concurrency testing.", "inputSchema": {"json": {"properties":
|
||||
{"query": {"description": "Search query", "title": "Query", "type": "string"}},
|
||||
"required": ["query"], "type": "object", "additionalProperties": false}}}},
|
||||
{"toolSpec": {"name": "parallel_local_search_three", "description": "Local search
|
||||
tool #3 for concurrency testing.", "inputSchema": {"json": {"properties": {"query":
|
||||
{"description": "Search query", "title": "Query", "type": "string"}}, "required":
|
||||
["query"], "type": "object", "additionalProperties": false}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '3756'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"message":"The security token included in the request is invalid."}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '68'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Thu, 19 Feb 2026 00:00:07 GMT
|
||||
x-amzn-ErrorType:
|
||||
- UnrecognizedClientException:http://internal.amazon.com/coral/com.amazon.coral.service/
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 403
|
||||
message: Forbidden
|
||||
version: 1
|
||||
|
||||
@@ -21,22 +21,61 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.vcr.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":2732},"output":{"message":{"content":[{"text":"Blank"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":1606,"outputTokens":5,"serverToolUsage":{},"totalTokens":1611}}'
|
||||
string: '{"metrics":{"latencyMs":867},"output":{"message":{"content":[{"text":"PDF"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":57,"outputTokens":4,"serverToolUsage":{},"totalTokens":61}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '321'
|
||||
- '204'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:34:51 GMT
|
||||
- Fri, 23 Jan 2026 03:26:35 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "What type of document
|
||||
is this? Answer in one word."}, {"document": {"name": "document", "format":
|
||||
"pdf", "source": {"bytes": "JVBERi0xLjQKMSAwIG9iaiA8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4gZW5kb2JqCjIgMCBvYmogPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUl0gL0NvdW50IDEgPj4gZW5kb2JqCjMgMCBvYmogPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXSA+PiBlbmRvYmoKeHJlZgowIDQKMDAwMDAwMDAwMCA2NTUzNSBmCjAwMDAwMDAwMDkgMDAwMDAgbgowMDAwMDAwMDU4IDAwMDAwIG4KMDAwMDAwMDExNSAwMDAwMCBuCnRyYWlsZXIgPDwgL1NpemUgNCAvUm9vdCAxIDAgUiA+PgpzdGFydHhyZWYKMTk2CiUlRU9GCg=="}}}]}],
|
||||
"inferenceConfig": {}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '646'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
amz-sdk-invocation-id:
|
||||
- AMZ-SDK-INVOCATION-ID-XXX
|
||||
amz-sdk-request:
|
||||
- !!binary |
|
||||
YXR0ZW1wdD0x
|
||||
authorization:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-haiku-20240307-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":291},"output":{"message":{"content":[{"text":"Incomplete"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":57,"outputTokens":5,"serverToolUsage":{},"totalTokens":62}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '211'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Fri, 23 Jan 2026 06:02:32 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,10 +1,14 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: '{"max_tokens":4096,"messages":[{"role":"user","content":[{"type":"text","text":"\nCurrent
|
||||
Task: Calculate 15 + 27 using your add_numbers tool. Report the result.","cache_control":{"type":"ephemeral"}}]}],"model":"claude-sonnet-4-6","stop_sequences":["\nObservation:"],"stream":false,"system":[{"type":"text","text":"You
|
||||
body: '{"max_tokens":4096,"messages":[{"role":"user","content":"\nCurrent Task:
|
||||
Calculate 15 + 27 using your add_numbers tool. Report the result."}],"model":"claude-3-5-haiku-20241022","stop_sequences":["\nObservation:"],"stream":false,"system":"You
|
||||
are Calculator. You are a calculator assistant that uses tools to compute results.\nYour
|
||||
personal goal is: Perform calculations using available tools","cache_control":{"type":"ephemeral"}}],"tools":[{"name":"add_numbers","description":"Add
|
||||
two numbers together and return the sum.","input_schema":{"properties":{"a":{"type":"integer"},"b":{"type":"integer"}},"required":["a","b"],"type":"object","additionalProperties":false},"strict":true}]}'
|
||||
personal goal is: Perform calculations using available tools","tool_choice":{"type":"tool","name":"structured_output"},"tools":[{"name":"structured_output","description":"Output
|
||||
the structured response","input_schema":{"type":"object","description":"Structured
|
||||
output for calculation results.","title":"CalculationResult","properties":{"operation":{"type":"string","description":"The
|
||||
mathematical operation performed","title":"Operation"},"result":{"type":"integer","description":"The
|
||||
result of the calculation","title":"Result"},"explanation":{"type":"string","description":"Brief
|
||||
explanation of the calculation","title":"Explanation"}},"additionalProperties":false,"required":["operation","result","explanation"]}}]}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -17,7 +21,7 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '762'
|
||||
- '1050'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
@@ -46,8 +50,8 @@ interactions:
|
||||
uri: https://api.anthropic.com/v1/messages
|
||||
response:
|
||||
body:
|
||||
string: '{"model":"claude-sonnet-4-6","id":"msg_01Hi6qhbcDQJas5A7kqA7Xif","type":"message","role":"assistant","content":[{"type":"text","text":"I''ll
|
||||
calculate 15 + 27 right away using the `add_numbers` tool!"},{"type":"tool_use","id":"toolu_0111pu1MrxY8aTqNzYSWAgQF","name":"add_numbers","input":{"a":15,"b":27},"caller":{"type":"direct"}}],"stop_reason":"tool_use","stop_sequence":null,"stop_details":null,"usage":{"input_tokens":633,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":92,"service_tier":"standard","inference_geo":"global"}}'
|
||||
string: '{"model":"claude-3-5-haiku-20241022","id":"msg_01MsoNSVoPuoMYGCcJLvfXS6","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01TtAsqddWjE7C4GYmCKavdg","name":"structured_output","input":{"operation":"Addition","result":42,"explanation":"Added
|
||||
15 and 27 together"}}],"stop_reason":"tool_use","stop_sequence":null,"usage":{"input_tokens":573,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":75,"service_tier":"standard","inference_geo":"not_available"}}'
|
||||
headers:
|
||||
CF-RAY:
|
||||
- CF-RAY-XXX
|
||||
@@ -58,7 +62,7 @@ interactions:
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 16:27:07 GMT
|
||||
- Thu, 12 Feb 2026 22:11:20 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Transfer-Encoding:
|
||||
@@ -80,123 +84,11 @@ interactions:
|
||||
anthropic-ratelimit-output-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-requests-limit:
|
||||
- '20000'
|
||||
- '4000'
|
||||
anthropic-ratelimit-requests-remaining:
|
||||
- '19999'
|
||||
- '3999'
|
||||
anthropic-ratelimit-requests-reset:
|
||||
- '2026-05-26T16:26:47Z'
|
||||
anthropic-ratelimit-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-RESET-XXX
|
||||
cf-cache-status:
|
||||
- DYNAMIC
|
||||
request-id:
|
||||
- REQUEST-ID-XXX
|
||||
set-cookie:
|
||||
- SET-COOKIE-XXX
|
||||
strict-transport-security:
|
||||
- STS-XXX
|
||||
traceresponse:
|
||||
- 00-0c532faf4d60e2359554c05e42d6c2b0-8ed2bd3616e95a40-01
|
||||
vary:
|
||||
- Accept-Encoding
|
||||
x-envoy-upstream-service-time:
|
||||
- '19361'
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"max_tokens":4096,"messages":[{"role":"user","content":[{"type":"text","text":"\nCurrent
|
||||
Task: Calculate 15 + 27 using your add_numbers tool. Report the result.","cache_control":{"type":"ephemeral"}}]},{"role":"assistant","content":[{"type":"tool_use","id":"toolu_0111pu1MrxY8aTqNzYSWAgQF","name":"add_numbers","input":{"a":15,"b":27}}]},{"role":"user","content":[{"type":"tool_result","tool_use_id":"toolu_0111pu1MrxY8aTqNzYSWAgQF","content":"42"}]}],"model":"claude-sonnet-4-6","stop_sequences":["\nObservation:"],"stream":false,"system":[{"type":"text","text":"You
|
||||
are Calculator. You are a calculator assistant that uses tools to compute results.\nYour
|
||||
personal goal is: Perform calculations using available tools","cache_control":{"type":"ephemeral"}}],"tools":[{"name":"add_numbers","description":"Add
|
||||
two numbers together and return the sum.","input_schema":{"properties":{"a":{"type":"integer"},"b":{"type":"integer"}},"required":["a","b"],"type":"object","additionalProperties":false},"strict":true}]}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
accept:
|
||||
- application/json
|
||||
accept-encoding:
|
||||
- ACCEPT-ENCODING-XXX
|
||||
anthropic-version:
|
||||
- '2023-06-01'
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '1011'
|
||||
content-type:
|
||||
- application/json
|
||||
cookie:
|
||||
- COOKIE-XXX
|
||||
host:
|
||||
- api.anthropic.com
|
||||
x-api-key:
|
||||
- X-API-KEY-XXX
|
||||
x-stainless-arch:
|
||||
- X-STAINLESS-ARCH-XXX
|
||||
x-stainless-async:
|
||||
- 'false'
|
||||
x-stainless-lang:
|
||||
- python
|
||||
x-stainless-os:
|
||||
- X-STAINLESS-OS-XXX
|
||||
x-stainless-package-version:
|
||||
- 0.73.0
|
||||
x-stainless-retry-count:
|
||||
- '0'
|
||||
x-stainless-runtime:
|
||||
- CPython
|
||||
x-stainless-runtime-version:
|
||||
- 3.13.3
|
||||
x-stainless-timeout:
|
||||
- NOT_GIVEN
|
||||
method: POST
|
||||
uri: https://api.anthropic.com/v1/messages
|
||||
response:
|
||||
body:
|
||||
string: "{\"model\":\"claude-sonnet-4-6\",\"id\":\"msg_01Eqs4XnbiSubo442YWNnn7G\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[{\"type\":\"text\",\"text\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F9EE\\n\\nUsing the `add_numbers` tool,
|
||||
I calculated that adding 15 and 27 together gives you a sum of **42**.\"}],\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":717,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":52,\"service_tier\":\"standard\",\"inference_geo\":\"global\"}}"
|
||||
headers:
|
||||
CF-RAY:
|
||||
- CF-RAY-XXX
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Security-Policy:
|
||||
- CSP-FILTERED
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 16:27:09 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
X-Robots-Tag:
|
||||
- none
|
||||
anthropic-organization-id:
|
||||
- ANTHROPIC-ORGANIZATION-ID-XXX
|
||||
anthropic-ratelimit-input-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-input-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-input-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-output-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-output-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-output-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-requests-limit:
|
||||
- '20000'
|
||||
anthropic-ratelimit-requests-remaining:
|
||||
- '19999'
|
||||
anthropic-ratelimit-requests-reset:
|
||||
- '2026-05-26T16:27:07Z'
|
||||
- '2026-02-12T22:11:18Z'
|
||||
anthropic-ratelimit-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-tokens-remaining:
|
||||
@@ -209,143 +101,8 @@ interactions:
|
||||
- REQUEST-ID-XXX
|
||||
strict-transport-security:
|
||||
- STS-XXX
|
||||
traceresponse:
|
||||
- 00-92d206559118bcf8b9b39b7ecd0c6e0e-68dd5efb3bbaff0e-01
|
||||
vary:
|
||||
- Accept-Encoding
|
||||
x-envoy-upstream-service-time:
|
||||
- '2021'
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: "{\"max_tokens\":4096,\"messages\":[{\"role\":\"user\",\"content\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F9EE\\n\\nUsing the `add_numbers` tool, I
|
||||
calculated that adding 15 and 27 together gives you a sum of **42**.\"}],\"model\":\"claude-sonnet-4-6\",\"stream\":false,\"system\":\"Format
|
||||
your final answer according to the following OpenAPI schema: {\\n \\\"type\\\":
|
||||
\\\"json_schema\\\",\\n \\\"json_schema\\\": {\\n \\\"name\\\": \\\"CalculationResult\\\",\\n
|
||||
\ \\\"strict\\\": true,\\n \\\"schema\\\": {\\n \\\"description\\\":
|
||||
\\\"Structured output for calculation results.\\\",\\n \\\"properties\\\":
|
||||
{\\n \\\"operation\\\": {\\n \\\"description\\\": \\\"The mathematical
|
||||
operation performed\\\",\\n \\\"title\\\": \\\"Operation\\\",\\n \\\"type\\\":
|
||||
\\\"string\\\"\\n },\\n \\\"result\\\": {\\n \\\"description\\\":
|
||||
\\\"The result of the calculation\\\",\\n \\\"title\\\": \\\"Result\\\",\\n
|
||||
\ \\\"type\\\": \\\"integer\\\"\\n },\\n \\\"explanation\\\":
|
||||
{\\n \\\"description\\\": \\\"Brief explanation of the calculation\\\",\\n
|
||||
\ \\\"title\\\": \\\"Explanation\\\",\\n \\\"type\\\": \\\"string\\\"\\n
|
||||
\ }\\n },\\n \\\"required\\\": [\\n \\\"operation\\\",\\n
|
||||
\ \\\"result\\\",\\n \\\"explanation\\\"\\n ],\\n \\\"title\\\":
|
||||
\\\"CalculationResult\\\",\\n \\\"type\\\": \\\"object\\\",\\n \\\"additionalProperties\\\":
|
||||
false\\n }\\n }\\n}\\n\\nIMPORTANT: Preserve the original content exactly
|
||||
as-is. Do NOT rewrite, paraphrase, or modify the meaning of the content. Only
|
||||
structure it to match the schema format.\\n\\nDo not include the OpenAPI schema
|
||||
in the final output. Ensure the final output does not include any code block
|
||||
markers like ```json or ```python.\",\"tool_choice\":{\"type\":\"tool\",\"name\":\"structured_output\"},\"tools\":[{\"name\":\"structured_output\",\"description\":\"Output
|
||||
the structured response\",\"input_schema\":{\"type\":\"object\",\"description\":\"Structured
|
||||
output for calculation results.\",\"title\":\"CalculationResult\",\"properties\":{\"operation\":{\"type\":\"string\",\"description\":\"The
|
||||
mathematical operation performed\",\"title\":\"Operation\"},\"result\":{\"type\":\"integer\",\"description\":\"The
|
||||
result of the calculation\",\"title\":\"Result\"},\"explanation\":{\"type\":\"string\",\"description\":\"Brief
|
||||
explanation of the calculation\",\"title\":\"Explanation\"}},\"additionalProperties\":false,\"required\":[\"operation\",\"result\",\"explanation\"]}}]}"
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
accept:
|
||||
- application/json
|
||||
accept-encoding:
|
||||
- ACCEPT-ENCODING-XXX
|
||||
anthropic-version:
|
||||
- '2023-06-01'
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '2289'
|
||||
content-type:
|
||||
- application/json
|
||||
cookie:
|
||||
- COOKIE-XXX
|
||||
host:
|
||||
- api.anthropic.com
|
||||
x-api-key:
|
||||
- X-API-KEY-XXX
|
||||
x-stainless-arch:
|
||||
- X-STAINLESS-ARCH-XXX
|
||||
x-stainless-async:
|
||||
- 'false'
|
||||
x-stainless-lang:
|
||||
- python
|
||||
x-stainless-os:
|
||||
- X-STAINLESS-OS-XXX
|
||||
x-stainless-package-version:
|
||||
- 0.73.0
|
||||
x-stainless-retry-count:
|
||||
- '0'
|
||||
x-stainless-runtime:
|
||||
- CPython
|
||||
x-stainless-runtime-version:
|
||||
- 3.13.3
|
||||
x-stainless-timeout:
|
||||
- NOT_GIVEN
|
||||
method: POST
|
||||
uri: https://api.anthropic.com/v1/messages
|
||||
response:
|
||||
body:
|
||||
string: '{"model":"claude-sonnet-4-6","id":"msg_012b6HHB7T6qZuKcXB5jkhpx","type":"message","role":"assistant","content":[{"type":"tool_use","id":"toolu_01UX2REqVJnQ3qNjHzVV1oNp","name":"structured_output","input":{"operation":"add_numbers","result":42,"explanation":"Adding
|
||||
15 and 27 together gives you a sum of 42."},"caller":{"type":"direct"}}],"stop_reason":"tool_use","stop_sequence":null,"stop_details":null,"usage":{"input_tokens":1123,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"cache_creation":{"ephemeral_5m_input_tokens":0,"ephemeral_1h_input_tokens":0},"output_tokens":84,"service_tier":"standard","inference_geo":"global"}}'
|
||||
headers:
|
||||
CF-RAY:
|
||||
- CF-RAY-XXX
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Security-Policy:
|
||||
- CSP-FILTERED
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 16:27:11 GMT
|
||||
Server:
|
||||
- cloudflare
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
X-Robots-Tag:
|
||||
- none
|
||||
anthropic-organization-id:
|
||||
- ANTHROPIC-ORGANIZATION-ID-XXX
|
||||
anthropic-ratelimit-input-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-input-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-input-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-INPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-output-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-output-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-output-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-OUTPUT-TOKENS-RESET-XXX
|
||||
anthropic-ratelimit-requests-limit:
|
||||
- '20000'
|
||||
anthropic-ratelimit-requests-remaining:
|
||||
- '19999'
|
||||
anthropic-ratelimit-requests-reset:
|
||||
- '2026-05-26T16:27:09Z'
|
||||
anthropic-ratelimit-tokens-limit:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-LIMIT-XXX
|
||||
anthropic-ratelimit-tokens-remaining:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-REMAINING-XXX
|
||||
anthropic-ratelimit-tokens-reset:
|
||||
- ANTHROPIC-RATELIMIT-TOKENS-RESET-XXX
|
||||
cf-cache-status:
|
||||
- DYNAMIC
|
||||
request-id:
|
||||
- REQUEST-ID-XXX
|
||||
strict-transport-security:
|
||||
- STS-XXX
|
||||
traceresponse:
|
||||
- 00-c97065bea414b95b086529ea43832d89-d5c4bad6e383ad9f-01
|
||||
vary:
|
||||
- Accept-Encoding
|
||||
x-envoy-upstream-service-time:
|
||||
- '2133'
|
||||
- '1234'
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
|
||||
@@ -8,10 +8,20 @@ interactions:
|
||||
[{"toolSpec": {"name": "add_numbers", "description": "Add two numbers together
|
||||
and return the sum.", "inputSchema": {"json": {"properties": {"a": {"title":
|
||||
"A", "type": "integer"}, "b": {"title": "B", "type": "integer"}}, "required":
|
||||
["a", "b"], "type": "object", "additionalProperties": false}}}}]}}'
|
||||
["a", "b"], "type": "object", "additionalProperties": false}}}}, {"toolSpec":
|
||||
{"name": "structured_output", "description": "Use this tool to provide your
|
||||
final structured response. Call this tool when you have gathered all necessary
|
||||
information and are ready to provide the final answer in the required format.",
|
||||
"inputSchema": {"json": {"description": "Structured output for calculation results.",
|
||||
"properties": {"operation": {"description": "The mathematical operation performed",
|
||||
"title": "Operation", "type": "string"}, "result": {"description": "The result
|
||||
of the calculation", "title": "Result", "type": "integer"}, "explanation": {"description":
|
||||
"Brief explanation of the calculation", "title": "Explanation", "type": "string"}},
|
||||
"required": ["operation", "result", "explanation"], "title": "CalculationResult",
|
||||
"type": "object", "additionalProperties": false}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '702'
|
||||
- '1509'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -26,23 +36,21 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-sonnet-20240229-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":2257},"output":{"message":{"content":[{"text":"I''ll
|
||||
calculate 15 + 27 right away using the `add_numbers` tool!"},{"toolUse":{"input":{"a":15,"b":27},"name":"add_numbers","toolUseId":"tooluse_CVmuFOrTItCY07vxuA84mU","type":"tool_use"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":645,"outputTokens":92,"serverToolUsage":{},"totalTokens":737}}'
|
||||
string: '{"metrics":{"latencyMs":1968},"output":{"message":{"content":[{"text":"Okay,
|
||||
let''s calculate 15 + 27 using the add_numbers tool:"},{"toolUse":{"input":{"a":15,"b":27},"name":"add_numbers","toolUseId":"tooluse_pSseOamVELzpL3kQG5VukN"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":488,"outputTokens":91,"serverToolUsage":{},"totalTokens":579}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '500'
|
||||
- '366'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:04:49 GMT
|
||||
- Thu, 12 Feb 2026 22:01:04 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
@@ -51,19 +59,29 @@ interactions:
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 + 27 using your add_numbers tool. Report the result."}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_CVmuFOrTItCY07vxuA84mU", "name":
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_pSseOamVELzpL3kQG5VukN", "name":
|
||||
"add_numbers", "input": {"a": 15, "b": 27}}}]}, {"role": "user", "content":
|
||||
[{"toolResult": {"toolUseId": "tooluse_CVmuFOrTItCY07vxuA84mU", "content": [{"text":
|
||||
[{"toolResult": {"toolUseId": "tooluse_pSseOamVELzpL3kQG5VukN", "content": [{"text":
|
||||
"42"}]}}]}], "inferenceConfig": {"stopSequences": ["\nObservation:"]}, "system":
|
||||
[{"text": "You are Calculator. You are a calculator assistant that uses tools
|
||||
to compute results.\nYour personal goal is: Perform calculations using available
|
||||
tools"}], "toolConfig": {"tools": [{"toolSpec": {"name": "add_numbers", "description":
|
||||
"Add two numbers together and return the sum.", "inputSchema": {"json": {"properties":
|
||||
{"a": {"title": "A", "type": "integer"}, "b": {"title": "B", "type": "integer"}},
|
||||
"required": ["a", "b"], "type": "object", "additionalProperties": false}}}}]}}'
|
||||
"required": ["a", "b"], "type": "object", "additionalProperties": false}}}},
|
||||
{"toolSpec": {"name": "structured_output", "description": "Use this tool to
|
||||
provide your final structured response. Call this tool when you have gathered
|
||||
all necessary information and are ready to provide the final answer in the required
|
||||
format.", "inputSchema": {"json": {"description": "Structured output for calculation
|
||||
results.", "properties": {"operation": {"description": "The mathematical operation
|
||||
performed", "title": "Operation", "type": "string"}, "result": {"description":
|
||||
"The result of the calculation", "title": "Result", "type": "integer"}, "explanation":
|
||||
{"description": "Brief explanation of the calculation", "title": "Explanation",
|
||||
"type": "string"}}, "required": ["operation", "result", "explanation"], "title":
|
||||
"CalculationResult", "type": "object", "additionalProperties": false}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '977'
|
||||
- '1784'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -78,49 +96,41 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-sonnet-20240229-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: "{\"metrics\":{\"latencyMs\":2393},\"output\":{\"message\":{\"content\":[{\"text\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F9EE\\n\\nUsing the `add_numbers` tool,
|
||||
I computed the sum of 15 and 27, and the result is **42**.\"}],\"role\":\"assistant\"}},\"stopReason\":\"end_turn\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":729,\"outputTokens\":51,\"serverToolUsage\":{},\"totalTokens\":780}}"
|
||||
string: '{"metrics":{"latencyMs":7598},"output":{"message":{"content":[{"toolUse":{"input":{"operation":"Addition","result":42,"explanation":"I
|
||||
added 15 and 27 using the add_numbers tool."},"name":"structured_output","toolUseId":"tooluse_RT8uSPaM37Q8CVuo3rJLtI"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":571,"outputTokens":102,"serverToolUsage":{},"totalTokens":673}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '443'
|
||||
- '387'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:04:51 GMT
|
||||
- Thu, 12 Feb 2026 22:01:12 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "The result of **15
|
||||
+ 27 = 42**! \ud83e\uddee\n\nUsing the `add_numbers` tool, I computed the sum
|
||||
of 15 and 27, and the result is **42**."}]}], "inferenceConfig": {}, "system":
|
||||
[{"text": "Format your final answer according to the following OpenAPI schema:
|
||||
{\n \"type\": \"json_schema\",\n \"json_schema\": {\n \"name\": \"CalculationResult\",\n \"strict\":
|
||||
true,\n \"schema\": {\n \"description\": \"Structured output for calculation
|
||||
results.\",\n \"properties\": {\n \"operation\": {\n \"description\":
|
||||
\"The mathematical operation performed\",\n \"title\": \"Operation\",\n \"type\":
|
||||
\"string\"\n },\n \"result\": {\n \"description\": \"The
|
||||
result of the calculation\",\n \"title\": \"Result\",\n \"type\":
|
||||
\"integer\"\n },\n \"explanation\": {\n \"description\":
|
||||
\"Brief explanation of the calculation\",\n \"title\": \"Explanation\",\n \"type\":
|
||||
\"string\"\n }\n },\n \"required\": [\n \"operation\",\n \"result\",\n \"explanation\"\n ],\n \"title\":
|
||||
\"CalculationResult\",\n \"type\": \"object\",\n \"additionalProperties\":
|
||||
false\n }\n }\n}\n\nIMPORTANT: Preserve the original content exactly as-is.
|
||||
Do NOT rewrite, paraphrase, or modify the meaning of the content. Only structure
|
||||
it to match the schema format.\n\nDo not include the OpenAPI schema in the final
|
||||
output. Ensure the final output does not include any code block markers like
|
||||
```json or ```python."}], "toolConfig": {"tools": [{"toolSpec": {"name": "structured_output",
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "\nCurrent Task: Calculate
|
||||
15 + 27 using your add_numbers tool. Report the result."}]}, {"role": "assistant",
|
||||
"content": [{"toolUse": {"toolUseId": "tooluse_pSseOamVELzpL3kQG5VukN", "name":
|
||||
"add_numbers", "input": {"a": 15, "b": 27}}}]}, {"role": "user", "content":
|
||||
[{"toolResult": {"toolUseId": "tooluse_pSseOamVELzpL3kQG5VukN", "content": [{"text":
|
||||
"42"}]}}]}, {"role": "assistant", "content": [{"text": "{\"operation\":\"Addition\",\"result\":42,\"explanation\":\"I
|
||||
added 15 and 27 using the add_numbers tool.\"}"}]}], "inferenceConfig": {"stopSequences":
|
||||
["\nObservation:"]}, "system": [{"text": "You are Calculator. You are a calculator
|
||||
assistant that uses tools to compute results.\nYour personal goal is: Perform
|
||||
calculations using available tools"}], "toolConfig": {"tools": [{"toolSpec":
|
||||
{"name": "add_numbers", "description": "Add two numbers together and return
|
||||
the sum.", "inputSchema": {"json": {"properties": {"a": {"title": "A", "type":
|
||||
"integer"}, "b": {"title": "B", "type": "integer"}}, "required": ["a", "b"],
|
||||
"type": "object", "additionalProperties": false}}}}, {"toolSpec": {"name": "structured_output",
|
||||
"description": "Use this tool to provide your final structured response. Call
|
||||
this tool when you have gathered all necessary information and are ready to
|
||||
provide the final answer in the required format.", "inputSchema": {"json": {"description":
|
||||
@@ -130,10 +140,10 @@ interactions:
|
||||
"type": "integer"}, "explanation": {"description": "Brief explanation of the
|
||||
calculation", "title": "Explanation", "type": "string"}}, "required": ["operation",
|
||||
"result", "explanation"], "title": "CalculationResult", "type": "object", "additionalProperties":
|
||||
false}}}}], "toolChoice": {"tool": {"name": "structured_output"}}}}'
|
||||
false}}}}]}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '2510'
|
||||
- '1942'
|
||||
Content-Type:
|
||||
- !!binary |
|
||||
YXBwbGljYXRpb24vanNvbg==
|
||||
@@ -148,27 +158,28 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-sonnet-20240229-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: "{\"metrics\":{\"latencyMs\":2107},\"output\":{\"message\":{\"content\":[{\"toolUse\":{\"input\":{\"operation\":\"add_numbers\",\"result\":42,\"explanation\":\"The
|
||||
result of **15 + 27 = 42**! \U0001F9EE\\n\\nUsing the `add_numbers` tool,
|
||||
I computed the sum of 15 and 27, and the result is **42**.\"},\"name\":\"structured_output\",\"toolUseId\":\"tooluse_5OzuYfgauW1f24uhsvXWDo\",\"type\":\"tool_use\"}}],\"role\":\"assistant\"}},\"stopReason\":\"tool_use\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":1150,\"outputTokens\":116,\"serverToolUsage\":{},\"totalTokens\":1266}}"
|
||||
string: '{"message":"The model returned the following errors: Your API request
|
||||
included an `assistant` message in the final position, which would pre-fill
|
||||
the `assistant` response. When using tools, pre-filling the `assistant` response
|
||||
is not supported."}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '603'
|
||||
- '246'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:04:54 GMT
|
||||
- Thu, 12 Feb 2026 22:01:12 GMT
|
||||
x-amzn-ErrorType:
|
||||
- ValidationException:http://internal.amazon.com/coral/com.amazon.bedrock/
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
code: 400
|
||||
message: Bad Request
|
||||
version: 1
|
||||
|
||||
@@ -33,37 +33,29 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-sonnet-20240229-v1%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: "{\"metrics\":{\"latencyMs\":6183},\"output\":{\"message\":{\"content\":[{\"toolUse\":{\"input\":{\"topic\":\"Benefits
|
||||
of Remote Work\",\"key_points\":[\"Improved Work-Life Balance: Employees gain
|
||||
flexibility to manage personal and professional responsibilities, reducing
|
||||
stress and burnout.\",\"Increased Productivity: Fewer office distractions
|
||||
and elimination of commutes allow workers to focus more effectively on tasks.\",\"Cost
|
||||
Savings: Both employers (reduced office overhead) and employees (lower commuting
|
||||
and wardrobe costs) benefit financially.\",\"Access to Global Talent: Companies
|
||||
can hire the best candidates regardless of geographic location, expanding
|
||||
the talent pool.\",\"Environmental Impact: Reduced commuting leads to lower
|
||||
carbon emissions and a smaller environmental footprint.\",\"Employee Retention
|
||||
& Satisfaction: Greater autonomy and flexibility contribute to higher job
|
||||
satisfaction and lower turnover rates.\"],\"summary\":\"Remote work offers
|
||||
a compelling mix of personal, financial, and organizational advantages. It
|
||||
empowers employees with flexibility and autonomy while enabling businesses
|
||||
to cut costs, access wider talent pools, and boost overall productivity \u2014
|
||||
making it a mutually beneficial arrangement in the modern workforce.\"},\"name\":\"structured_output\",\"toolUseId\":\"tooluse_miAVY9Wyw0HMShZbgbyTwX\",\"type\":\"tool_use\"}}],\"role\":\"assistant\"}},\"stopReason\":\"tool_use\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":851,\"outputTokens\":268,\"serverToolUsage\":{},\"totalTokens\":1119}}"
|
||||
string: '{"metrics":{"latencyMs":3496},"output":{"message":{"content":[{"toolUse":{"input":{"topic":"Benefits
|
||||
of remote work","key_points":"- Increased flexibility and work-life balance\n-
|
||||
Reduced commute time and costs\n- Access to a wider talent pool for companies\n-
|
||||
Increased productivity for some employees\n- Environmental benefits from reduced
|
||||
commuting","summary":"Remote work offers several benefits including improved
|
||||
work-life balance, cost and time savings from eliminating commutes, access
|
||||
to a broader talent pool for employers, productivity gains, and environmental
|
||||
advantages from reduced transportation. However, it also presents challenges
|
||||
like social isolation, blurred work-life boundaries, and potential distractions
|
||||
at home that need to be managed effectively."},"name":"structured_output","toolUseId":"tooluse_Jfg8pUBaRxWkKwR_rp5mCw"}}],"role":"assistant"}},"stopReason":"tool_use","usage":{"inputTokens":512,"outputTokens":187,"serverToolUsage":{},"totalTokens":699}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '1568'
|
||||
- '982'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:01 GMT
|
||||
- Fri, 30 Jan 2026 01:04:10 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -19,23 +19,21 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-sonnet-20241022-v2%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: "{\"metrics\":{\"latencyMs\":2397},\"output\":{\"message\":{\"content\":[{\"text\":\"Hello!
|
||||
\U0001F44B How are you doing? Is there something I can help you with today?\"}],\"role\":\"assistant\"}},\"stopReason\":\"end_turn\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":9,\"outputTokens\":24,\"serverToolUsage\":{},\"totalTokens\":33}}"
|
||||
string: '{"metrics":{"latencyMs":776},"output":{"message":{"content":[{"text":"Hello!
|
||||
How are you today?"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":9,"outputTokens":10,"serverToolUsage":{},"totalTokens":19}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '388'
|
||||
- '226'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:24 GMT
|
||||
- Mon, 01 Dec 2025 08:50:59 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -21,23 +21,21 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-sonnet-20241022-v2%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1900},"output":{"message":{"content":[{"text":"Your
|
||||
name is Alice! You told me that at the start of our conversation."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":31,"outputTokens":19,"serverToolUsage":{},"totalTokens":50}}'
|
||||
string: '{"metrics":{"latencyMs":622},"output":{"message":{"content":[{"text":"Your
|
||||
name is Alice."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":31,"outputTokens":8,"serverToolUsage":{},"totalTokens":39}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '383'
|
||||
- '330'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:10 GMT
|
||||
- Mon, 01 Dec 2025 08:51:04 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -19,23 +19,20 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-sonnet-20241022-v2%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":2148},"output":{"message":{"content":[{"text":"1
|
||||
+ 1 = **2**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":14,"outputTokens":14,"serverToolUsage":{},"totalTokens":28}}'
|
||||
string: '{"metrics":{"latencyMs":583},"output":{"message":{"content":[{"text":"1+1=2"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":14,"outputTokens":9,"serverToolUsage":{},"totalTokens":23}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '326'
|
||||
- '206'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:12 GMT
|
||||
- Mon, 01 Dec 2025 08:51:00 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
@@ -61,23 +58,20 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-sonnet-20241022-v2%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1443},"output":{"message":{"content":[{"text":"2
|
||||
+ 2 = **4**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":14,"outputTokens":14,"serverToolUsage":{},"totalTokens":28}}'
|
||||
string: '{"metrics":{"latencyMs":869},"output":{"message":{"content":[{"text":"2+2=4"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":14,"outputTokens":9,"serverToolUsage":{},"totalTokens":23}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '326'
|
||||
- '206'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:14 GMT
|
||||
- Mon, 01 Dec 2025 08:51:01 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -19,23 +19,21 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-sonnet-20241022-v2%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1421},"output":{"message":{"content":[{"text":"#
|
||||
The Last Ember of Varathorn"}],"role":"assistant"}},"stopReason":"max_tokens","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":16,"outputTokens":10,"serverToolUsage":{},"totalTokens":26}}'
|
||||
string: '{"metrics":{"latencyMs":966},"output":{"message":{"content":[{"text":"Here''s
|
||||
a long story about a dragon:"}],"role":"assistant"}},"stopReason":"max_tokens","usage":{"inputTokens":16,"outputTokens":10,"serverToolUsage":{},"totalTokens":26}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '344'
|
||||
- '239'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:16 GMT
|
||||
- Mon, 01 Dec 2025 08:50:58 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
interactions:
|
||||
- request:
|
||||
body: '{"messages": [{"role": "user", "content": [{"text": "Tell me a short fact"}]}],
|
||||
"inferenceConfig": {"maxTokens": 100, "temperature": 0.7}}'
|
||||
"inferenceConfig": {"maxTokens": 100, "temperature": 0.7, "topP": 0.9}}'
|
||||
headers:
|
||||
Content-Length:
|
||||
- '138'
|
||||
- '151'
|
||||
Content-Type:
|
||||
- application/json
|
||||
User-Agent:
|
||||
@@ -19,24 +19,22 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-sonnet-20241022-v2%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: "{\"metrics\":{\"latencyMs\":2721},\"output\":{\"message\":{\"content\":[{\"text\":\"Here's
|
||||
a short fact:\\n\\n**Honey never spoils.** Archaeologists have found 3,000-year-old
|
||||
honey in Egyptian tombs that was still perfectly edible. \U0001F36F\"}],\"role\":\"assistant\"}},\"stopReason\":\"end_turn\",\"usage\":{\"cacheReadInputTokenCount\":0,\"cacheReadInputTokens\":0,\"cacheWriteInputTokenCount\":0,\"cacheWriteInputTokens\":0,\"inputTokens\":12,\"outputTokens\":47,\"serverToolUsage\":{},\"totalTokens\":59}}"
|
||||
string: '{"metrics":{"latencyMs":1360},"output":{"message":{"content":[{"text":"Here''s
|
||||
a short fact: Honeybees can recognize human faces by learning and remembering
|
||||
facial features, similar to how we do."}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":12,"outputTokens":31,"serverToolUsage":{},"totalTokens":43}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '463'
|
||||
- '436'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:06:27 GMT
|
||||
- Mon, 01 Dec 2025 08:50:57 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -19,23 +19,21 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-sonnet-20241022-v2%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":2975},"output":{"message":{"content":[{"text":"2
|
||||
+ 2 = **4**"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":21,"outputTokens":14,"serverToolUsage":{},"totalTokens":35}}'
|
||||
string: '{"metrics":{"latencyMs":677},"output":{"message":{"content":[{"text":"2
|
||||
+ 2 = 4"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":20,"outputTokens":13,"serverToolUsage":{},"totalTokens":33}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '326'
|
||||
- '211'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:21 GMT
|
||||
- Mon, 01 Dec 2025 08:51:03 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -19,22 +19,20 @@ interactions:
|
||||
- AUTHORIZATION-XXX
|
||||
x-amz-date:
|
||||
- X-AMZ-DATE-XXX
|
||||
x-amz-security-token:
|
||||
- X-AMZ-SECURITY-TOKEN-XXX
|
||||
method: POST
|
||||
uri: https://bedrock-runtime.us-west-2.amazonaws.com/model/us.anthropic.claude-sonnet-4-6/converse
|
||||
uri: https://bedrock-runtime.us-east-1.amazonaws.com/model/us.anthropic.claude-3-5-sonnet-20241022-v2%3A0/converse
|
||||
response:
|
||||
body:
|
||||
string: '{"metrics":{"latencyMs":1720},"output":{"message":{"content":[{"text":"test"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"cacheReadInputTokenCount":0,"cacheReadInputTokens":0,"cacheWriteInputTokenCount":0,"cacheWriteInputTokens":0,"inputTokens":15,"outputTokens":4,"serverToolUsage":{},"totalTokens":19}}'
|
||||
string: '{"metrics":{"latencyMs":654},"output":{"message":{"content":[{"text":"test"}],"role":"assistant"}},"stopReason":"end_turn","usage":{"inputTokens":15,"outputTokens":4,"serverToolUsage":{},"totalTokens":19}}'
|
||||
headers:
|
||||
Connection:
|
||||
- keep-alive
|
||||
Content-Length:
|
||||
- '316'
|
||||
- '205'
|
||||
Content-Type:
|
||||
- application/json
|
||||
Date:
|
||||
- Tue, 26 May 2026 17:05:18 GMT
|
||||
- Mon, 01 Dec 2025 08:51:02 GMT
|
||||
x-amzn-RequestId:
|
||||
- X-AMZN-REQUESTID-XXX
|
||||
status:
|
||||
|
||||
@@ -8,8 +8,18 @@ interactions:
|
||||
[{"description": "Add two numbers together and return the sum.", "name": "add_numbers",
|
||||
"parameters_json_schema": {"properties": {"a": {"title": "A", "type": "integer"},
|
||||
"b": {"title": "B", "type": "integer"}}, "required": ["a", "b"], "type": "object",
|
||||
"additionalProperties": false}}]}], "generationConfig": {"stopSequences": ["\nObservation:"],
|
||||
"thinkingConfig": {"include_thoughts": true}}}'
|
||||
"additionalProperties": false}}, {"description": "Use this tool to provide your
|
||||
final structured response. Call this tool when you have gathered all necessary
|
||||
information and are ready to provide the final answer in the required format.",
|
||||
"name": "structured_output", "parameters_json_schema": {"description": "Structured
|
||||
output for calculation results.", "properties": {"operation": {"description":
|
||||
"The mathematical operation performed", "title": "Operation", "type": "string"},
|
||||
"result": {"description": "The result of the calculation", "title": "Result",
|
||||
"type": "integer"}, "explanation": {"description": "Brief explanation of the
|
||||
calculation", "title": "Explanation", "type": "string"}}, "required": ["operation",
|
||||
"result", "explanation"], "title": "CalculationResult", "type": "object", "additionalProperties":
|
||||
false, "propertyOrdering": ["operation", "result", "explanation"]}}]}], "generationConfig":
|
||||
{"stopSequences": ["\nObservation:"]}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -20,13 +30,13 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '784'
|
||||
- '1592'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
- google-genai-sdk/1.49.0 gl-python/3.13.3
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
@@ -34,36 +44,27 @@ interactions:
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"text\": \"Okay, here's my thought process on
|
||||
tackling this simple addition problem:\\n\\n**Calculating 15 + 27**\\n\\nRight,
|
||||
so I need to calculate 15 plus 27. It's a straightforward arithmetic operation,
|
||||
and I know I have a dedicated tool for that \u2013 the `add_numbers` function.
|
||||
No need to reinvent the wheel, I should use the appropriate tool in my toolbox.\\n\\nTo
|
||||
use the tool effectively, I need to provide the correct inputs. In this case,
|
||||
I'll set `a` equal to 15, and `b` equal to 27. That should be a piece of cake
|
||||
for the function. Now I just need to call it!\\n\",\n \"thought\":
|
||||
true\n },\n {\n \"functionCall\": {\n \"name\":
|
||||
\"add_numbers\",\n \"args\": {\n \"a\": 15,\n
|
||||
\ \"b\": 27\n }\n },\n \"thoughtSignature\":
|
||||
\"CqwBAQw51sfkbjIDS7wS47oc/Bej+AYsUu5Cs+BC2Ae5NMasRmWa/u5Ct426qkpkIpgzGSNjwwfitf1gK93Abse9EGj5m1swXmPU2XSkqhMYMEXZGH1mW2U2XH8zaXHRIAx2aI0O8VbJ3sL8h1lJgbVCkvLa2RyWwY6E8FRPhQOHtrOQEQtfAUtHdJz928j6UEgS818X/7hEwuWsQhIho0frtziX30UlI7yXOeBBWw==\"\n
|
||||
[\n {\n \"functionCall\": {\n \"name\": \"add_numbers\",\n
|
||||
\ \"args\": {\n \"a\": 15,\n \"b\":
|
||||
27\n }\n },\n \"thoughtSignature\": \"CqMFAb4+9vtoEAola3khZd5LD4cccGlQsdVI9cPJGQBURT0qF5Xqp8o1L7oGN4s5trQpk7NPhKe1CYDMXDJueC7zM/zGlcy2daSJAeuTd9pxAbtndEXCGjM/9Nt8QRpvaDV3Ff2bkKSn/JCOJdzsN5m6G5C6BMRGVt8bZyRHelwu7tjCNYiMEvFqVoQIWN6d+CWKkHnbSwOlSUTDXJEcWvUwP82Ou7s68l2k7XNbDWCY5Tt8LUdPgeqjfH15JoEgZUbPxbVKA0ykRln1svfpvQ4Vm3Hn7PL3voWZWGzP5uLnH6JF2M8H6TokSDYZETvlDo5bK1Cx9IzrdUgHkku6gNbct/e53CPEUgqSKbY1VhsLAXAHieT4PKqeMQ4B+7gyCLXHeL6TOGjqSVGBBOQLtF9yCbKbkXa5pPu3+DnPhoOeH7jEPb+bqIWv6rxERErbKhu0IlP+UNBRAAj+wXNDZxQvLnlrlXrLtWllO9wFshr1DzgDgNZSRsPQeVQq2L0bL+KRobCXAfjMpH/8bhxdTI3sgsCtU3+dKwV5Z8Fg6e5oRyBAss8AE2CmYtdnYpt+iss9IT8NlSpI2DcdmVErEFNsebVcSwnr+9YXoESh4O1i8er9lX59hKTBdYXdP2GJ63cq9cSOalzx/doKxA2FzP3QhdV+H11LiUQzsQCXHqv0D+D290z1QoPhpsHEd7b/1EoW7D/2rub4acV8tpUcG2oe/Mj1kzYQoiEwZkgM56JoUs++5+5tWBMW68e4y1AmkyhDTCDkiNIa4noE6AOdNsLjL/+EHvcNFRmayFXXiUShIcMT0WQ9xNriWQP/dbhd6F5K7BKSajdB1391OYeHVmSEzzXYxjnUWXd+jqORQcsiPNIVRQkZI7ZGl6+4exmZsfrKzbFy\"\n
|
||||
\ }\n ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0,\n \"finishMessage\": \"Model generated
|
||||
function call(s).\"\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
104,\n \"candidatesTokenCount\": 22,\n \"totalTokenCount\": 173,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 104\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 47,\n \"serviceTier\": \"standard\"\n
|
||||
\ },\n \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"MpgPapmwO_vN-sAPvrWJmA0\"\n}\n"
|
||||
202,\n \"candidatesTokenCount\": 22,\n \"totalTokenCount\": 403,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 202\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 179\n },\n \"modelVersion\":
|
||||
\"gemini-2.5-flash\",\n \"responseId\": \"AlCOadrrK7aVjMcPksrU-A0\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Thu, 21 May 2026 23:41:40 GMT
|
||||
- Thu, 12 Feb 2026 22:11:14 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=1920
|
||||
- gfet4t7; dur=1417
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
@@ -74,8 +75,6 @@ interactions:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
@@ -84,7 +83,7 @@ interactions:
|
||||
- request:
|
||||
body: '{"contents": [{"parts": [{"text": "\nCurrent Task: Calculate 15 + 27 using
|
||||
your add_numbers tool. Report the result."}], "role": "user"}, {"parts": [{"functionCall":
|
||||
{"args": {"a": 15, "b": 27}, "name": "add_numbers"}, "thoughtSignature": "CqwBAQw51sfkbjIDS7wS47oc_Bej-AYsUu5Cs-BC2Ae5NMasRmWa_u5Ct426qkpkIpgzGSNjwwfitf1gK93Abse9EGj5m1swXmPU2XSkqhMYMEXZGH1mW2U2XH8zaXHRIAx2aI0O8VbJ3sL8h1lJgbVCkvLa2RyWwY6E8FRPhQOHtrOQEQtfAUtHdJz928j6UEgS818X_7hEwuWsQhIho0frtziX30UlI7yXOeBBWw=="}],
|
||||
{"args": {"a": 15, "b": 27}, "name": "add_numbers"}, "thoughtSignature": "CqMFAb4-9vtoEAola3khZd5LD4cccGlQsdVI9cPJGQBURT0qF5Xqp8o1L7oGN4s5trQpk7NPhKe1CYDMXDJueC7zM_zGlcy2daSJAeuTd9pxAbtndEXCGjM_9Nt8QRpvaDV3Ff2bkKSn_JCOJdzsN5m6G5C6BMRGVt8bZyRHelwu7tjCNYiMEvFqVoQIWN6d-CWKkHnbSwOlSUTDXJEcWvUwP82Ou7s68l2k7XNbDWCY5Tt8LUdPgeqjfH15JoEgZUbPxbVKA0ykRln1svfpvQ4Vm3Hn7PL3voWZWGzP5uLnH6JF2M8H6TokSDYZETvlDo5bK1Cx9IzrdUgHkku6gNbct_e53CPEUgqSKbY1VhsLAXAHieT4PKqeMQ4B-7gyCLXHeL6TOGjqSVGBBOQLtF9yCbKbkXa5pPu3-DnPhoOeH7jEPb-bqIWv6rxERErbKhu0IlP-UNBRAAj-wXNDZxQvLnlrlXrLtWllO9wFshr1DzgDgNZSRsPQeVQq2L0bL-KRobCXAfjMpH_8bhxdTI3sgsCtU3-dKwV5Z8Fg6e5oRyBAss8AE2CmYtdnYpt-iss9IT8NlSpI2DcdmVErEFNsebVcSwnr-9YXoESh4O1i8er9lX59hKTBdYXdP2GJ63cq9cSOalzx_doKxA2FzP3QhdV-H11LiUQzsQCXHqv0D-D290z1QoPhpsHEd7b_1EoW7D_2rub4acV8tpUcG2oe_Mj1kzYQoiEwZkgM56JoUs--5-5tWBMW68e4y1AmkyhDTCDkiNIa4noE6AOdNsLjL_-EHvcNFRmayFXXiUShIcMT0WQ9xNriWQP_dbhd6F5K7BKSajdB1391OYeHVmSEzzXYxjnUWXd-jqORQcsiPNIVRQkZI7ZGl6-4exmZsfrKzbFy"}],
|
||||
"role": "model"}, {"parts": [{"functionResponse": {"name": "add_numbers", "response":
|
||||
{"result": 42}}}], "role": "user"}], "systemInstruction": {"parts": [{"text":
|
||||
"You are Calculator. You are a calculator assistant that uses tools to compute
|
||||
@@ -93,8 +92,18 @@ interactions:
|
||||
numbers together and return the sum.", "name": "add_numbers", "parameters_json_schema":
|
||||
{"properties": {"a": {"title": "A", "type": "integer"}, "b": {"title": "B",
|
||||
"type": "integer"}}, "required": ["a", "b"], "type": "object", "additionalProperties":
|
||||
false}}]}], "generationConfig": {"stopSequences": ["\nObservation:"], "thinkingConfig":
|
||||
{"include_thoughts": true}}}'
|
||||
false}}, {"description": "Use this tool to provide your final structured response.
|
||||
Call this tool when you have gathered all necessary information and are ready
|
||||
to provide the final answer in the required format.", "name": "structured_output",
|
||||
"parameters_json_schema": {"description": "Structured output for calculation
|
||||
results.", "properties": {"operation": {"description": "The mathematical operation
|
||||
performed", "title": "Operation", "type": "string"}, "result": {"description":
|
||||
"The result of the calculation", "title": "Result", "type": "integer"}, "explanation":
|
||||
{"description": "Brief explanation of the calculation", "title": "Explanation",
|
||||
"type": "string"}}, "required": ["operation", "result", "explanation"], "title":
|
||||
"CalculationResult", "type": "object", "additionalProperties": false, "propertyOrdering":
|
||||
["operation", "result", "explanation"]}}]}], "generationConfig": {"stopSequences":
|
||||
["\nObservation:"]}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -105,13 +114,13 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '1249'
|
||||
- '2725'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
- google-genai-sdk/1.49.0 gl-python/3.13.3
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
@@ -119,24 +128,28 @@ interactions:
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"text\": \"The sum of 15 and 27 is 42.\"\n }\n
|
||||
\ ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
142,\n \"candidatesTokenCount\": 15,\n \"totalTokenCount\": 157,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 142\n
|
||||
\ }\n ],\n \"serviceTier\": \"standard\"\n },\n \"modelVersion\":
|
||||
\"gemini-2.5-flash\",\n \"responseId\": \"NZgPasTKBf3F-sAP4Lu48Ak\"\n}\n"
|
||||
[\n {\n \"functionCall\": {\n \"name\": \"structured_output\",\n
|
||||
\ \"args\": {\n \"result\": 42,\n \"explanation\":
|
||||
\"The sum of 15 and 27 is 42.\",\n \"operation\": \"Addition\"\n
|
||||
\ }\n },\n \"thoughtSignature\": \"CtYCAb4+9vsKJoVFV1W8ORKk+Likt7GS9CuzuE53V9sbS2gFuiEjJ7ghBqWDG2UrgyRYFjPl6EalXUBnEbEq9rZNYGY27VpcweI1tv6p+477bgz1pmZnL0nfAcrp4nuphL+Ij0nXZQoo5cF4Gk29RQSNy49VRn3eP9eUW0hG7EpkPmfJiUSSDuaQENHN1UBBnFS9QUC+Fw+unnQ10B57fauyiXWNrBUkE2PYqgj5vELa5lVMtk5beh4ydWNnZ04t8gvQniCJ38EWWQr8VAXrSqE156oCBMwkFaFM7huPWHZk53n/HAG/VsQgPayf045STWKWjBzp6uTiwH9pYtoI1LBah3uxVbJRKOzH7HI4U0cHsffQqIIUn8cW4SP1UK/nvAivU1l0p6Bot8KIVJ5vqoF+o2oDmTuZv0HkDo5+UvXRqfsO5AylpUdM+JMGaXVAA7oZNqVPQybw\"\n
|
||||
\ }\n ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0,\n \"finishMessage\": \"Model generated
|
||||
function call(s).\"\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
240,\n \"candidatesTokenCount\": 39,\n \"totalTokenCount\": 357,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 240\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 78\n },\n \"modelVersion\":
|
||||
\"gemini-2.5-flash\",\n \"responseId\": \"A1COaaWbKvKGjMcPsN-EkAs\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Thu, 21 May 2026 23:41:41 GMT
|
||||
- Thu, 12 Feb 2026 22:11:15 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=750
|
||||
- gfet4t7; dur=906
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
@@ -147,107 +160,6 @@ interactions:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
code: 200
|
||||
message: OK
|
||||
- request:
|
||||
body: '{"contents": [{"parts": [{"text": "The sum of 15 and 27 is 42."}], "role":
|
||||
"user"}], "systemInstruction": {"parts": [{"text": "Format your final answer
|
||||
according to the following OpenAPI schema: {\n \"type\": \"json_schema\",\n \"json_schema\":
|
||||
{\n \"name\": \"CalculationResult\",\n \"strict\": true,\n \"schema\":
|
||||
{\n \"description\": \"Structured output for calculation results.\",\n \"properties\":
|
||||
{\n \"operation\": {\n \"description\": \"The mathematical operation
|
||||
performed\",\n \"title\": \"Operation\",\n \"type\": \"string\"\n },\n \"result\":
|
||||
{\n \"description\": \"The result of the calculation\",\n \"title\":
|
||||
\"Result\",\n \"type\": \"integer\"\n },\n \"explanation\":
|
||||
{\n \"description\": \"Brief explanation of the calculation\",\n \"title\":
|
||||
\"Explanation\",\n \"type\": \"string\"\n }\n },\n \"required\":
|
||||
[\n \"operation\",\n \"result\",\n \"explanation\"\n ],\n \"title\":
|
||||
\"CalculationResult\",\n \"type\": \"object\",\n \"additionalProperties\":
|
||||
false\n }\n }\n}\n\nIMPORTANT: Preserve the original content exactly as-is.
|
||||
Do NOT rewrite, paraphrase, or modify the meaning of the content. Only structure
|
||||
it to match the schema format.\n\nDo not include the OpenAPI schema in the final
|
||||
output. Ensure the final output does not include any code block markers like
|
||||
```json or ```python."}], "role": "user"}, "generationConfig": {"responseMimeType":
|
||||
"application/json", "responseJsonSchema": {"description": "Structured output
|
||||
for calculation results.", "properties": {"operation": {"description": "The
|
||||
mathematical operation performed", "title": "Operation", "type": "string"},
|
||||
"result": {"description": "The result of the calculation", "title": "Result",
|
||||
"type": "integer"}, "explanation": {"description": "Brief explanation of the
|
||||
calculation", "title": "Explanation", "type": "string"}}, "required": ["operation",
|
||||
"result", "explanation"], "title": "CalculationResult", "type": "object", "additionalProperties":
|
||||
false, "propertyOrdering": ["operation", "result", "explanation"]}, "thinkingConfig":
|
||||
{"include_thoughts": true}}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
accept:
|
||||
- '*/*'
|
||||
accept-encoding:
|
||||
- ACCEPT-ENCODING-XXX
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '2247'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"text\": \"**Analyzing the User's Statement**\\n\\nOkay,
|
||||
so the user has given me the statement: \\\"The sum of 15 and 27 is 42.\\\"
|
||||
My task is to break this down into a structured JSON object according to the
|
||||
`CalculationResult` schema I'm working with. This is straightforward; let's
|
||||
extract the key pieces:\\n\\nFirst, the **operation**: The word \\\"sum\\\"
|
||||
is a clear indicator that we're dealing with addition. No ambiguity there.\\n\\nNext,
|
||||
the **result**: The statement explicitly tells us that the result \\\"is 42\\\".
|
||||
That's a direct, easily extracted value.\\n\\nFinally, the **explanation**:
|
||||
I can use the entire original statement, \\\"The sum of 15 and 27 is 42.\\\",
|
||||
as the explanation. It's concise and perfectly encapsulates the context of
|
||||
the calculation.\\n\",\n \"thought\": true\n },\n {\n
|
||||
\ \"text\": \"{\\\"operation\\\":\\\"addition\\\",\\\"result\\\":42,\\\"explanation\\\":\\\"The
|
||||
sum of 15 and 27 is 42.\\\"}\"\n }\n ],\n \"role\":
|
||||
\"model\"\n },\n \"finishReason\": \"STOP\",\n \"index\": 0\n
|
||||
\ }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\": 321,\n \"candidatesTokenCount\":
|
||||
28,\n \"totalTokenCount\": 480,\n \"promptTokensDetails\": [\n {\n
|
||||
\ \"modality\": \"TEXT\",\n \"tokenCount\": 321\n }\n ],\n
|
||||
\ \"thoughtsTokenCount\": 131,\n \"serviceTier\": \"standard\"\n },\n
|
||||
\ \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"NZgPasDuKf2VjMcPwc6D4Ak\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Thu, 21 May 2026 23:41:44 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=2425
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
- Origin
|
||||
- X-Origin
|
||||
- Referer
|
||||
X-Content-Type-Options:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
|
||||
@@ -23,8 +23,17 @@ interactions:
|
||||
numbers together and return the sum.", "name": "add_numbers", "parameters_json_schema":
|
||||
{"properties": {"a": {"title": "A", "type": "integer"}, "b": {"title": "B",
|
||||
"type": "integer"}}, "required": ["a", "b"], "type": "object", "additionalProperties":
|
||||
false}}]}], "generationConfig": {"stopSequences": ["\nObservation:"], "thinkingConfig":
|
||||
{"include_thoughts": true}}}'
|
||||
false}}, {"description": "Use this tool to provide your final structured response.
|
||||
Call this tool when you have gathered all necessary information and are ready
|
||||
to provide the final answer in the required format.", "name": "structured_output",
|
||||
"parameters_json_schema": {"properties": {"operation": {"description": "The
|
||||
mathematical operation performed", "title": "Operation", "type": "string"},
|
||||
"result": {"description": "The result of the calculation", "title": "Result",
|
||||
"type": "integer"}, "explanation": {"description": "Brief explanation of the
|
||||
calculation", "title": "Explanation", "type": "string"}}, "required": ["operation",
|
||||
"result", "explanation"], "title": "CalculationResult", "type": "object", "additionalProperties":
|
||||
false, "propertyOrdering": ["operation", "result", "explanation"]}}]}], "generationConfig":
|
||||
{"stopSequences": ["\nObservation:"]}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -35,67 +44,41 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '2016'
|
||||
- '2763'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
- google-genai-sdk/1.49.0 gl-python/3.13.12
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-001:generateContent
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"text\": \"**My Calculation Process**\\n\\nAlright,
|
||||
the user wants me to compute 15 + 27. Simple enough. I have a tool specifically
|
||||
designed for this: `add_numbers(a: int, b: int)`. This is ideal; I'll utilize
|
||||
that.\\n\\nSo, first step: I need to call the `add_numbers` tool. The inputs
|
||||
are straightforward: `a` should be 15 and `b` should be 27. I'll execute that
|
||||
call immediately.\\n\\nOnce I have the result \u2013 the sum \u2013 in hand,
|
||||
I need to format the output. The user is specific about the structure; it
|
||||
needs to be a JSON object conforming to that OpenAPI schema. Specifically,
|
||||
the JSON should include: an \\\"operation\\\" field set to \\\"Addition\\\",
|
||||
a \\\"result\\\" field populated with the calculated sum, and an \\\"explanation\\\"
|
||||
field giving some context, which should be \\\"Added 15 and 27 together.\\\"\\n\\nTherefore,
|
||||
my workflow is: call the tool with the provided numbers, get the sum, and
|
||||
then construct the final JSON object in the required format.\\n\",\n \"thought\":
|
||||
true\n },\n {\n \"text\": \"**My Reasoning for
|
||||
Calculating 15 + 27**\\n\\nOkay, the user wants me to compute 15 plus 27.
|
||||
No problem; that's straightforward. I've got a dedicated `add_numbers` tool
|
||||
for this, which is exactly the right approach. Let's see...I need to call
|
||||
that tool, providing `a=15` and `b=27` as input parameters. Once I receive
|
||||
the sum, I can move on to formatting the result.\\n\\nNow, the important part:
|
||||
the output needs to be a JSON object, specifically structured as dictated
|
||||
by the OpenAPI schema. I need to make sure I include the \\\"operation\\\",
|
||||
\\\"result\\\", and \\\"explanation\\\" fields. \\\"operation\\\" will be
|
||||
\\\"Addition\\\", the \\\"result\\\" will naturally be the sum I get from
|
||||
the tool, and the \\\"explanation\\\" will simply be \\\"Added 15 and 27 together.\\\"
|
||||
That should cover everything, and the user should get a perfectly formatted
|
||||
response.\\n\",\n \"thought\": true\n },\n {\n
|
||||
\ \"functionCall\": {\n \"name\": \"add_numbers\",\n
|
||||
[\n {\n \"functionCall\": {\n \"name\": \"add_numbers\",\n
|
||||
\ \"args\": {\n \"a\": 15,\n \"b\":
|
||||
27\n }\n },\n \"thoughtSignature\": \"CtkGAQw51sf8m1RivBZ7Zp+ZkaqxDdZzSlzepmvlCKak9gl6edIuej/pHxR5dg3qZf89XmHvQ6HigZyzqHcYbSvcRHVGbpNkTr62FC0g10oK5ZEp/r1otLIcgXoVgyFGguJPe/NsfWSX3Uc7ZaYgV0Q2MHBsjUmEHicPH0Pj4Xmbe2I1pK/9DPrzSQqZW3duhLBlBIF9RwZUiltPH6mK+k71l8bN/ebsbbZM18FMXf0wg/7lf3OjvY2wdLDNUD/F2M7T8yfi7NelPWorjIuTGOVWlVRsdGW0QEzuVoyYY7OfbBJC+XsmTumYt+vqgIR3jcQZlA5/3yJdj3e/3mrNmzGt+8VvkjUnu3pz0IUkq2SoTG0+6Y/ajsUI0YA/BFiAXHjrRhH1Nx3ihGWT7E7VzpU/E1ZPFMJIOPLRSpRv8G6ITnjZGthozTZtKLgoHCF7kx4Ni8eVdOh2Us6kY7tYpVabM1dmw0gextEEt+fBMoI+qZGkXdL1YW6SEtQBHh3BGKX8khcrqNvqPZDFzSG0iieMJq7abbEYAIc8zRkeGlWEdX6ES6e+njnFN7JX0Nc32GzOjmpgx9gRhYe+wKonqBQ9RwLLNK+lFuflLTrU3D8jMiPCJyvoRsjdjEc+2JtHXo14ibOVXvZ6oYCHsTEB7f+90/qzcrITESyDBD/rmiT/SqgitBa44MZE9CZ9Ml+BW0xd9FfCy4oLy8w4vszVFDw9Eotr4pEzdCeDeWjMn35taJnWf6jUeF0z/0iyHjbi7XRubJXxI2YuKQ+HRCKX1RFaJWLhmxO4JNBDBqfYZqsO/FefqxjWi2pRzE8U/Upp8Tv/hy1FoN9Abs8W6lPoqgOyEiOcpVkM+u0CgUbf87I1X2EiPpuJF4D9dHlEJqumiPqIGazSLnrjW1qqbM5UpQQuPoTC7q+G092CEnNJBIwrufddZPDfD9rqINpmMa+7OswldKViVaCWR3VsgrSXJj7lVRntCyE2atWxTvtQVnR/JLDdyc98CAUChtAPnC4K/K3OVI4jffQQsHmfeOnTyg0n2VnZ6Yhgo0lMdE4IfMrNOWOuNvHodeHisD2yXjvTCgScO8B3s+EJTvenHMert3nRgjNRmFZ0cRNSjbTeG0UlB9s7Uy0uyrn5ODkKIgEMOdbH9yJU53jInG9boFeMXb1qif47Pc72taZkl6ZaMK4=\"\n
|
||||
\ }\n ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0,\n \"finishMessage\": \"Model generated
|
||||
function call(s).\"\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
383,\n \"candidatesTokenCount\": 22,\n \"totalTokenCount\": 658,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 383\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 253,\n \"serviceTier\": \"standard\"\n
|
||||
\ },\n \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"qagPas37Ba2R-8YPzYzI8AY\"\n}\n"
|
||||
27\n }\n }\n }\n ],\n \"role\":
|
||||
\"model\"\n },\n \"finishReason\": \"STOP\",\n \"avgLogprobs\":
|
||||
4.3579145442760951e-06\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
377,\n \"candidatesTokenCount\": 7,\n \"totalTokenCount\": 384,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 377\n
|
||||
\ }\n ],\n \"candidatesTokensDetails\": [\n {\n \"modality\":
|
||||
\"TEXT\",\n \"tokenCount\": 7\n }\n ]\n },\n \"modelVersion\":
|
||||
\"gemini-2.0-flash-001\",\n \"responseId\": \"vVefaYDSOouXjMcPicLCsQY\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Fri, 22 May 2026 00:51:56 GMT
|
||||
- Wed, 25 Feb 2026 20:12:46 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=3892
|
||||
- gfet4t7; dur=718
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
@@ -106,8 +89,6 @@ interactions:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
@@ -131,17 +112,27 @@ interactions:
|
||||
the schema format.\n\nDo not include the OpenAPI schema in the final output.
|
||||
Ensure the final output does not include any code block markers like ```json
|
||||
or ```python."}], "role": "user"}, {"parts": [{"functionCall": {"args": {"a":
|
||||
15, "b": 27}, "name": "add_numbers"}, "thoughtSignature": "CtkGAQw51sf8m1RivBZ7Zp-ZkaqxDdZzSlzepmvlCKak9gl6edIuej_pHxR5dg3qZf89XmHvQ6HigZyzqHcYbSvcRHVGbpNkTr62FC0g10oK5ZEp_r1otLIcgXoVgyFGguJPe_NsfWSX3Uc7ZaYgV0Q2MHBsjUmEHicPH0Pj4Xmbe2I1pK_9DPrzSQqZW3duhLBlBIF9RwZUiltPH6mK-k71l8bN_ebsbbZM18FMXf0wg_7lf3OjvY2wdLDNUD_F2M7T8yfi7NelPWorjIuTGOVWlVRsdGW0QEzuVoyYY7OfbBJC-XsmTumYt-vqgIR3jcQZlA5_3yJdj3e_3mrNmzGt-8VvkjUnu3pz0IUkq2SoTG0-6Y_ajsUI0YA_BFiAXHjrRhH1Nx3ihGWT7E7VzpU_E1ZPFMJIOPLRSpRv8G6ITnjZGthozTZtKLgoHCF7kx4Ni8eVdOh2Us6kY7tYpVabM1dmw0gextEEt-fBMoI-qZGkXdL1YW6SEtQBHh3BGKX8khcrqNvqPZDFzSG0iieMJq7abbEYAIc8zRkeGlWEdX6ES6e-njnFN7JX0Nc32GzOjmpgx9gRhYe-wKonqBQ9RwLLNK-lFuflLTrU3D8jMiPCJyvoRsjdjEc-2JtHXo14ibOVXvZ6oYCHsTEB7f-90_qzcrITESyDBD_rmiT_SqgitBa44MZE9CZ9Ml-BW0xd9FfCy4oLy8w4vszVFDw9Eotr4pEzdCeDeWjMn35taJnWf6jUeF0z_0iyHjbi7XRubJXxI2YuKQ-HRCKX1RFaJWLhmxO4JNBDBqfYZqsO_FefqxjWi2pRzE8U_Upp8Tv_hy1FoN9Abs8W6lPoqgOyEiOcpVkM-u0CgUbf87I1X2EiPpuJF4D9dHlEJqumiPqIGazSLnrjW1qqbM5UpQQuPoTC7q-G092CEnNJBIwrufddZPDfD9rqINpmMa-7OswldKViVaCWR3VsgrSXJj7lVRntCyE2atWxTvtQVnR_JLDdyc98CAUChtAPnC4K_K3OVI4jffQQsHmfeOnTyg0n2VnZ6Yhgo0lMdE4IfMrNOWOuNvHodeHisD2yXjvTCgScO8B3s-EJTvenHMert3nRgjNRmFZ0cRNSjbTeG0UlB9s7Uy0uyrn5ODkKIgEMOdbH9yJU53jInG9boFeMXb1qif47Pc72taZkl6ZaMK4="}],
|
||||
"role": "model"}, {"parts": [{"functionResponse": {"name": "add_numbers", "response":
|
||||
{"result": 42}}}], "role": "user"}], "systemInstruction": {"parts": [{"text":
|
||||
"You are Calculator. You are a calculator assistant that uses tools to compute
|
||||
results.\nYour personal goal is: Perform calculations using available tools"}],
|
||||
"role": "user"}, "tools": [{"functionDeclarations": [{"description": "Add two
|
||||
numbers together and return the sum.", "name": "add_numbers", "parameters_json_schema":
|
||||
{"properties": {"a": {"title": "A", "type": "integer"}, "b": {"title": "B",
|
||||
"type": "integer"}}, "required": ["a", "b"], "type": "object", "additionalProperties":
|
||||
false}}]}], "generationConfig": {"stopSequences": ["\nObservation:"], "thinkingConfig":
|
||||
{"include_thoughts": true}}}'
|
||||
15, "b": 27}, "name": "add_numbers"}}], "role": "model"}, {"parts": [{"functionResponse":
|
||||
{"name": "add_numbers", "response": {"result": 42}}}], "role": "user"}, {"parts":
|
||||
[{"text": "Analyze the tool result. If requirements are met, provide the Final
|
||||
Answer. Otherwise, call the next tool. Deliver only the answer without meta-commentary."}],
|
||||
"role": "user"}], "systemInstruction": {"parts": [{"text": "You are Calculator.
|
||||
You are a calculator assistant that uses tools to compute results.\nYour personal
|
||||
goal is: Perform calculations using available tools"}], "role": "user"}, "tools":
|
||||
[{"functionDeclarations": [{"description": "Add two numbers together and return
|
||||
the sum.", "name": "add_numbers", "parameters_json_schema": {"properties": {"a":
|
||||
{"title": "A", "type": "integer"}, "b": {"title": "B", "type": "integer"}},
|
||||
"required": ["a", "b"], "type": "object", "additionalProperties": false}}, {"description":
|
||||
"Use this tool to provide your final structured response. Call this tool when
|
||||
you have gathered all necessary information and are ready to provide the final
|
||||
answer in the required format.", "name": "structured_output", "parameters_json_schema":
|
||||
{"properties": {"operation": {"description": "The mathematical operation performed",
|
||||
"title": "Operation", "type": "string"}, "result": {"description": "The result
|
||||
of the calculation", "title": "Result", "type": "integer"}, "explanation": {"description":
|
||||
"Brief explanation of the calculation", "title": "Explanation", "type": "string"}},
|
||||
"required": ["operation", "result", "explanation"], "title": "CalculationResult",
|
||||
"type": "object", "additionalProperties": false, "propertyOrdering": ["operation",
|
||||
"result", "explanation"]}}]}], "generationConfig": {"stopSequences": ["\nObservation:"]}}'
|
||||
headers:
|
||||
User-Agent:
|
||||
- X-USER-AGENT-XXX
|
||||
@@ -152,50 +143,42 @@ interactions:
|
||||
connection:
|
||||
- keep-alive
|
||||
content-length:
|
||||
- '3441'
|
||||
- '3166'
|
||||
content-type:
|
||||
- application/json
|
||||
host:
|
||||
- generativelanguage.googleapis.com
|
||||
x-goog-api-client:
|
||||
- google-genai-sdk/1.65.0 gl-python/3.13.3
|
||||
- google-genai-sdk/1.49.0 gl-python/3.13.12
|
||||
x-goog-api-key:
|
||||
- X-GOOG-API-KEY-XXX
|
||||
method: POST
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent
|
||||
uri: https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-001:generateContent
|
||||
response:
|
||||
body:
|
||||
string: "{\n \"candidates\": [\n {\n \"content\": {\n \"parts\":
|
||||
[\n {\n \"text\": \"**My Calculation and OpenAPI Formatting**\\n\\nOkay,
|
||||
so I've just crunched the numbers, 15 plus 27, and the answer, as expected,
|
||||
is 42. Now comes the formatting, the part I truly appreciate. It's time to
|
||||
translate this into the precise structure that the OpenAPI schema dictates.\\n\\nLet's
|
||||
see\u2026 I need to populate three key fields: `operation`, `result`, and
|
||||
`explanation`. This is straightforward. For `operation`, I'll enter \\\"Addition,\\\"
|
||||
because, well, that's what I did! For `result`, the answer I painstakingly
|
||||
produced, 42. And for `explanation`, a concise note, \\\"Added 15 and 27 together.\\\"
|
||||
Perfect. That should do the trick. Now I can move on to the next task.\\n\",\n
|
||||
\ \"thought\": true\n },\n {\n \"text\":
|
||||
\"{\\n \\\"operation\\\": \\\"Addition\\\",\\n \\\"result\\\": 42,\\n \\\"explanation\\\":
|
||||
\\\"Added 15 and 27 together.\\\"\\n}\",\n \"thoughtSignature\":
|
||||
\"CrcDAQw51sd+vh7cJvN7WGZKQIJGL6Xtr/+CNnL2r9YWGHv5EBrOm/Qdzr4eK0eyrJhuJGBZg5V5XakEuLMULUvth7stE+FTz16F5Vzx2yKMuM5Ictv/DlI7s4Z5WFaI5HJVJTojOhW9K/1TM8y48+eStJre8Qyz3tOvFg1DPEau6JCk+1uoRil2RoZHxFQpd0LaDhl4sKZkRr1e5c2gtfZiK3NHR3ipbRejIOGjDQah4+q4D6ASTiHZxHCBIjAP4HH8DF40oylF6mQR1WHWezKzvkZ0sz3ydPGExM5+lFOE8z1NUpqH2kJ3PfzdrbX2VccIT+5pWz9NsIW8N1JYbPvb7xKENh7mTI+tmCtuAiO9DTwWUf450OHNWdrHQPxn3MMT10+4RMzKBeDAjEFVZ6M68CyUDTJ0uDtqJZ6SXs3ZdmmLGQY1lAk29r0eklaMJLk226uMUKCXlHKwyDbJVH3+SwGkgU+Am81AiekV5ZWQjfe3gUN8ojOLSNvpAfaf/K8ZvR4uGCEMs2pJ2sqI6sCIE9w9+u2biTattqWtcO+wmPXZ/CwU/ASXHlBqt55cvB2XyFTXO7kQGw==\"\n
|
||||
\ }\n ],\n \"role\": \"model\"\n },\n \"finishReason\":
|
||||
\"STOP\",\n \"index\": 0\n }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\":
|
||||
421,\n \"candidatesTokenCount\": 36,\n \"totalTokenCount\": 560,\n \"promptTokensDetails\":
|
||||
[\n {\n \"modality\": \"TEXT\",\n \"tokenCount\": 421\n
|
||||
\ }\n ],\n \"thoughtsTokenCount\": 103,\n \"serviceTier\": \"standard\"\n
|
||||
\ },\n \"modelVersion\": \"gemini-2.5-flash\",\n \"responseId\": \"ragPaseeA6nT_uMP653cmAc\"\n}\n"
|
||||
[\n {\n \"functionCall\": {\n \"name\": \"structured_output\",\n
|
||||
\ \"args\": {\n \"result\": 42,\n \"explanation\":
|
||||
\"15 + 27 = 42\",\n \"operation\": \"addition\"\n }\n
|
||||
\ }\n }\n ],\n \"role\": \"model\"\n },\n
|
||||
\ \"finishReason\": \"STOP\",\n \"avgLogprobs\": -0.07498827245500353\n
|
||||
\ }\n ],\n \"usageMetadata\": {\n \"promptTokenCount\": 421,\n \"candidatesTokenCount\":
|
||||
18,\n \"totalTokenCount\": 439,\n \"promptTokensDetails\": [\n {\n
|
||||
\ \"modality\": \"TEXT\",\n \"tokenCount\": 421\n }\n ],\n
|
||||
\ \"candidatesTokensDetails\": [\n {\n \"modality\": \"TEXT\",\n
|
||||
\ \"tokenCount\": 18\n }\n ]\n },\n \"modelVersion\": \"gemini-2.0-flash-001\",\n
|
||||
\ \"responseId\": \"vlefac7bJb6TjMcPzYWh0Ag\"\n}\n"
|
||||
headers:
|
||||
Alt-Svc:
|
||||
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
|
||||
Content-Type:
|
||||
- application/json; charset=UTF-8
|
||||
Date:
|
||||
- Fri, 22 May 2026 00:51:59 GMT
|
||||
- Wed, 25 Feb 2026 20:12:47 GMT
|
||||
Server:
|
||||
- scaffolding on HTTPServer2
|
||||
Server-Timing:
|
||||
- gfet4t7; dur=2377
|
||||
- gfet4t7; dur=774
|
||||
Transfer-Encoding:
|
||||
- chunked
|
||||
Vary:
|
||||
@@ -206,8 +189,6 @@ interactions:
|
||||
- X-CONTENT-TYPE-XXX
|
||||
X-Frame-Options:
|
||||
- X-FRAME-OPTIONS-XXX
|
||||
X-Gemini-Service-Tier:
|
||||
- standard
|
||||
X-XSS-Protection:
|
||||
- '0'
|
||||
status:
|
||||
|
||||
@@ -923,7 +923,7 @@ def test_anthropic_agent_kickoff_structured_output_with_tools():
|
||||
role="Calculator",
|
||||
goal="Perform calculations using available tools",
|
||||
backstory="You are a calculator assistant that uses tools to compute results.",
|
||||
llm=LLM(model="anthropic/claude-sonnet-4-6"),
|
||||
llm=LLM(model="anthropic/claude-3-5-haiku-20241022"),
|
||||
tools=[add_numbers],
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
@@ -844,7 +844,7 @@ def test_bedrock_agent_kickoff_structured_output_without_tools():
|
||||
role="Analyst",
|
||||
goal="Provide structured analysis on topics",
|
||||
backstory="You are an expert analyst who provides clear, structured insights.",
|
||||
llm=LLM(model="bedrock/us.anthropic.claude-sonnet-4-6"),
|
||||
llm=LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"),
|
||||
tools=[],
|
||||
verbose=True,
|
||||
)
|
||||
@@ -886,7 +886,7 @@ def test_bedrock_agent_kickoff_structured_output_with_tools():
|
||||
role="Calculator",
|
||||
goal="Perform calculations using available tools",
|
||||
backstory="You are a calculator assistant that uses tools to compute results.",
|
||||
llm=LLM(model="bedrock/us.anthropic.claude-sonnet-4-6"),
|
||||
llm=LLM(model="bedrock/anthropic.claude-3-sonnet-20240229-v1:0"),
|
||||
tools=[add_numbers],
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
@@ -17,7 +17,7 @@ SKIP_REASON = "VCR does not support aiobotocore async HTTP client"
|
||||
@pytest.mark.skip(reason=SKIP_REASON)
|
||||
async def test_bedrock_async_basic_call():
|
||||
"""Test basic async call with Bedrock."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6")
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-3-5-sonnet-20241022-v2:0")
|
||||
|
||||
result = await llm.acall("Say hello")
|
||||
|
||||
@@ -31,7 +31,7 @@ async def test_bedrock_async_basic_call():
|
||||
@pytest.mark.skip(reason=SKIP_REASON)
|
||||
async def test_bedrock_async_with_temperature():
|
||||
"""Test async call with temperature parameter."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6", temperature=0.1)
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-3-5-sonnet-20241022-v2:0", temperature=0.1)
|
||||
|
||||
result = await llm.acall("Say the word 'test' once")
|
||||
|
||||
@@ -44,7 +44,7 @@ async def test_bedrock_async_with_temperature():
|
||||
@pytest.mark.skip(reason=SKIP_REASON)
|
||||
async def test_bedrock_async_with_max_tokens():
|
||||
"""Test async call with max_tokens parameter."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6", max_tokens=10)
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-3-5-sonnet-20241022-v2:0", max_tokens=10)
|
||||
|
||||
result = await llm.acall("Write a very long story about a dragon.")
|
||||
|
||||
@@ -58,7 +58,7 @@ async def test_bedrock_async_with_max_tokens():
|
||||
@pytest.mark.skip(reason=SKIP_REASON)
|
||||
async def test_bedrock_async_with_system_message():
|
||||
"""Test async call with system message."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6")
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-3-5-sonnet-20241022-v2:0")
|
||||
|
||||
messages = [
|
||||
{"role": "system", "content": "You are a helpful assistant."},
|
||||
@@ -76,7 +76,7 @@ async def test_bedrock_async_with_system_message():
|
||||
@pytest.mark.skip(reason=SKIP_REASON)
|
||||
async def test_bedrock_async_conversation():
|
||||
"""Test async call with conversation history."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6")
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-3-5-sonnet-20241022-v2:0")
|
||||
|
||||
messages = [
|
||||
{"role": "user", "content": "My name is Alice."},
|
||||
@@ -95,7 +95,7 @@ async def test_bedrock_async_conversation():
|
||||
@pytest.mark.skip(reason=SKIP_REASON)
|
||||
async def test_bedrock_async_multiple_calls():
|
||||
"""Test making multiple async calls in sequence."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6")
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-3-5-sonnet-20241022-v2:0")
|
||||
|
||||
result1 = await llm.acall("What is 1+1?")
|
||||
result2 = await llm.acall("What is 2+2?")
|
||||
@@ -112,9 +112,10 @@ async def test_bedrock_async_multiple_calls():
|
||||
async def test_bedrock_async_with_parameters():
|
||||
"""Test async call with multiple parameters."""
|
||||
llm = LLM(
|
||||
model="bedrock/us.anthropic.claude-sonnet-4-6",
|
||||
model="bedrock/us.anthropic.claude-3-5-sonnet-20241022-v2:0",
|
||||
temperature=0.7,
|
||||
max_tokens=100,
|
||||
top_p=0.9
|
||||
)
|
||||
|
||||
result = await llm.acall("Tell me a short fact")
|
||||
|
||||
@@ -969,7 +969,7 @@ def test_gemini_crew_structured_output_with_tools():
|
||||
role="Calculator",
|
||||
goal="Perform calculations using available tools",
|
||||
backstory="You are a calculator assistant that uses tools to compute results.",
|
||||
llm=LLM(model="google/gemini-2.5-flash"),
|
||||
llm=LLM(model="google/gemini-2.0-flash-001"),
|
||||
tools=[add_numbers],
|
||||
)
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ class TestBedrockMultimodalIntegration:
|
||||
@pytest.mark.vcr()
|
||||
def test_describe_image(self, test_image_bytes: bytes) -> None:
|
||||
"""Test Bedrock Claude can describe an image."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6")
|
||||
llm = LLM(model="bedrock/anthropic.claude-3-haiku-20240307-v1:0")
|
||||
files = {"image": ImageFile(source=test_image_bytes)}
|
||||
|
||||
messages = _build_multimodal_message(
|
||||
@@ -308,7 +308,7 @@ class TestBedrockMultimodalIntegration:
|
||||
@pytest.mark.vcr()
|
||||
def test_analyze_pdf(self) -> None:
|
||||
"""Test Bedrock Claude can analyze a PDF."""
|
||||
llm = LLM(model="bedrock/us.anthropic.claude-sonnet-4-6")
|
||||
llm = LLM(model="bedrock/anthropic.claude-3-haiku-20240307-v1:0")
|
||||
files = {"document": PDFFile(source=MINIMAL_PDF)}
|
||||
|
||||
messages = _build_multimodal_message(
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
"""Tests for stdio transport."""
|
||||
|
||||
from unittest.mock import AsyncMock, MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
import crewai.mcp.transports.stdio as stdio_transport_module
|
||||
from crewai.mcp.transports.stdio import StdioTransport
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_ambient_env_does_not_leak_to_server(monkeypatch):
|
||||
"""Ambient env vars outside the MCP SDK's default allowlist must not reach the server.
|
||||
|
||||
Regression guard: previously StdioTransport did os.environ.copy(), which leaked
|
||||
every ambient var (COMPANY_SECRET, AWS_*, etc.) into every spawned MCP server.
|
||||
"""
|
||||
monkeypatch.setenv("COMPANY_SECRET", "leaked")
|
||||
monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "leaked")
|
||||
|
||||
transport = StdioTransport(
|
||||
command="python",
|
||||
args=["server.py"],
|
||||
env={"OPENAI_API_KEY": "sk-test"},
|
||||
)
|
||||
|
||||
captured: dict[str, dict[str, str] | None] = {}
|
||||
|
||||
fake_ctx = MagicMock()
|
||||
fake_ctx.__aenter__ = AsyncMock(return_value=(MagicMock(), MagicMock()))
|
||||
fake_ctx.__aexit__ = AsyncMock(return_value=None)
|
||||
|
||||
def fake_stdio_client(server_params):
|
||||
captured["env"] = server_params.env
|
||||
return fake_ctx
|
||||
|
||||
with (
|
||||
patch("mcp.client.stdio.stdio_client", side_effect=fake_stdio_client),
|
||||
patch(
|
||||
"mcp.client.stdio.get_default_environment",
|
||||
return_value={"PATH": "/usr/bin", "HOME": "/home/user"},
|
||||
),
|
||||
):
|
||||
await transport.connect()
|
||||
|
||||
env = captured["env"]
|
||||
assert env is not None
|
||||
assert "COMPANY_SECRET" not in env
|
||||
assert "AWS_SECRET_ACCESS_KEY" not in env
|
||||
assert env.get("OPENAI_API_KEY") == "sk-test"
|
||||
assert env.get("PATH") == "/usr/bin"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_env_overrides_default_environment():
|
||||
"""User-supplied env values must override keys returned by get_default_environment()."""
|
||||
transport = StdioTransport(
|
||||
command="python",
|
||||
args=["server.py"],
|
||||
env={"PATH": "/custom/bin"},
|
||||
)
|
||||
|
||||
captured: dict[str, dict[str, str] | None] = {}
|
||||
|
||||
fake_ctx = MagicMock()
|
||||
fake_ctx.__aenter__ = AsyncMock(return_value=(MagicMock(), MagicMock()))
|
||||
fake_ctx.__aexit__ = AsyncMock(return_value=None)
|
||||
|
||||
def fake_stdio_client(server_params):
|
||||
captured["env"] = server_params.env
|
||||
return fake_ctx
|
||||
|
||||
with (
|
||||
patch("mcp.client.stdio.stdio_client", side_effect=fake_stdio_client),
|
||||
patch(
|
||||
"mcp.client.stdio.get_default_environment",
|
||||
return_value={"PATH": "/usr/bin"},
|
||||
),
|
||||
):
|
||||
await transport.connect()
|
||||
|
||||
assert captured["env"]["PATH"] == "/custom/bin"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_env_filter_hook_runs_after_merge():
|
||||
"""An extension-supplied env_filter_hook must be applied to the final env."""
|
||||
transport = StdioTransport(
|
||||
command="python",
|
||||
args=["server.py"],
|
||||
env={"OPENAI_API_KEY": "sk-test", "AWS_SECRET_ACCESS_KEY": "should-strip"},
|
||||
)
|
||||
|
||||
captured: dict[str, dict[str, str] | None] = {}
|
||||
|
||||
fake_ctx = MagicMock()
|
||||
fake_ctx.__aenter__ = AsyncMock(return_value=(MagicMock(), MagicMock()))
|
||||
fake_ctx.__aexit__ = AsyncMock(return_value=None)
|
||||
|
||||
def fake_stdio_client(server_params):
|
||||
captured["env"] = server_params.env
|
||||
return fake_ctx
|
||||
|
||||
def drop_aws(env):
|
||||
return {k: v for k, v in env.items() if not k.startswith("AWS_")}
|
||||
|
||||
original_hook = stdio_transport_module._env_filter_hook
|
||||
stdio_transport_module._env_filter_hook = drop_aws
|
||||
try:
|
||||
with (
|
||||
patch("mcp.client.stdio.stdio_client", side_effect=fake_stdio_client),
|
||||
patch(
|
||||
"mcp.client.stdio.get_default_environment",
|
||||
return_value={"PATH": "/usr/bin"},
|
||||
),
|
||||
):
|
||||
await transport.connect()
|
||||
finally:
|
||||
stdio_transport_module._env_filter_hook = original_hook
|
||||
|
||||
env = captured["env"]
|
||||
assert "AWS_SECRET_ACCESS_KEY" not in env
|
||||
assert env.get("OPENAI_API_KEY") == "sk-test"
|
||||
assert env.get("PATH") == "/usr/bin"
|
||||
@@ -42,7 +42,7 @@ GEMINI_MODELS = [
|
||||
]
|
||||
|
||||
BEDROCK_MODELS = [
|
||||
"bedrock/us.anthropic.claude-sonnet-4-6",
|
||||
"bedrock/anthropic.claude-3-haiku-20240307-v1:0",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
"""CrewAI development tools."""
|
||||
|
||||
__version__ = "1.14.6a2"
|
||||
__version__ = "1.14.6a1"
|
||||
|
||||
Reference in New Issue
Block a user