Compare commits

...

122 Commits

Author SHA1 Message Date
Brandon Hancock
06350a74ef Clean up end of docs 2024-07-31 10:57:09 -04:00
Brandon Hancock
6aab0ebcbc Remove overly complicated test 2024-07-31 10:12:37 -04:00
Brandon Hancock
41df368156 Merge branch 'main' into feature/procedure_v2 2024-07-31 09:49:48 -04:00
João Moura
c93b85ac53 Preparing for new version 2024-07-30 19:21:18 -04:00
Lorenze Jay
6378f6caec WIP fixed mypy src types (#1036) 2024-07-30 10:59:50 -07:00
Brandon Hancock
072044c537 Rename variables based on joaos feedback 2024-07-30 09:54:11 -04:00
Brandon Hancock
e1a03ad97d Change names 2024-07-30 09:43:36 -04:00
Eduardo Chiarotti
d824db82a3 feat: Add execution time to both task and testing feature (#1031)
* feat: Add execution time to both task and testing feature

* feat: Remove unused functions

* feat: change test_crew to evalaute_crew to avoid issues with testing libs

* feat: fix tests
2024-07-29 23:17:07 -03:00
Matt Young
de6b597eff telemetry.py - fix typo in comment. (#1020) 2024-07-29 23:03:51 -03:00
Deepak Tammali
6111d05219 docs: Fix crewai-tools package name typo in getting-started docs (#1026) 2024-07-29 23:03:32 -03:00
Monarch Wadia
f83c91d612 Fixed package name typo in pip install command (#1029)
Changed `pip install crewai-tools` to `pip install crewai-tools`
2024-07-29 23:02:48 -03:00
Mackensie Alvarez
c8f360414e Update Start-a-New-CrewAI-Project-Template-Method.md (#1030) 2024-07-29 23:02:18 -03:00
Brandon Hancock
910c8df1a7 Update pipeline to use UsageMetric 2024-07-29 16:00:57 -04:00
Brandon Hancock
b9177f2d04 Merge branch 'brandon/cre-117-create-a-type-for-usage-metrics' into feature/procedure_v2 2024-07-29 15:55:11 -04:00
Brandon Hancock
03eafe1671 Fix 1 type error in pipeline 2024-07-29 15:54:49 -04:00
Brandon Hancock
f2830d9c7a Drop todo 2024-07-29 15:51:14 -04:00
Brandon Hancock
619806f80d Fix tests that were checking usage metrics 2024-07-29 15:48:48 -04:00
Brandon Hancock
e3182d135a WIP. Converting usage metrics from a dict to an object 2024-07-29 15:30:54 -04:00
Brandon Hancock
75c7aaf585 Merge branch 'main' into feature/procedure_v2 2024-07-29 14:27:28 -04:00
Brandon Hancock (bhancock_ai)
fa4393d77e Add in missing triple quote and execution time to resume agent functionality. (#1025)
* Add in missing triple quote and execution time to resume agent functionality

* Fixing broken kwargs and other issues causing our tests to fail
2024-07-29 14:39:02 -03:00
Brandon Hancock
083949fc23 Merge branch 'main' into feature/procedure_v2 2024-07-29 12:48:53 -04:00
Brandon Hancock
04de7730fa Add doc strings 2024-07-29 12:44:10 -04:00
Brandon Hancock
de6950046d Add developer notes to explain what is going on in pipelines. 2024-07-29 12:36:03 -04:00
Brandon Hancock
cb2276dc7d Add in Eduardo feedback. Still need to add in more commentary describing the design decisions for pipeline 2024-07-29 12:20:18 -04:00
Rip&Tear
25c314befc Minor fixes and updates (#1019)
Co-authored-by: theCyberTech <mattrapidb@gmail.com>
2024-07-29 03:24:23 -03:00
Rip&Tear
2fe79e68cd Small 404 error fixes (#1018)
* Updated Docs:  New Getting started section + content update / addition

* fixed indentation issue

* Minor updates to fix typos

* Fixed up 404 error on latest commit

---------

Co-authored-by: theCyberTech <the_t3ch@pm.me>
Co-authored-by: theCyberTech <mattrapidb@gmail.com>
2024-07-28 22:01:04 -03:00
Nuraly
37d05a2365 Update Force-Tool-Ouput-as-Result.md (#964)
I think there is some mistake, because there is no such parameter as force_output_result, and as the code shows, the correct parameter result_as_answer is set during agent creation, not task.
2024-07-28 15:41:56 -03:00
Carine Bruyndoncx
0111d261a4 Update Crews.md - correct result variable to crew_output (#972) 2024-07-28 15:40:36 -03:00
Taleb
0a23e1dc13 Performed spell check across the rest of code base, and enahnced the yaml paraser code a little (#895)
* Performed spell check across the entire documentation

Thank you once again!

* Performed spell check across the most of code base
Folders been checked:
- agents
- cli
- memory
- project
- tasks
- telemetry
- tools
- translations

* Trying to add a max_token for the agents, so they limited by number of tokens.

* Performed spell check across the rest of code base, and enahnced the yaml paraser code a little

* Small change in the main agent doc

* Improve _save_file method to handle both dict and str inputs

- Add check for dict type input
- Use json.dump for dict serialization
- Convert non-dict inputs to string
- Remove type ignore comments

---------

Co-authored-by: João Moura <joaomdmoura@gmail.com>
2024-07-28 15:39:54 -03:00
Henri Wenlin
ef5ff71346 feat: add verbose option for printing in ToolUsage (#990) 2024-07-28 15:12:10 -03:00
Samuel Mallet
1697b4cacb Add docs for new parameters to SerperDevTool (#993) 2024-07-28 15:09:55 -03:00
Taleb
6b4710a8d1 Improve _save_file method to handle both dict and str inputs (#1011)
- Add check for dict type input
- Use json.dump for dict serialization
- Convert non-dict inputs to string
- Remove type ignore comments
2024-07-28 15:03:18 -03:00
Lennex Zinyando
6f2a8f08ba Fixes getting started section links (#1016) 2024-07-28 15:02:41 -03:00
João Moura
4e6abf596d updating test 2024-07-28 13:23:03 -04:00
Rip&Tear
9018e2ab6a Docs update (#1008)
* Updated Docs:  New Getting started section + content update / addition

* fixed indentation issue

* Minor updates to fix typos

---------

Co-authored-by: theCyberTech <the_t3ch@pm.me>
2024-07-28 11:55:09 -03:00
ResearchAI
99d023c5f3 Update reset_memories_command.py (#974) 2024-07-26 14:40:47 -07:00
Brandon Hancock (bhancock_ai)
da7d8256eb Json Task Output Truncation with Escape Characters (#1009)
* Fixed special character issue when converting json to models. Added numerous tests to ensure thigns work properly.

* Fix linting error and cleaned up tests

* Fix customer_converter_cls test failure

* Fixed tests. Thank you lorenze for pointing that out. added a few more to ensure converter creation works properly

* Address lorenze feedback

* Fix linting issues
2024-07-26 17:27:01 -04:00
Brandon Hancock (bhancock_ai)
88bffaa0d0 Merge pull request #1012 from crewAIInc/fix/breaking-test-task-eval
fix test due to asserting instructions model_schema change
2024-07-26 16:55:26 -04:00
Lorenze Jay
1159140d9f fix test due to asserting instructions model_schema change 2024-07-26 13:37:44 -07:00
Lorenze Jay
5ac7050f7a Patch/non gpt model pydantic output (#1003)
* patching for non-gpt model

* removal of json_object tool name assignment

* fixed issue for smaller models due to instructions prompt

* fixing for ollama llama3 models

* closing brackets

* removed not used and fixes
2024-07-26 10:57:56 -07:00
Lorenze Jay
8b513de64c hierarchical process unblocked for async tasks (#995)
* WIP: hierarchical unblock for async tasks

* added better test

* update name change

* added more test and crew manager cleanup

* remove prints

* code cleanup, no need to pass manager
2024-07-26 10:55:51 -07:00
Eduardo Chiarotti
144e6d203f feat: add ability to set LLM for AgentPLanner on Crew (#1001)
* feat: add ability to set LLM for AgentPLanner on Crew

* feat: fixes issue on instantiating the ChatOpenAI on the crew

* docs: add docs for the planning_llm new parameter

* docs: change message to ChatOpenAI llm

* feat: add tests
2024-07-26 14:24:29 -03:00
Eduardo Chiarotti
2d2154ed65 feat: add crew Testing/Evaluating feature (#998)
* feat: add crew Testing/evalauting feature

* feat: add docs and add unit test

* feat: improve testing output table

* feat: add tests

* feat: fix type checking issue

* feat: add raise ValueError when testing if output is not the expected

* docs: add docs for Testing

* feat: improve tests and fix some issue

* feat: back to sync

* feat: change opdeai model

* feat: fix test
2024-07-26 14:23:51 -03:00
Brandon Hancock
d9e60c8b57 Drop router for now. will add in separately 2024-07-25 14:29:17 -04:00
Brandon Hancock
2119ba7c32 Starting to work on router 2024-07-25 09:33:05 -04:00
Brandon Hancock
b00bc44921 Add back in commentary at top of pipeline file 2024-07-24 11:27:47 -04:00
Brandon Hancock (bhancock_ai)
2d086ab596 Merge pull request #994 from crewAIInc/fix/getting-started-docs
fixed bullet points for crew yaml annoations
2024-07-23 14:36:45 -04:00
Lorenze Jay
776c67cc0f clearer usage for crewai create command 2024-07-23 11:32:25 -07:00
Lorenze Jay
78ef490646 fixed bullet points for crew yaml annoations 2024-07-23 11:31:09 -07:00
Brandon Hancock
6b4ebe16d0 Update Pipeline docs 2024-07-23 11:24:57 -04:00
Brandon Hancock
602ade4cc4 Update pipeline to properly process input and ouput dictionary 2024-07-23 11:12:55 -04:00
Lorenze Jay
4da5cc9778 Feat yaml config all attributes (#985)
* WIP: yaml proper mapping for agents and agent

* WIP: added output_json and output_pydantic setup

* WIP: core logic added, need cleanup

* code cleanup

* updated docs and example template to use yaml to reference agents within tasks

* cleanup type errors

* Update Start-a-New-CrewAI-Project.md

---------

Co-authored-by: João Moura <joaomdmoura@gmail.com>
2024-07-23 00:21:01 -03:00
Brandon Hancock
471c5b970c Update docs for pipeline 2024-07-22 19:28:32 -04:00
Brandon Hancock
33d9828edc Implemented additional tests for pipeline. One test is failing. Need team support 2024-07-22 16:35:16 -04:00
Eduardo Chiarotti
6930656897 feat: add crewai test feature (#984)
* feat: add crewai test feature

* fix: remove unused import

* feat: update docstirng

* fix: tests
2024-07-22 17:21:05 -03:00
Brandon Hancock
e95ef6fca9 Merge branch 'main' into feature/procedure_v2 2024-07-22 09:55:03 -04:00
João Moura
349753a013 prepping new version 2024-07-20 12:26:32 -04:00
Eduardo Chiarotti
f53a3a00e1 fix: planning feature output (#969)
* fix: planning feature output

* fix: add validation for planning result
2024-07-20 11:56:53 -03:00
Brandon Hancock
afd6bff159 Fix pipelineoutput to look more like crewoutput and taskoutput 2024-07-19 15:18:19 -04:00
Brandon Hancock
392490c48b new pipeline flow with traces and usage metrics working. need to add more tests and make sure PipelineOutput behaves likew CrewOutput 2024-07-19 14:39:31 -04:00
João Moura
e2113fe417 preparing new verions 2024-07-19 13:22:28 -04:00
Eduardo Chiarotti
f9288295e6 fix: agent missing fix (#966) 2024-07-19 13:15:33 -03:00
João Moura
fcc57f2fc0 rmeoving extra logging 2024-07-19 01:16:15 -04:00
Dev Khant
5cb6ee9eeb Docs: Update info about tools (#896) 2024-07-19 01:38:42 -03:00
ariel
b38f0825e7 Fix broken link to the installation guide (#912)
Updated the installation guide link to use the absolute URL instead of a relative path, ensuring it correctly points to 'https://docs.crewai.com/how-to/Installing-CrewAI/'.
2024-07-19 01:37:54 -03:00
Salman Faroz
f51e94dede Update Crews.md (#889)
To solve :
I encountered an error while trying to use the tool. This was the error: DuckDuckGoSearchRun._run() got an unexpected keyword argument 'q'.
 Tool duckduckgo_search accepts these inputs: A wrapper around DuckDuckGo Search. Useful for when you need to answer questions about current events. Input should be a search query.

refer : https://github.com/joaomdmoura/crewAI/issues/316
2024-07-19 01:37:24 -03:00
robbyriverside
47bf93d291 Update Memory.md (#728)
The memory documentation left me with a lot of questions.  After I went through the code to find an answer.  I added this paragraph to explain what I found.  Hope this is helpful.
2024-07-19 01:36:54 -03:00
Brandon Hancock
d094e178f1 Update terminology 2024-07-18 14:59:38 -04:00
Braelyn Boynton
41fd1c6124 upgrade agentops to 0.3 (#957)
* upgrade agentops to 0.3

* lockfile
2024-07-18 13:30:04 -03:00
Lorenze Jay
be1b9a3994 Reset memory (#958)
* reseting memory on cli

* using storage.reset

* deleting memories on command

* added tests

* handle when no flags are used

* added docs
2024-07-18 13:29:42 -03:00
Eduardo Chiarotti
61a196394b feat: Add planning feature to crew (#919)
* feat: add planning feature to crew

* feat: add test to planning handler and change to execute_async method

* docs: add planning parameter to the Core documentation

* docs: add planning docs

* fix: fix type checking issue

* fix: test and logic
2024-07-18 13:15:08 -03:00
Brandon Hancock
834c62feca Going to start refactoring for pipeline_output 2024-07-18 11:20:26 -04:00
Brandon Hancock
c0c329b6e0 Merge branch 'main' into feature/procedure_v2 2024-07-17 13:37:27 -04:00
Lorenze Jay
5b442e4350 Merge pull request #951 from crewAIInc/test-hierarchical-tools-proper-setup
Test hierarchical tools proper setup
2024-07-17 08:53:23 -07:00
Lorenze Jay
c9920b9823 better spacing 2024-07-17 08:40:52 -07:00
Lorenze Jay
2faa2dbddb code cleanup 2024-07-17 08:39:57 -07:00
Lorenze Jay
76607062f0 using gpt4o 2024-07-17 08:27:43 -07:00
Lorenze Jay
a8cac9b7e9 Merge branch 'main' of github.com:joaomdmoura/crewAI into test-hierarchical-tools-proper-setup 2024-07-17 08:21:13 -07:00
Brandon Hancock (bhancock_ai)
dfacc8832f Merge pull request #954 from crewAIInc/hotfix/improve-async-logging
Fix logging for async and sync tasks
2024-07-17 11:20:13 -04:00
Lorenze Jay
93f643f851 fixed test 2024-07-17 08:20:05 -07:00
Brandon Hancock
cbf5d548be Merge branch 'main' into hotfix/improve-async-logging 2024-07-17 11:17:23 -04:00
Lorenze Jay
6946b89e17 Merge branch 'main' of github.com:joaomdmoura/crewAI into test-hierarchical-tools-proper-setup 2024-07-17 08:16:44 -07:00
Brandon Hancock (bhancock_ai)
dc4911b1ca Merge pull request #950 from crewAIInc/conditional-task-f
conditional task feat
2024-07-17 11:08:06 -04:00
Brandon Hancock
6ad218f9a0 Fix issues found by linter 2024-07-17 11:05:31 -04:00
Brandon Hancock
36efa172ee Add more tests. Clean up docs. Improve conditional task 2024-07-17 11:03:11 -04:00
Brandon Hancock
a7a2dfd296 Fix logging 2024-07-17 10:10:34 -04:00
João Moura
7baaeacac3 Adding better support for open source tool calling models (#952)
* Adding better support for open source tool calling models

* making sure the right tool is called

* fixing tests

* better support opensource models
2024-07-17 05:54:13 -03:00
Lorenze Jay
021f2eb8a1 Merge branch 'conditional-task-f' of github.com:joaomdmoura/crewAI into test-hierarchical-tools-proper-setup 2024-07-16 20:35:27 -07:00
Lorenze Jay
cb720143c7 Merge branch 'main' of github.com:joaomdmoura/crewAI into conditional-task-f 2024-07-16 20:34:35 -07:00
Lorenze Jay
731de2ff31 Merge branch 'test-hierarchical-tools-proper-setup' of github.com:joaomdmoura/crewAI into test-hierarchical-tools-proper-setup 2024-07-16 20:31:42 -07:00
Lorenze Jay
24e28da203 Merge branch 'conditional-task-f' of github.com:joaomdmoura/crewAI into test-hierarchical-tools-proper-setup 2024-07-16 20:28:50 -07:00
Lorenze Jay
bde0a3e99c code cleanup 2024-07-16 20:11:52 -07:00
Lorenze Jay
0415b9982b code cleanup 2024-07-16 20:07:05 -07:00
Brandon Hancock (bhancock_ai)
99ada42d97 Merge pull request #941 from crewAIInc/bugfix/minor-max-retry-recursion-fix
Properly capture result from max retry recursive call
2024-07-16 22:05:58 -04:00
Lorenze Jay
ee32d36312 Merge branch 'conditional-task-f' of github.com:joaomdmoura/crewAI into test-hierarchical-tools-proper-setup 2024-07-16 16:05:09 -07:00
Lorenze Jay
ef928ee3cb added docs and tests 2024-07-16 16:04:41 -07:00
Lorenze Jay
c66559345f Merge branch 'conditional-task-f' of github.com:joaomdmoura/crewAI into test-hierarchical-tools-proper-setup 2024-07-16 15:20:46 -07:00
Lorenze Jay
3ad95d50d4 ensures _update_manager_tools has a manager otherwise throw error 2024-07-16 15:15:50 -07:00
Lorenze Jay
bc7f601f84 updated fixes for conditional tasks 2024-07-16 15:10:13 -07:00
Lorenze Jay
e8cbdb7881 fixed hierarchial manager tools when assigned an agent 2024-07-16 14:00:25 -07:00
Lorenze Jay
b0c2b15a3e better code spacing 2024-07-16 13:07:31 -07:00
Lorenze Jay
c0f04bbb37 removing unused code 2024-07-16 13:06:50 -07:00
Lorenze Jay
c320fc655e conditional task feat 2024-07-16 12:04:34 -07:00
Brandon Hancock
f737b3b379 WIP 2024-07-16 11:35:24 -04:00
Brandon Hancock
467536b96a Merge branch 'main' into feature/procedure_v2 2024-07-16 10:34:55 -04:00
Brandon Hancock (bhancock_ai)
ac2815c781 Add docs for crewoutput and taskoutput (#943)
* Add docs for crewoutput and taskoutput

* Add reference to change log
2024-07-15 21:39:15 -03:00
Gui Vieira
dd8a199e99 Introduce structure keys (#902)
* Introduce structure keys

* Add agent key to tasks

* Rebasing is hard

* Rename task output telemetry

* Feedback
2024-07-15 19:37:07 -03:00
Gui Vieira
161c4a6856 Fix crew creation telemetry (#939)
* Fix crew creation telemetry

* Remove task index
2024-07-15 17:43:57 -03:00
Lorenze Jay
67b04b30bf Replay feat using db (#930)
* Cleaned up task execution to now have separate paths for async and sync execution. Updating all kickoff functions to return CrewOutput. WIP. Waiting for Joao feedback on async task execution with task_output

* Consistently storing async and sync output for context

* outline tests I need to create going forward

* Major rehaul of TaskOutput and CrewOutput. Updated all tests to work with new change. Need to add in a few final tricky async tests and add a few more to verify output types on TaskOutput and CrewOutput.

* Encountering issues with callback. Need to test on main. WIP

* working on tests. WIP

* WIP. Figuring out disconnect issue.

* Cleaned up logs now that I've isolated the issue to the LLM

* more wip.

* WIP. It looks like usage metrics has always been broken for async

* Update parent crew who is managing for_each loop

* Merge in main to bugfix/kickoff-for-each-usage-metrics

* Clean up code for review

* Add new tests

* Final cleanup. Ready for review.

* Moving copy functionality from Agent to BaseAgent

* Fix renaming issue

* Fix linting errors

* use BaseAgent instead of Agent where applicable

* Fixing missing function. Working on tests.

* WIP. Needing team to review change

* Fixing issues brought about by merge

* WIP: need to fix json encoder

* WIP need to fix encoder

* WIP

* WIP: replay working with async. need to add tests

* Implement major fixes from yesterdays group conversation. Now working on tests.

* The majority of tasks are working now. Need to fix converter class

* Fix final failing test

* Fix linting and type-checker issues

* Add more tests to fully test CrewOutput and TaskOutput changes

* Add in validation for async cannot depend on other async tasks.

* WIP: working replay feat fixing inputs, need tests

* WIP: core logic of seq and heir for executing tasks added into one

* Update validators and tests

* better logic for seq and hier

* replay working for both seq and hier just need tests

* fixed context

* added cli command + code cleanup TODO: need better refactoring

* refactoring for cleaner code

* added better tests

* removed todo comments and fixed some tests

* fix logging now all tests should pass

* cleaner code

* ensure replay is delcared when replaying specific tasks

* ensure hierarchical works

* better typing for stored_outputs and separated task_output_handler

* added better tests

* added replay feature to crew docs

* easier cli command name

* fixing changes

* using sqllite instead of .json file for logging previous task_outputs

* tools fix

* added to docs and fixed tests

* fixed .db

* fixed docs and removed unneeded comments

* separating ltm and replay db

* fixed printing colors

* added how to doc

---------

Co-authored-by: Brandon Hancock <brandon@brandonhancock.io>
2024-07-15 17:14:10 -03:00
Gui Vieira
7696b45fc3 Fix tool usage (#925)
* Fix tool usage

* new tests

---------

Co-authored-by: João Moura <joaomdmoura@gmail.com>
2024-07-15 17:13:35 -03:00
Brandon Hancock
641921eb6c capture result from recursive call 2024-07-15 13:59:58 -04:00
Brandon Hancock
a02d2fb93e Add return statement to recursive call 2024-07-15 13:40:51 -04:00
Brandon Hancock
1988a00c60 Merge branch 'bugfix/langchain-tool-config-change' into feature/procedure_v2 2024-07-15 11:47:16 -04:00
Brandon Hancock
e2f4405291 Merge branch 'main' into feature/procedure_v2 2024-07-15 09:44:41 -04:00
Brandon Hancock
040e5a78d2 Add back in Gui's tool_usage fix 2024-07-15 09:21:21 -04:00
Gui Vieira
b93632a53a [DO NOT MERGE] Provide inputs on crew creation (#898)
* Provide inputs on crew creation

* Better naming

* Add crew id and task index to tasks

* Fix type again
2024-07-15 09:00:02 -03:00
Eduardo Chiarotti
09938641cd feat: add max retry limit to agent execution (#899)
* feat: add max retry limit to agent execution

* feat: add test to max retry limit feature

* feat: add code execution docstring

---------

Co-authored-by: João Moura <joaomdmoura@gmail.com>
2024-07-15 08:58:50 -03:00
Brandon Hancock (bhancock_ai)
7acf0b2107 Feature/use converter instead of manually trimming (#894)
* Exploring output being passed to tool selector to see if we can better format data

* WIP. Adding JSON repair functionality

* Almost done implementing JSON repair. Testing fixes vs current base case.

* More action cleanup with additional tests

* WIP. Trying to figure out what is going on with tool descriptions

* Update tool description generation

* WIP. Trying to find out what is causing the tools to duplicate

* Replacing tools properly instead of duplicating them accidentally

* Fixing issues for MR

* Update dependencies for JSON_REPAIR

* More cleaning up pull request

* preppering for call

* Fix type-checking issues

---------

Co-authored-by: João Moura <joaomdmoura@gmail.com>
2024-07-15 08:53:41 -03:00
OP (oppenheimer)
4eb4073661 Add Groq - OpenAI Compatible API - details (#934) 2024-07-14 16:11:54 -03:00
Brandon Hancock
c5002eedd9 rshift working 2024-07-12 16:48:19 -04:00
Brandon Hancock
f7680d6157 All tests are passing now 2024-07-12 11:00:29 -04:00
Brandon Hancock
adf93c91f7 WIP. Procedure appears to be working well. Working on mocking properly for tests 2024-07-11 15:26:46 -04:00
114 changed files with 481589 additions and 10573 deletions

3
.gitignore vendored
View File

@@ -14,4 +14,5 @@ test.py
rc-tests/*
*.pkl
temp/*
.vscode/*
.vscode/*
crew_tasks_output.json

View File

@@ -254,7 +254,7 @@ pip install dist/*.tar.gz
CrewAI uses anonymous telemetry to collect usage data with the main purpose of helping us improve the library by focusing our efforts on the most used features, integrations and tools.
There is NO data being collected on the prompts, tasks descriptions agents backstories or goals nor tools usage, no API calls, nor responses nor any data that is being processed by the agents, nor any secrets and env vars.
It's pivotal to understand that **NO data is collected** concerning prompts, task descriptions, agents' backstories or goals, usage of tools, API calls, responses, any data processed by the agents, or secrets and environment variables, with the exception of the conditions mentioned. When the `share_crew` feature is enabled, detailed data including task descriptions, agents' backstories or goals, and other specific attributes are collected to provide deeper insights while respecting user privacy. We don't offer a way to disable it now, but we will in the future.
Data collected includes:
@@ -279,7 +279,7 @@ Data collected includes:
- Tools names available
- Understand out of the publically available tools, which ones are being used the most so we can improve them
Users can opt-in sharing the complete telemetry data by setting the `share_crew` attribute to `True` on their Crews.
Users can opt-in to Further Telemetry, sharing the complete telemetry data by setting the `share_crew` attribute to `True` on their Crews. Enabling `share_crew` results in the collection of detailed crew and task execution data, including `goal`, `backstory`, `context`, and `output` of tasks. This enables a deeper insight into usage patterns while respecting the user's choice to share.
## License

View File

@@ -114,7 +114,7 @@ from langchain.agents import load_tools
langchain_tools = load_tools(["google-serper"], llm=llm)
agent1 = CustomAgent(
role="backstory agent",
role="agent role",
goal="who is {input}?",
backstory="agent backstory",
verbose=True,
@@ -127,7 +127,7 @@ task1 = Task(
)
agent2 = Agent(
role="bio agent",
role="agent role",
goal="summarize the short bio for {input} and if needed do more research",
backstory="agent backstory",
verbose=True,

View File

@@ -4,36 +4,39 @@ description: Understanding and utilizing crews in the crewAI framework with comp
---
## What is a Crew?
A crew in crewAI represents a collaborative group of agents working together to achieve a set of tasks. Each crew defines the strategy for task execution, agent collaboration, and the overall workflow.
## Crew Attributes
| Attribute | Parameters | Description |
| :-------------------------- | :------------------ | :------------------------------------------------------------------------------------------------------- |
| **Tasks** | `tasks` | A list of tasks assigned to the crew. |
| **Agents** | `agents` | A list of agents that are part of the crew. |
| **Process** *(optional)* | `process` | The process flow (e.g., sequential, hierarchical) the crew follows. |
| **Verbose** *(optional)* | `verbose` | The verbosity level for logging during execution. |
| **Manager LLM** *(optional)*| `manager_llm` | The language model used by the manager agent in a hierarchical process. **Required when using a hierarchical process.** |
| **Function Calling LLM** *(optional)* | `function_calling_llm` | If passed, the crew will use this LLM to do function calling for tools for all agents in the crew. Each agent can have its own LLM, which overrides the crew's LLM for function calling. |
| **Config** *(optional)* | `config` | Optional configuration settings for the crew, in `Json` or `Dict[str, Any]` format. |
| **Max RPM** *(optional)* | `max_rpm` | Maximum requests per minute the crew adheres to during execution. |
| **Language** *(optional)* | `language` | Language used for the crew, defaults to English. |
| **Language File** *(optional)* | `language_file` | Path to the language file to be used for the crew. |
| **Memory** *(optional)* | `memory` | Utilized for storing execution memories (short-term, long-term, entity memory). |
| **Cache** *(optional)* | `cache` | Specifies whether to use a cache for storing the results of tools' execution. |
| **Embedder** *(optional)* | `embedder` | Configuration for the embedder to be used by the crew. Mostly used by memory for now. |
| **Full Output** *(optional)*| `full_output` | Whether the crew should return the full output with all tasks outputs or just the final output. |
| **Step Callback** *(optional)* | `step_callback` | A function that is called after each step of every agent. This can be used to log the agent's actions or to perform other operations; it won't override the agent-specific `step_callback`. |
| **Task Callback** *(optional)* | `task_callback` | A function that is called after the completion of each task. Useful for monitoring or additional operations post-task execution. |
| **Share Crew** *(optional)* | `share_crew` | Whether you want to share the complete crew information and execution with the crewAI team to make the library better, and allow us to train models. |
| **Output Log File** *(optional)* | `output_log_file` | Whether you want to have a file with the complete crew output and execution. You can set it using True and it will default to the folder you are currently in and it will be called logs.txt or passing a string with the full path and name of the file. |
| **Manager Agent** *(optional)* | `manager_agent` | `manager` sets a custom agent that will be used as a manager. |
| **Manager Callbacks** *(optional)* | `manager_callbacks` | `manager_callbacks` takes a list of callback handlers to be executed by the manager agent when a hierarchical process is used. |
| **Prompt File** *(optional)* | `prompt_file` | Path to the prompt JSON file to be used for the crew. |
| Attribute | Parameters | Description |
| :------------------------------------ | :--------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Tasks** | `tasks` | A list of tasks assigned to the crew. |
| **Agents** | `agents` | A list of agents that are part of the crew. |
| **Process** _(optional)_ | `process` | The process flow (e.g., sequential, hierarchical) the crew follows. |
| **Verbose** _(optional)_ | `verbose` | The verbosity level for logging during execution. |
| **Manager LLM** _(optional)_ | `manager_llm` | The language model used by the manager agent in a hierarchical process. **Required when using a hierarchical process.** |
| **Function Calling LLM** _(optional)_ | `function_calling_llm` | If passed, the crew will use this LLM to do function calling for tools for all agents in the crew. Each agent can have its own LLM, which overrides the crew's LLM for function calling. |
| **Config** _(optional)_ | `config` | Optional configuration settings for the crew, in `Json` or `Dict[str, Any]` format. |
| **Max RPM** _(optional)_ | `max_rpm` | Maximum requests per minute the crew adheres to during execution. |
| **Language** _(optional)_ | `language` | Language used for the crew, defaults to English. |
| **Language File** _(optional)_ | `language_file` | Path to the language file to be used for the crew. |
| **Memory** _(optional)_ | `memory` | Utilized for storing execution memories (short-term, long-term, entity memory). |
| **Cache** _(optional)_ | `cache` | Specifies whether to use a cache for storing the results of tools' execution. |
| **Embedder** _(optional)_ | `embedder` | Configuration for the embedder to be used by the crew. Mostly used by memory for now. |
| **Full Output** _(optional)_ | `full_output` | Whether the crew should return the full output with all tasks outputs or just the final output. |
| **Step Callback** _(optional)_ | `step_callback` | A function that is called after each step of every agent. This can be used to log the agent's actions or to perform other operations; it won't override the agent-specific `step_callback`. |
| **Task Callback** _(optional)_ | `task_callback` | A function that is called after the completion of each task. Useful for monitoring or additional operations post-task execution. |
| **Share Crew** _(optional)_ | `share_crew` | Whether you want to share the complete crew information and execution with the crewAI team to make the library better, and allow us to train models. |
| **Output Log File** _(optional)_ | `output_log_file` | Whether you want to have a file with the complete crew output and execution. You can set it using True and it will default to the folder you are currently in and it will be called logs.txt or passing a string with the full path and name of the file. |
| **Manager Agent** _(optional)_ | `manager_agent` | `manager` sets a custom agent that will be used as a manager. |
| **Manager Callbacks** _(optional)_ | `manager_callbacks` | `manager_callbacks` takes a list of callback handlers to be executed by the manager agent when a hierarchical process is used. |
| **Prompt File** _(optional)_ | `prompt_file` | Path to the prompt JSON file to be used for the crew. |
| **Planning** *(optional)* | `planning` | Adds planning ability to the Crew. When activated before each Crew iteration, all Crew data is sent to an AgentPlanner that will plan the tasks and this plan will be added to each task description.
| **Planning LLM** *(optional)* | `planning_llm` | The language model used by the AgentPlanner in a planning process. |
!!! note "Crew Max RPM"
The `max_rpm` attribute sets the maximum number of requests per minute the crew can perform to avoid rate limits and will override individual agents' `max_rpm` settings if you set it.
The `max_rpm` attribute sets the maximum number of requests per minute the crew can perform to avoid rate limits and will override individual agents' `max_rpm` settings if you set it.
## Creating a Crew
@@ -44,6 +47,12 @@ When assembling a crew, you combine agents with complementary roles and tools, a
```python
from crewai import Crew, Agent, Task, Process
from langchain_community.tools import DuckDuckGoSearchRun
from crewai_tools import tool
@tool('DuckDuckGoSearch')
def search(search_query: str):
"""Search the web for information on a given topic"""
return DuckDuckGoSearchRun().run(search_query)
# Define agents with specific roles and tools
researcher = Agent(
@@ -54,7 +63,7 @@ researcher = Agent(
to the business.
You're currently working on a project to analyze the
trends and innovations in the space of artificial intelligence.""",
tools=[DuckDuckGoSearchRun()]
tools=[search]
)
writer = Agent(
@@ -89,6 +98,57 @@ my_crew = Crew(
)
```
## Crew Output
!!! note "Understanding Crew Outputs"
The output of a crew in the crewAI framework is encapsulated within the `CrewOutput` class.
This class provides a structured way to access results of the crew's execution, including various formats such as raw strings, JSON, and Pydantic models.
The `CrewOutput` includes the results from the final task output, token usage, and individual task outputs.
### Crew Output Attributes
| Attribute | Parameters | Type | Description |
| :--------------- | :------------- | :------------------------- | :--------------------------------------------------------------------------------------------------- |
| **Raw** | `raw` | `str` | The raw output of the crew. This is the default format for the output. |
| **Pydantic** | `pydantic` | `Optional[BaseModel]` | A Pydantic model object representing the structured output of the crew. |
| **JSON Dict** | `json_dict` | `Optional[Dict[str, Any]]` | A dictionary representing the JSON output of the crew. |
| **Tasks Output** | `tasks_output` | `List[TaskOutput]` | A list of `TaskOutput` objects, each representing the output of a task in the crew. |
| **Token Usage** | `token_usage` | `Dict[str, Any]` | A summary of token usage, providing insights into the language model's performance during execution. |
### Crew Output Methods and Properties
| Method/Property | Description |
| :-------------- | :------------------------------------------------------------------------------------------------ |
| **json** | Returns the JSON string representation of the crew output if the output format is JSON. |
| **to_dict** | Converts the JSON and Pydantic outputs to a dictionary. |
| \***\*str\*\*** | Returns the string representation of the crew output, prioritizing Pydantic, then JSON, then raw. |
### Accessing Crew Outputs
Once a crew has been executed, its output can be accessed through the `output` attribute of the `Crew` object. The `CrewOutput` class provides various ways to interact with and present this output.
#### Example
```python
# Example crew execution
crew = Crew(
agents=[research_agent, writer_agent],
tasks=[research_task, write_article_task],
verbose=2
)
crew_output = crew.kickoff()
# Accessing the crew output
print(f"Raw Output: {crew_output.raw}")
if crew_output.json_dict:
print(f"JSON Output: {json.dumps(crew_output.json_dict, indent=2)}")
if crew_output.pydantic:
print(f"Pydantic Output: {crew_output.pydantic}")
print(f"Tasks Output: {crew_output.tasks_output}")
print(f"Token Usage: {crew_output.token_usage}")
```
## Memory Utilization
Crews can utilize memory (short-term, long-term, and entity memory) to enhance their execution and learning over time. This feature allows crews to store and recall execution memories, aiding in decision-making and task execution strategies.
@@ -156,3 +216,32 @@ for async_result in async_results:
```
These methods provide flexibility in how you manage and execute tasks within your crew, allowing for both synchronous and asynchronous workflows tailored to your needs
### Replaying from specific task:
You can now replay from a specific task using our cli command replay.
The replay feature in CrewAI allows you to replay from a specific task using the command-line interface (CLI). By running the command `crewai replay -t <task_id>`, you can specify the `task_id` for the replay process.
Kickoffs will now save the latest kickoffs returned task outputs locally for you to be able to replay from.
### Replaying from specific task Using the CLI
To use the replay feature, follow these steps:
1. Open your terminal or command prompt.
2. Navigate to the directory where your CrewAI project is located.
3. Run the following command:
To view latest kickoff task_ids use:
```shell
crewai log-tasks-outputs
```
```shell
crewai replay -t <task_id>
```
These commands let you replay from your latest kickoff tasks, still retaining context from previously executed tasks.

View File

@@ -29,6 +29,11 @@ description: Leveraging memory systems in the crewAI framework to enhance agent
When configuring a crew, you can enable and customize each memory component to suit the crew's objectives and the nature of tasks it will perform.
By default, the memory system is disabled, and you can ensure it is active by setting `memory=True` in the crew configuration. The memory will use OpenAI Embeddings by default, but you can change it by setting `embedder` to a different model.
The 'embedder' only applies to **Short-Term Memory** which uses Chroma for RAG using EmbedChain package.
The **Long-Term Memory** uses SQLLite3 to store task results. Currently, there is no way to override these storage implementations.
The data storage files are saved into a platform specific location found using the appdirs package
and the name of the project which can be overridden using the **CREWAI_STORAGE_DIR** environment variable.
### Example: Configuring Memory for a Crew
```python
@@ -161,10 +166,43 @@ my_crew = Crew(
)
```
### Resetting Memory
```sh
crewai reset_memories [OPTIONS]
```
#### Resetting Memory Options
- **`-l, --long`**
- **Description:** Reset LONG TERM memory.
- **Type:** Flag (boolean)
- **Default:** False
- **`-s, --short`**
- **Description:** Reset SHORT TERM memory.
- **Type:** Flag (boolean)
- **Default:** False
- **`-e, --entities`**
- **Description:** Reset ENTITIES memory.
- **Type:** Flag (boolean)
- **Default:** False
- **`-k, --kickoff-outputs`**
- **Description:** Reset LATEST KICKOFF TASK OUTPUTS.
- **Type:** Flag (boolean)
- **Default:** False
- **`-a, --all`**
- **Description:** Reset ALL memories.
- **Type:** Flag (boolean)
- **Default:** False
## Benefits of Using crewAI's Memory System
- **Adaptive Learning:** Crews become more efficient over time, adapting to new information and refining their approach to tasks.
- **Enhanced Personalization:** Memory enables agents to remember user preferences and historical interactions, leading to personalized experiences.
- **Improved Problem Solving:** Access to a rich memory store aids agents in making more informed decisions, drawing on past learnings and contextual insights.
## Getting Started
Integrating crewAI's memory system into your projects is straightforward. By leveraging the provided memory components and configurations, you can quickly empower your agents with the ability to remember, reason, and learn from their interactions, unlocking new levels of intelligence and capability.
Integrating crewAI's memory system into your projects is straightforward. By leveraging the provided memory components and configurations, you can quickly empower your agents with the ability to remember, reason, and learn from their interactions, unlocking new levels of intelligence and capability.

View File

@@ -0,0 +1,196 @@
---
title: crewAI Pipelines
description: Understanding and utilizing pipelines in the crewAI framework for efficient multi-stage task processing.
---
## What is a Pipeline?
A pipeline in crewAI represents a structured workflow that allows for the sequential or parallel execution of multiple crews. It provides a way to organize complex processes involving multiple stages, where the output of one stage can serve as input for subsequent stages.
## Key Terminology
Understanding the following terms is crucial for working effectively with pipelines:
- **Stage**: A distinct part of the pipeline, which can be either sequential (a single crew) or parallel (multiple crews executing concurrently).
- **Run**: A specific execution of the pipeline for a given set of inputs, representing a single instance of processing through the pipeline.
- **Branch**: Parallel executions within a stage (e.g., concurrent crew operations).
- **Trace**: The journey of an individual input through the entire pipeline, capturing the path and transformations it undergoes.
Example pipeline structure:
```
crew1 >> [crew2, crew3] >> crew4
```
This represents a pipeline with three stages:
1. A sequential stage (crew1)
2. A parallel stage with two branches (crew2 and crew3 executing concurrently)
3. Another sequential stage (crew4)
Each input creates its own run, flowing through all stages of the pipeline. Multiple runs can be processed concurrently, each following the defined pipeline structure.
## Pipeline Attributes
| Attribute | Parameters | Description |
| :--------- | :--------- | :------------------------------------------------------------------------------------ |
| **Stages** | `stages` | A list of crews or lists of crews representing the stages to be executed in sequence. |
## Creating a Pipeline
When creating a pipeline, you define a series of stages, each consisting of either a single crew or a list of crews for parallel execution. The pipeline ensures that each stage is executed in order, with the output of one stage feeding into the next.
### Example: Assembling a Pipeline
```python
from crewai import Crew, Agent, Task, Pipeline
# Define your crews
research_crew = Crew(
agents=[researcher],
tasks=[research_task],
process=Process.sequential
)
analysis_crew = Crew(
agents=[analyst],
tasks=[analysis_task],
process=Process.sequential
)
writing_crew = Crew(
agents=[writer],
tasks=[writing_task],
process=Process.sequential
)
# Assemble the pipeline
my_pipeline = Pipeline(
stages=[research_crew, analysis_crew, writing_crew]
)
```
## Pipeline Methods
| Method | Description |
| :--------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **process_runs** | Executes the pipeline, processing all stages and returning the results. This method initiates one or more runs through the pipeline, handling the flow of data between stages. |
## Pipeline Output
!!! note "Understanding Pipeline Outputs"
The output of a pipeline in the crewAI framework is encapsulated within two main classes: `PipelineOutput` and `PipelineRunResult`. These classes provide a structured way to access the results of the pipeline's execution, including various formats such as raw strings, JSON, and Pydantic models.
### Pipeline Output Attributes
| Attribute | Parameters | Type | Description |
| :-------------- | :------------ | :------------------------ | :-------------------------------------------------------------------------------------------------------- |
| **ID** | `id` | `UUID4` | A unique identifier for the pipeline output. |
| **Run Results** | `run_results` | `List[PipelineRunResult]` | A list of `PipelineRunResult` objects, each representing the output of a single run through the pipeline. |
### Pipeline Output Methods
| Method/Property | Description |
| :----------------- | :----------------------------------------------------- |
| **add_run_result** | Adds a `PipelineRunResult` to the list of run results. |
### Pipeline Run Result Attributes
| Attribute | Parameters | Type | Description |
| :---------------- | :-------------- | :------------------------- | :-------------------------------------------------------------------------------------------- |
| **ID** | `id` | `UUID4` | A unique identifier for the run result. |
| **Raw** | `raw` | `str` | The raw output of the final stage in the pipeline run. |
| **Pydantic** | `pydantic` | `Optional[BaseModel]` | A Pydantic model object representing the structured output of the final stage, if applicable. |
| **JSON Dict** | `json_dict` | `Optional[Dict[str, Any]]` | A dictionary representing the JSON output of the final stage, if applicable. |
| **Token Usage** | `token_usage` | `Dict[str, Any]` | A summary of token usage across all stages of the pipeline run. |
| **Trace** | `trace` | `List[Any]` | A trace of the journey of inputs through the pipeline run. |
| **Crews Outputs** | `crews_outputs` | `List[CrewOutput]` | A list of `CrewOutput` objects, representing the outputs from each crew in the pipeline run. |
### Pipeline Run Result Methods and Properties
| Method/Property | Description |
| :-------------- | :------------------------------------------------------------------------------------------------------- |
| **json** | Returns the JSON string representation of the run result if the output format of the final task is JSON. |
| **to_dict** | Converts the JSON and Pydantic outputs to a dictionary. |
| \***\*str\*\*** | Returns the string representation of the run result, prioritizing Pydantic, then JSON, then raw. |
### Accessing Pipeline Outputs
Once a pipeline has been executed, its output can be accessed through the `PipelineOutput` object returned by the `process_runs` method. The `PipelineOutput` class provides access to individual `PipelineRunResult` objects, each representing a single run through the pipeline.
#### Example
```python
# Define input data for the pipeline
input_data = [{"initial_query": "Latest advancements in AI"}, {"initial_query": "Future of robotics"}]
# Execute the pipeline
pipeline_output = await my_pipeline.process_runs(input_data)
# Access the results
for run_result in pipeline_output.run_results:
print(f"Run ID: {run_result.id}")
print(f"Final Raw Output: {run_result.raw}")
if run_result.json_dict:
print(f"JSON Output: {json.dumps(run_result.json_dict, indent=2)}")
if run_result.pydantic:
print(f"Pydantic Output: {run_result.pydantic}")
print(f"Token Usage: {run_result.token_usage}")
print(f"Trace: {run_result.trace}")
print("Crew Outputs:")
for crew_output in run_result.crews_outputs:
print(f" Crew: {crew_output.raw}")
print("\n")
```
This example demonstrates how to access and work with the pipeline output, including individual run results and their associated data.
## Using Pipelines
Pipelines are particularly useful for complex workflows that involve multiple stages of processing, analysis, or content generation. They allow you to:
1. **Sequence Operations**: Execute crews in a specific order, ensuring that the output of one crew is available as input to the next.
2. **Parallel Processing**: Run multiple crews concurrently within a stage for increased efficiency.
3. **Manage Complex Workflows**: Break down large tasks into smaller, manageable steps executed by specialized crews.
### Example: Running a Pipeline
```python
# Define input data for the pipeline
input_data = [{"initial_query": "Latest advancements in AI"}]
# Execute the pipeline, initiating a run for each input
results = await my_pipeline.process_runs(input_data)
# Access the results
for result in results:
print(f"Final Output: {result.raw}")
print(f"Token Usage: {result.token_usage}")
print(f"Trace: {result.trace}") # Shows the path of the input through all stages
```
## Advanced Features
### Parallel Execution within Stages
You can define parallel execution within a stage by providing a list of crews, creating multiple branches:
```python
parallel_analysis_crew = Crew(agents=[financial_analyst], tasks=[financial_analysis_task])
market_analysis_crew = Crew(agents=[market_analyst], tasks=[market_analysis_task])
my_pipeline = Pipeline(
stages=[
research_crew,
[parallel_analysis_crew, market_analysis_crew], # Parallel execution (branching)
writing_crew
]
)
```
### Error Handling and Validation
The Pipeline class includes validation mechanisms to ensure the robustness of the pipeline structure:
- Validates that stages contain only Crew instances or lists of Crew instances.
- Prevents double nesting of stages to maintain a clear structure.

View File

@@ -0,0 +1,138 @@
---
title: crewAI Planning
description: Learn how to add planning to your crewAI Crew and improve their performance.
---
## Introduction
The planning feature in CrewAI allows you to add planning capability to your crew. When enabled, before each Crew iteration, all Crew information is sent to an AgentPlanner that will plan the tasks step by step, and this plan will be added to each task description.
### Using the Planning Feature
Getting started with the planning feature is very easy, the only step required is to add `planning=True` to your Crew:
```python
from crewai import Crew, Agent, Task, Process
# Assemble your crew with planning capabilities
my_crew = Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
planning=True,
)
```
From this point on, your crew will have planning enabled, and the tasks will be planned before each iteration.
#### Planning LLM
Now you can define the LLM that will be used to plan the tasks. You can use any ChatOpenAI LLM model available.
```python
from crewai import Crew, Agent, Task, Process
from langchain_openai import ChatOpenAI
# Assemble your crew with planning capabilities and custom LLM
my_crew = Crew(
agents=self.agents,
tasks=self.tasks,
process=Process.sequential,
planning=True,
planning_llm=ChatOpenAI(model="gpt-4o")
)
```
### Example
When running the base case example, you will see something like the following output, which represents the output of the AgentPlanner responsible for creating the step-by-step logic to add to the Agents tasks.
```bash
[2024-07-15 16:49:11][INFO]: Planning the crew execution
**Step-by-Step Plan for Task Execution**
**Task Number 1: Conduct a thorough research about AI LLMs**
**Agent:** AI LLMs Senior Data Researcher
**Agent Goal:** Uncover cutting-edge developments in AI LLMs
**Task Expected Output:** A list with 10 bullet points of the most relevant information about AI LLMs
**Task Tools:** None specified
**Agent Tools:** None specified
**Step-by-Step Plan:**
1. **Define Research Scope:**
- Determine the specific areas of AI LLMs to focus on, such as advancements in architecture, use cases, ethical considerations, and performance metrics.
2. **Identify Reliable Sources:**
- List reputable sources for AI research, including academic journals, industry reports, conferences (e.g., NeurIPS, ACL), AI research labs (e.g., OpenAI, Google AI), and online databases (e.g., IEEE Xplore, arXiv).
3. **Collect Data:**
- Search for the latest papers, articles, and reports published in 2023 and early 2024.
- Use keywords like "Large Language Models 2024", "AI LLM advancements", "AI ethics 2024", etc.
4. **Analyze Findings:**
- Read and summarize the key points from each source.
- Highlight new techniques, models, and applications introduced in the past year.
5. **Organize Information:**
- Categorize the information into relevant topics (e.g., new architectures, ethical implications, real-world applications).
- Ensure each bullet point is concise but informative.
6. **Create the List:**
- Compile the 10 most relevant pieces of information into a bullet point list.
- Review the list to ensure clarity and relevance.
**Expected Output:**
A list with 10 bullet points of the most relevant information about AI LLMs.
---
**Task Number 2: Review the context you got and expand each topic into a full section for a report**
**Agent:** AI LLMs Reporting Analyst
**Agent Goal:** Create detailed reports based on AI LLMs data analysis and research findings
**Task Expected Output:** A fully fledge report with the main topics, each with a full section of information. Formatted as markdown without '```'
**Task Tools:** None specified
**Agent Tools:** None specified
**Step-by-Step Plan:**
1. **Review the Bullet Points:**
- Carefully read through the list of 10 bullet points provided by the AI LLMs Senior Data Researcher.
2. **Outline the Report:**
- Create an outline with each bullet point as a main section heading.
- Plan sub-sections under each main heading to cover different aspects of the topic.
3. **Research Further Details:**
- For each bullet point, conduct additional research if necessary to gather more detailed information.
- Look for case studies, examples, and statistical data to support each section.
4. **Write Detailed Sections:**
- Expand each bullet point into a comprehensive section.
- Ensure each section includes an introduction, detailed explanation, examples, and a conclusion.
- Use markdown formatting for headings, subheadings, lists, and emphasis.
5. **Review and Edit:**
- Proofread the report for clarity, coherence, and correctness.
- Make sure the report flows logically from one section to the next.
- Format the report according to markdown standards.
6. **Finalize the Report:**
- Ensure the report is complete with all sections expanded and detailed.
- Double-check formatting and make any necessary adjustments.
**Expected Output:**
A fully-fledged report with the main topics, each with a full section of information. Formatted as markdown without '```'.
---
```

View File

@@ -4,27 +4,29 @@ description: Detailed guide on managing and creating tasks within the crewAI fra
---
## Overview of a Task
!!! note "What is a Task?"
In the crewAI framework, tasks are specific assignments completed by agents. They provide all necessary details for execution, such as a description, the agent responsible, required tools, and more, facilitating a wide range of action complexities.
In the crewAI framework, tasks are specific assignments completed by agents. They provide all necessary details for execution, such as a description, the agent responsible, required tools, and more, facilitating a wide range of action complexities.
Tasks within crewAI can be collaborative, requiring multiple agents to work together. This is managed through the task properties and orchestrated by the Crew's process, enhancing teamwork and efficiency.
## Task Attributes
| Attribute | Parameters | Description |
| :----------------------| :------------------- | :-------------------------------------------------------------------------------------------- |
| **Description** | `description` | A clear, concise statement of what the task entails. |
| **Agent** | `agent` | The agent responsible for the task, assigned either directly or by the crew's process. |
| **Expected Output** | `expected_output` | A detailed description of what the task's completion looks like. |
| **Tools** *(optional)* | `tools` | The functions or capabilities the agent can utilize to perform the task. |
| **Async Execution** *(optional)* | `async_execution` | If set, the task executes asynchronously, allowing progression without waiting for completion.|
| **Context** *(optional)* | `context` | Specifies tasks whose outputs are used as context for this task. |
| **Config** *(optional)* | `config` | Additional configuration details for the agent executing the task, allowing further customization. |
| **Output JSON** *(optional)* | `output_json` | Outputs a JSON object, requiring an OpenAI client. Only one output format can be set. |
| **Output Pydantic** *(optional)* | `output_pydantic` | Outputs a Pydantic model object, requiring an OpenAI client. Only one output format can be set. |
| **Output File** *(optional)* | `output_file` | Saves the task output to a file. If used with `Output JSON` or `Output Pydantic`, specifies how the output is saved. |
| **Callback** *(optional)* | `callback` | A Python callable that is executed with the task's output upon completion. |
| **Human Input** *(optional)* | `human_input` | Indicates if the task requires human feedback at the end, useful for tasks needing human oversight. |
| Attribute | Parameters | Description |
| :------------------------------- | :---------------- | :------------------------------------------------------------------------------------------------------------------- |
| **Description** | `description` | A clear, concise statement of what the task entails. |
| **Agent** | `agent` | The agent responsible for the task, assigned either directly or by the crew's process. |
| **Expected Output** | `expected_output` | A detailed description of what the task's completion looks like. |
| **Tools** _(optional)_ | `tools` | The functions or capabilities the agent can utilize to perform the task. |
| **Async Execution** _(optional)_ | `async_execution` | If set, the task executes asynchronously, allowing progression without waiting for completion. |
| **Context** _(optional)_ | `context` | Specifies tasks whose outputs are used as context for this task. |
| **Config** _(optional)_ | `config` | Additional configuration details for the agent executing the task, allowing further customization. |
| **Output JSON** _(optional)_ | `output_json` | Outputs a JSON object, requiring an OpenAI client. Only one output format can be set. |
| **Output Pydantic** _(optional)_ | `output_pydantic` | Outputs a Pydantic model object, requiring an OpenAI client. Only one output format can be set. |
| **Output File** _(optional)_ | `output_file` | Saves the task output to a file. If used with `Output JSON` or `Output Pydantic`, specifies how the output is saved. |
| **Output** _(optional)_ | `output` | The output of the task, containing the raw, JSON, and Pydantic output plus additional details. |
| **Callback** _(optional)_ | `callback` | A Python callable that is executed with the task's output upon completion. |
| **Human Input** _(optional)_ | `human_input` | Indicates if the task requires human feedback at the end, useful for tasks needing human oversight. |
## Creating a Task
@@ -35,12 +37,75 @@ from crewai import Task
task = Task(
description='Find and summarize the latest and most relevant news on AI',
agent=sales_agent
agent=sales_agent,
expected_output='A bullet list summary of the top 5 most important AI news',
)
```
!!! note "Task Assignment"
Directly specify an `agent` for assignment or let the `hierarchical` CrewAI's process decide based on roles, availability, etc.
Directly specify an `agent` for assignment or let the `hierarchical` CrewAI's process decide based on roles, availability, etc.
## Task Output
!!! note "Understanding Task Outputs"
The output of a task in the crewAI framework is encapsulated within the `TaskOutput` class. This class provides a structured way to access results of a task, including various formats such as raw strings, JSON, and Pydantic models.
By default, the `TaskOutput` will only include the `raw` output. A `TaskOutput` will only include the `pydantic` or `json_dict` output if the original `Task` object was configured with `output_pydantic` or `output_json`, respectively.
### Task Output Attributes
| Attribute | Parameters | Type | Description |
| :---------------- | :-------------- | :------------------------- | :------------------------------------------------------------------------------------------------- |
| **Description** | `description` | `str` | A brief description of the task. |
| **Summary** | `summary` | `Optional[str]` | A short summary of the task, auto-generated from the description. |
| **Raw** | `raw` | `str` | The raw output of the task. This is the default format for the output. |
| **Pydantic** | `pydantic` | `Optional[BaseModel]` | A Pydantic model object representing the structured output of the task. |
| **JSON Dict** | `json_dict` | `Optional[Dict[str, Any]]` | A dictionary representing the JSON output of the task. |
| **Agent** | `agent` | `str` | The agent that executed the task. |
| **Output Format** | `output_format` | `OutputFormat` | The format of the task output, with options including RAW, JSON, and Pydantic. The default is RAW. |
### Task Output Methods and Properties
| Method/Property | Description |
| :-------------- | :------------------------------------------------------------------------------------------------ |
| **json** | Returns the JSON string representation of the task output if the output format is JSON. |
| **to_dict** | Converts the JSON and Pydantic outputs to a dictionary. |
| \***\*str\*\*** | Returns the string representation of the task output, prioritizing Pydantic, then JSON, then raw. |
### Accessing Task Outputs
Once a task has been executed, its output can be accessed through the `output` attribute of the `Task` object. The `TaskOutput` class provides various ways to interact with and present this output.
#### Example
```python
# Example task
task = Task(
description='Find and summarize the latest AI news',
expected_output='A bullet list summary of the top 5 most important AI news',
agent=research_agent,
tools=[search_tool]
)
# Execute the crew
crew = Crew(
agents=[research_agent],
tasks=[task],
verbose=2
)
result = crew.kickoff()
# Accessing the task output
task_output = task.output
print(f"Task Description: {task_output.description}")
print(f"Task Summary: {task_output.summary}")
print(f"Raw Output: {task_output.raw}")
if task_output.json_dict:
print(f"JSON Output: {json.dumps(task_output.json_dict, indent=2)}")
if task_output.pydantic:
print(f"Pydantic Output: {task_output.pydantic}")
```
## Integrating Tools with Tasks

View File

@@ -0,0 +1,41 @@
---
title: crewAI Testing
description: Learn how to test your crewAI Crew and evaluate their performance.
---
## Introduction
Testing is a crucial part of the development process, and it is essential to ensure that your crew is performing as expected. And with crewAI, you can easily test your crew and evaluate its performance using the built-in testing capabilities.
### Using the Testing Feature
We added the CLI command `crewai test` to make it easy to test your crew. This command will run your crew for a specified number of iterations and provide detailed performance metrics.
The parameters are `n_iterations` and `model` which are optional and default to 2 and `gpt-4o-mini` respectively. For now the only provider available is OpenAI.
```bash
crewai test
```
If you want to run more iterations or use a different model, you can specify the parameters like this:
```bash
crewai test --n_iterations 5 --model gpt-4o
```
What happens when you run the `crewai test` command is that the crew will be executed for the specified number of iterations, and the performance metrics will be displayed at the end of the run.
A table of scores at the end will show the performance of the crew in terms of the following metrics:
```
Task Scores
(1-10 Higher is better)
┏━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━┓
┃ Tasks/Crew ┃ Run 1 ┃ Run 2 ┃ Avg. Total ┃
┡━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━┩
│ Task 1 │ 10.0 │ 9.0 │ 9.5 │
│ Task 2 │ 9.0 │ 9.0 │ 9.0 │
│ Crew │ 9.5 │ 9.0 │ 9.2 │
└────────────┴───────┴───────┴────────────┘
```
The example above shows the test results for two runs of the crew with two tasks, with the average total score for each task and the crew as a whole.

View File

@@ -100,16 +100,24 @@ Here is a list of the available tools and their descriptions:
| Tool | Description |
| :-------------------------- | :-------------------------------------------------------------------------------------------- |
| **BrowserbaseLoadTool** | A tool for interacting with and extracting data from web browsers. |
| **CodeDocsSearchTool** | A RAG tool optimized for searching through code documentation and related technical documents. |
| **CodeInterpreterTool** | A tool for interpreting python code. |
| **ComposioTool** | Enables use of Composio tools. |
| **CSVSearchTool** | A RAG tool designed for searching within CSV files, tailored to handle structured data. |
| **DirectorySearchTool** | A RAG tool for searching within directories, useful for navigating through file systems. |
| **DOCXSearchTool** | A RAG tool aimed at searching within DOCX documents, ideal for processing Word files. |
| **DirectoryReadTool** | Facilitates reading and processing of directory structures and their contents. |
| **EXASearchTool** | A tool designed for performing exhaustive searches across various data sources. |
| **FileReadTool** | Enables reading and extracting data from files, supporting various file formats. |
| **FirecrawlSearchTool** | A tool to search webpages using Firecrawl and return the results. |
| **FirecrawlCrawlWebsiteTool** | A tool for crawling webpages using Firecrawl. |
| **FirecrawlScrapeWebsiteTool** | A tool for scraping webpages url using Firecrawl and returning its contents. |
| **GithubSearchTool** | A RAG tool for searching within GitHub repositories, useful for code and documentation search.|
| **SerperDevTool** | A specialized tool for development purposes, with specific functionalities under development. |
| **TXTSearchTool** | A RAG tool focused on searching within text (.txt) files, suitable for unstructured data. |
| **JSONSearchTool** | A RAG tool designed for searching within JSON files, catering to structured data handling. |
| **LlamaIndexTool** | Enables the use of LlamaIndex tools. |
| **MDXSearchTool** | A RAG tool tailored for searching within Markdown (MDX) files, useful for documentation. |
| **PDFSearchTool** | A RAG tool aimed at searching within PDF documents, ideal for processing scanned documents. |
| **PGSearchTool** | A RAG tool optimized for searching within PostgreSQL databases, suitable for database queries. |
@@ -120,8 +128,6 @@ Here is a list of the available tools and their descriptions:
| **XMLSearchTool** | A RAG tool designed for searching within XML files, suitable for structured data formats. |
| **YoutubeChannelSearchTool**| A RAG tool for searching within YouTube channels, useful for video content analysis. |
| **YoutubeVideoSearchTool** | A RAG tool aimed at searching within YouTube videos, ideal for video data extraction. |
| **BrowserbaseTool** | A tool for interacting with and extracting data from web browsers. |
| **ExaSearchTool** | A tool designed for performing exhaustive searches across various data sources. |
## Creating your own Tools

View File

@@ -18,4 +18,7 @@ pip install crewai
# Install the main crewAI package and the tools package
# that includes a series of helpful tools for your agents
pip install 'crewai[tools]'
# Alternatively, you can also use:
pip install crewai crewai-tools
```

View File

@@ -0,0 +1,255 @@
---
title: Starting a New CrewAI Project - Using Template
description: A comprehensive guide to starting a new CrewAI project, including the latest updates and project setup methods.
---
# Starting Your CrewAI Project
Welcome to the ultimate guide for starting a new CrewAI project. This document will walk you through the steps to create, customize, and run your CrewAI project, ensuring you have everything you need to get started.
Beforre we start there are a couple of things to note:
1. CrewAI is a Python package and requires Python >=3.10 and <=3.13 to run.
2. The preferred way of setting up CrewAI is using the `crewai create` command.This will create a new project folder and install a skeleton template for you to work on.
## Prerequisites
Before getting started with CrewAI, make sure that you have installed it via pip:
```shell
$ pip install crewai crewai-tools
```
### Virtual Environemnts
It is highly recommended that you use virtual environments to ensure that your CrewAI project is isolated from other projects and dependencies. Virtual environments provide a clean, separate workspace for each project, preventing conflicts between different versions of packages and libraries. This isolation is crucial for maintaining consistency and reproducibility in your development process. You have multiple options for setting up virtual environments depending on your operating system and Python version:
1. Use venv (Python's built-in virtual environment tool):
venv is included with Python 3.3 and later, making it a convenient choice for many developers. It's lightweight and easy to use, perfect for simple project setups.
To set up virtual environments with venv, refer to the official [Python documentation](https://docs.python.org/3/tutorial/venv.html).
2. Use Conda (A Python virtual environment manager):
Conda is an open-source package manager and environment management system for Python. It's widely used by data scientists, developers, and researchers to manage dependencies and environments in a reproducible way.
To set up virtual environments with Conda, refer to the official [Conda documentation](https://docs.conda.io/projects/conda/en/stable/user-guide/getting-started.html).
3. Use Poetry (A Python package manager and dependency management tool):
Poetry is an open-source Python package manager that simplifies the installation of packages and their dependencies. Poetry offers a convenient way to manage virtual environments and dependencies.
Poetry is CrewAI's prefered tool for package / dependancy management in CrewAI.
### Code IDEs
Most users of CrewAI a Code Editor / Integrated Development Environment (IDE) for building there Crews. You can use any code IDE of your choice. Seee below for some popular options for Code Editors / Integrated Development Environments (IDE):
- [Visual Studio Code](https://code.visualstudio.com/) - Most popular
- [PyCharm](https://www.jetbrains.com/pycharm/)
- [Cursor AI](https://cursor.com)
Pick one that suits your style and needs.
## Creating a New Project
In this example we will be using Venv as our virtual environment manager.
To setup a virtual environment, run the following CLI command:
```shell
$ python3 -m venv <venv-name>
```
Activate your virtual environment by running the following CLI command:
```shell
$ source <venv-name>/bin/activate
```
Now, to create a new CrewAI project, run the following CLI command:
```shell
$ crewai create <project_name>
```
This command will create a new project folder with the following structure:
```shell
my_project/
├── .gitignore
├── pyproject.toml
├── README.md
└── src/
└── my_project/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
You can now start developing your project by editing the files in the `src/my_project` folder. The `main.py` file is the entry point of your project, and the `crew.py` file is where you define your agents and tasks.
## Customizing Your Project
To customize your project, you can:
- Modify `src/my_project/config/agents.yaml` to define your agents.
- Modify `src/my_project/config/tasks.yaml` to define your tasks.
- Modify `src/my_project/crew.py` to add your own logic, tools, and specific arguments.
- Modify `src/my_project/main.py` to add custom inputs for your agents and tasks.
- Add your environment variables into the `.env` file.
### Example: Defining Agents and Tasks
#### agents.yaml
```yaml
researcher:
role: >
Job Candidate Researcher
goal: >
Find potential candidates for the job
backstory: >
You are adept at finding the right candidates by exploring various online
resources. Your skill in identifying suitable candidates ensures the best
match for job positions.
```
#### tasks.yaml
```yaml
research_candidates_task:
description: >
Conduct thorough research to find potential candidates for the specified job.
Utilize various online resources and databases to gather a comprehensive list of potential candidates.
Ensure that the candidates meet the job requirements provided.
Job Requirements:
{job_requirements}
expected_output: >
A list of 10 potential candidates with their contact information and brief profiles highlighting their suitability.
agent: researcher # THIS NEEDS TO MATCH THE AGENT NAME IN THE AGENTS.YAML FILE AND THE AGENT DEFINED IN THE Crew.PY FILE
context: # THESE NEED TO MATCH THE TASK NAMES DEFINED ABOVE AND THE TASKS.YAML FILE AND THE TASK DEFINED IN THE Crew.PY FILE
- researcher
```
### Referencing Variables:
Your defined functions with the same name will be used. For example, you can reference the agent for specific tasks from task.yaml file. Ensure your annotated agent and function name is the same otherwise your task wont recognize the reference properly.
#### Example References
agent.yaml
```yaml
email_summarizer:
role: >
Email Summarizer
goal: >
Summarize emails into a concise and clear summary
backstory: >
You will create a 5 bullet point summary of the report
llm: mixtal_llm
```
task.yaml
```yaml
email_summarizer_task:
description: >
Summarize the email into a 5 bullet point summary
expected_output: >
A 5 bullet point summary of the email
agent: email_summarizer
context:
- reporting_task
- research_task
```
Use the annotations are used to properly reference the agent and task in the crew.py file.
### Annotations include:
* @agent
* @task
* @crew
* @llm
* @tool
* @callback
* @output_json
* @output_pydantic
* @cache_handler
crew.py
```py
...
@llm
def mixtal_llm(self):
return ChatGroq(temperature=0, model_name="mixtral-8x7b-32768")
@agent
def email_summarizer(self) -> Agent:
return Agent(
config=self.agents_config["email_summarizer"],
)
## ...other tasks defined
@task
def email_summarizer_task(self) -> Task:
return Task(
config=self.tasks_config["email_summarizer_task"],
)
...
```
## Installing Dependencies
To install the dependencies for your project, you can use Poetry. First, navigate to your project directory:
```shell
$ cd my_project
$ poetry lock
$ poetry install
```
This will install the dependencies specified in the `pyproject.toml` file.
## Interpolating Variables
Any variable interpolated in your `agents.yaml` and `tasks.yaml` files like `{variable}` will be replaced by the value of the variable in the `main.py` file.
#### agents.yaml
```yaml
research_task:
description: >
Conduct a thorough research about the customer and competitors in the context
of {customer_domain}.
Make sure you find any interesting and relevant information given the
current year is 2024.
expected_output: >
A complete report on the customer and their customers and competitors,
including their demographics, preferences, market positioning and audience engagement.
```
#### main.py
```python
# main.py
def run():
inputs = {
"customer_domain": "crewai.com"
}
MyProjectCrew(inputs).crew().kickoff(inputs=inputs)
```
## Running Your Project
To run your project, use the following command:
```shell
$ poetry run my_project
```
This will initialize your crew of AI agents and begin task execution as defined in your configuration in the `main.py` file.
## Deploying Your Project
The easiest way to deploy your crew is through [CrewAI+](https://www.crewai.com/crewaiplus), where you can deploy your crew in a few clicks.

View File

@@ -0,0 +1,87 @@
---
title: Conditional Tasks
description: Learn how to use conditional tasks in a crewAI kickoff
---
## Introduction
Conditional Tasks in crewAI allow for dynamic workflow adaptation based on the outcomes of previous tasks. This powerful feature enables crews to make decisions and execute tasks selectively, enhancing the flexibility and efficiency of your AI-driven processes.
```python
from typing import List
from pydantic import BaseModel
from crewai import Agent, Crew
from crewai.tasks.conditional_task import ConditionalTask
from crewai.tasks.task_output import TaskOutput
from crewai.task import Task
from crewai_tools import SerperDevTool
# Define a condition function for the conditional task
# if false task will be skipped, true, then execute task
def is_data_missing(output: TaskOutput) -> bool:
return len(output.pydantic.events) < 10: # this will skip this task
# Define the agents
data_fetcher_agent = Agent(
role="Data Fetcher",
goal="Fetch data online using Serper tool",
backstory="Backstory 1",
verbose=True,
tools=[SerperDevTool()],
)
data_processor_agent = Agent(
role="Data Processor",
goal="Process fetched data",
backstory="Backstory 2",
verbose=True,
)
summary_generator_agent = Agent(
role="Summary Generator",
goal="Generate summary from fetched data",
backstory="Backstory 3",
verbose=True,
)
class EventOutput(BaseModel):
events: List[str]
task1 = Task(
description="Fetch data about events in San Francisco using Serper tool",
expected_output="List of 10 things to do in SF this week",
agent=data_fetcher_agent,
output_pydantic=EventOutput,
)
conditional_task = ConditionalTask(
description="""
Check if data is missing. If we have less than 10 events,
fetch more events using Serper tool so that
we have a total of 10 events in SF this week..
""",
expected_output="List of 10 Things to do in SF this week ",
condition=is_data_missing,
agent=data_processor_agent,
)
task3 = Task(
description="Generate summary of events in San Francisco from fetched data",
expected_output="summary_generated",
agent=summary_generator_agent,
)
# Create a crew with the tasks
crew = Crew(
agents=[data_fetcher_agent, data_processor_agent, summary_generator_agent],
tasks=[task1, conditional_task, task3],
verbose=2,
)
result = crew.kickoff()
print("results", result)
```

View File

@@ -1,82 +0,0 @@
---
title: Assembling and Activating Your CrewAI Team
description: A comprehensive guide to creating a dynamic CrewAI team for your projects, with updated functionalities including verbose mode, memory capabilities, asynchronous execution, output customization, language model configuration, code execution, integration with third-party agents, and improved task management.
---
## Introduction
Embark on your CrewAI journey by setting up your environment and initiating your AI crew with the latest features. This guide ensures a smooth start, incorporating all recent updates for an enhanced experience, including code execution capabilities, integration with third-party agents, and advanced task management.
## Step 0: Installation
Install CrewAI and any necessary packages for your project. CrewAI is compatible with Python >=3.10,<=3.13.
```shell
pip install crewai
pip install 'crewai[tools]'
```
## Step 1: Assemble Your Agents
Define your agents with distinct roles, backstories, and enhanced capabilities. The Agent class now supports a wide range of attributes for fine-tuned control over agent behavior and interactions, including code execution and integration with third-party agents.
```python
import os
from langchain.llms import OpenAI
from crewai import Agent
from crewai_tools import SerperDevTool, BrowserbaseTool, ExaSearchTool
os.environ["OPENAI_API_KEY"] = "Your OpenAI Key"
os.environ["SERPER_API_KEY"] = "Your Serper Key"
search_tool = SerperDevTool()
browser_tool = BrowserbaseTool()
exa_search_tool = ExaSearchTool()
# Creating a senior researcher agent with advanced configurations
researcher = Agent(
role='Senior Researcher',
goal='Uncover groundbreaking technologies in {topic}',
backstory=("Driven by curiosity, you're at the forefront of innovation, "
"eager to explore and share knowledge that could change the world."),
memory=True,
verbose=True,
allow_delegation=False,
tools=[search_tool, browser_tool],
allow_code_execution=False, # New attribute for enabling code execution
max_iter=15, # Maximum number of iterations for task execution
max_rpm=100, # Maximum requests per minute
max_execution_time=3600, # Maximum execution time in seconds
system_template="Your custom system template here", # Custom system template
prompt_template="Your custom prompt template here", # Custom prompt template
response_template="Your custom response template here", # Custom response template
)
# Creating a writer agent with custom tools and specific configurations
writer = Agent(
role='Writer',
goal='Narrate compelling tech stories about {topic}',
backstory=("With a flair for simplifying complex topics, you craft engaging "
"narratives that captivate and educate, bringing new discoveries to light."),
verbose=True,
allow_delegation=False,
memory=True,
tools=[exa_search_tool],
function_calling_llm=OpenAI(model_name="gpt-3.5-turbo"), # Separate LLM for function calling
)
# Setting a specific manager agent
manager = Agent(
role='Manager',
goal='Ensure the smooth operation and coordination of the team',
verbose=True,
backstory=(
"As a seasoned project manager, you excel in organizing "
"tasks, managing timelines, and ensuring the team stays on track."
),
allow_code_execution=True, # Enable code execution for the manager
)
```
### New Agent Attributes and Features
1. `allow_code_execution`: Enable or disable code execution capabilities for the agent (default is False).
2. `max_execution_time`: Set a maximum execution time (in seconds) for the agent to complete a task.
3. `function_calling_llm`: Specify a separate language model for function calling.

View File

@@ -7,7 +7,7 @@ description: Learn how to force tool output as the result in of an Agent's task
In CrewAI, you can force the output of a tool as the result of an agent's task. This feature is useful when you want to ensure that the tool output is captured and returned as the task result, and avoid the agent modifying the output during the task execution.
## Forcing Tool Output as Result
To force the tool output as the result of an agent's task, you can set the `force_tool_output` parameter to `True` when creating the task. This parameter ensures that the tool output is captured and returned as the task result, without any modifications by the agent.
To force the tool output as the result of an agent's task, you can set the `result_as_answer` parameter to `True` when creating the agent. This parameter ensures that the tool output is captured and returned as the task result, without any modifications by the agent.
Here's an example of how to force the tool output as the result of an agent's task:

View File

@@ -127,7 +127,7 @@ llm = HuggingFaceHub(
```
## OpenAI Compatible API Endpoints
Switch between APIs and models seamlessly using environment variables, supporting platforms like FastChat, LM Studio, and Mistral AI.
Switch between APIs and models seamlessly using environment variables, supporting platforms like FastChat, LM Studio, Groq, and Mistral AI.
### Configuration Examples
#### FastChat
@@ -144,6 +144,13 @@ OPENAI_API_BASE="http://localhost:1234/v1"
OPENAI_API_KEY="lm-studio"
```
#### Groq API
```sh
OPENAI_API_KEY=your-groq-api-key
OPENAI_MODEL_NAME='llama3-8b-8192'
OPENAI_API_BASE=https://api.groq.com/openai/v1
```
#### Mistral API
```sh
OPENAI_API_KEY=your-mistral-api-key
@@ -211,4 +218,4 @@ azure_agent = Agent(
```
## Conclusion
Integrating CrewAI with different LLMs expands the framework's versatility, allowing for customized, efficient AI solutions across various domains and platforms.
Integrating CrewAI with different LLMs expands the framework's versatility, allowing for customized, efficient AI solutions across various domains and platforms.

View File

@@ -0,0 +1,49 @@
---
title: Replay Tasks from Latest Crew Kickoff
description: Replay tasks from the latest crew.kickoff(...)
---
## Introduction
CrewAI provides the ability to replay from a task specified from the latest crew kickoff. This feature is particularly useful when you've finished a kickoff and may want to retry certain tasks or don't need to refetch data over and your agents already have the context saved from the kickoff execution so you just need to replay the tasks you want to.
## Note:
You must run `crew.kickoff()` before you can replay a task. Currently, only the latest kickoff is supported, so if you use `kickoff_for_each`, it will only allow you to replay from the most recent crew run.
Here's an example of how to replay from a task:
### Replaying from specific task Using the CLI
To use the replay feature, follow these steps:
1. Open your terminal or command prompt.
2. Navigate to the directory where your CrewAI project is located.
3. Run the following command:
To view latest kickoff task_ids use:
```shell
crewai log-tasks-outputs
```
Once you have your task_id to replay from use:
```shell
crewai replay -t <task_id>
```
### Replaying from a task Programmatically
To replay from a task programmatically, use the following steps:
1. Specify the task_id and input parameters for the replay process.
2. Execute the replay command within a try-except block to handle potential errors.
```python
def replay():
"""
Replay the crew execution from a specific task.
"""
task_id = '<task_id>'
inputs = {"topic": "CrewAI Training"} # this is optional, you can pass in the inputs you want to replay otherwise uses the previous kickoffs inputs
try:
YourCrewName_Crew().crew().replay(task_id=task_id, inputs=inputs)
except Exception as e:
raise Exception(f"An error occurred while replaying the crew: {e}")

View File

@@ -1,137 +0,0 @@
---
title: Starting a New CrewAI Project
description: A comprehensive guide to starting a new CrewAI project, including the latest updates and project setup methods.
---
# Starting Your CrewAI Project
Welcome to the ultimate guide for starting a new CrewAI project. This document will walk you through the steps to create, customize, and run your CrewAI project, ensuring you have everything you need to get started.
## Prerequisites
We assume you have already installed CrewAI. If not, please refer to the [installation guide](how-to/Installing-CrewAI.md) to install CrewAI and its dependencies.
## Creating a New Project
To create a new project, run the following CLI command:
```shell
$ crewai create my_project
```
This command will create a new project folder with the following structure:
```shell
my_project/
├── .gitignore
├── pyproject.toml
├── README.md
└── src/
└── my_project/
├── __init__.py
├── main.py
├── crew.py
├── tools/
│ ├── custom_tool.py
│ └── __init__.py
└── config/
├── agents.yaml
└── tasks.yaml
```
You can now start developing your project by editing the files in the `src/my_project` folder. The `main.py` file is the entry point of your project, and the `crew.py` file is where you define your agents and tasks.
## Customizing Your Project
To customize your project, you can:
- Modify `src/my_project/config/agents.yaml` to define your agents.
- Modify `src/my_project/config/tasks.yaml` to define your tasks.
- Modify `src/my_project/crew.py` to add your own logic, tools, and specific arguments.
- Modify `src/my_project/main.py` to add custom inputs for your agents and tasks.
- Add your environment variables into the `.env` file.
### Example: Defining Agents and Tasks
#### agents.yaml
```yaml
researcher:
role: >
Job Candidate Researcher
goal: >
Find potential candidates for the job
backstory: >
You are adept at finding the right candidates by exploring various online
resources. Your skill in identifying suitable candidates ensures the best
match for job positions.
```
#### tasks.yaml
```yaml
research_candidates_task:
description: >
Conduct thorough research to find potential candidates for the specified job.
Utilize various online resources and databases to gather a comprehensive list of potential candidates.
Ensure that the candidates meet the job requirements provided.
Job Requirements:
{job_requirements}
expected_output: >
A list of 10 potential candidates with their contact information and brief profiles highlighting their suitability.
```
## Installing Dependencies
To install the dependencies for your project, you can use Poetry. First, navigate to your project directory:
```shell
$ cd my_project
$ poetry lock
$ poetry install
```
This will install the dependencies specified in the `pyproject.toml` file.
## Interpolating Variables
Any variable interpolated in your `agents.yaml` and `tasks.yaml` files like `{variable}` will be replaced by the value of the variable in the `main.py` file.
#### agents.yaml
```yaml
research_task:
description: >
Conduct a thorough research about the customer and competitors in the context
of {customer_domain}.
Make sure you find any interesting and relevant information given the
current year is 2024.
expected_output: >
A complete report on the customer and their customers and competitors,
including their demographics, preferences, market positioning and audience engagement.
```
#### main.py
```python
# main.py
def run():
inputs = {
"customer_domain": "crewai.com"
}
MyProjectCrew(inputs).crew().kickoff(inputs=inputs)
```
## Running Your Project
To run your project, use the following command:
```shell
$ poetry run my_project
```
This will initialize your crew of AI agents and begin task execution as defined in your configuration in the `main.py` file.
## Deploying Your Project
The easiest way to deploy your crew is through [CrewAI+](https://www.crewai.com/crewaiplus), where you can deploy your crew in a few clicks.

View File

@@ -5,6 +5,19 @@
Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks.
<div style="display:flex; margin:0 auto; justify-content: center;">
<div style="width:25%">
<h2>Getting Started</h2>
<ul>
<li><a href='./getting-started/Installing-CrewAI'>
Installing CrewAI
</a>
</li>
<li><a href='./getting-started/Start-a-New-CrewAI-Project-Template-Method'>
Start a New CrewAI Project: Template Method
</a>
</li>
</ul>
</div>
<div style="width:25%">
<h2>Core Concepts</h2>
<ul>
@@ -33,6 +46,11 @@ Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By
Crews
</a>
</li>
<li>
<a href="./core-concepts/Pipeline">
Pipeline
</a>
</li>
<li>
<a href="./core-concepts/Training-Crew">
Training
@@ -43,26 +61,16 @@ Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By
Memory
</a>
</li>
<li>
<a href="./core-concepts/Planning">
Planning
</a>
</li>
</ul>
</div>
<div style="width:30%">
<h2>How-To Guides</h2>
<ul>
<li>
<a href="./how-to/Start-a-New-CrewAI-Project">
Starting Your crewAI Project
</a>
</li>
<li>
<a href="./how-to/Installing-CrewAI">
Installing crewAI
</a>
</li>
<li>
<a href="./how-to/Creating-a-Crew-and-kick-it-off">
Getting Started
</a>
</li>
<li>
<a href="./how-to/Create-Custom-Tools">
Create Custom Tools
@@ -113,6 +121,16 @@ Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By
Kickoff a Crew for a List
</a>
</li>
<li>
<a href="./how-to/Replay-tasks-from-latest-Crew-Kickoff">
Replay from a Task
</a>
</li>
<li>
<a href="./how-to/Conditional-Tasks">
Conditional Tasks
</a>
</li>
<li>
<a href="./how-to/AgentOps-Observability">
Agent Monitoring with AgentOps

View File

@@ -5,7 +5,7 @@ description: Understanding the telemetry data collected by CrewAI and how it con
## Telemetry
CrewAI utilizes anonymous telemetry to gather usage statistics with the primary goal of enhancing the library. Our focus is on improving and developing the features, integrations, and tools most utilized by our users.
CrewAI utilizes anonymous telemetry to gather usage statistics with the primary goal of enhancing the library. Our focus is on improving and developing the features, integrations, and tools most utilized by our users. We don't offer a way to disable it now, but we will in the future.
It's pivotal to understand that **NO data is collected** concerning prompts, task descriptions, agents' backstories or goals, usage of tools, API calls, responses, any data processed by the agents, or secrets and environment variables, with the exception of the conditions mentioned. When the `share_crew` feature is enabled, detailed data including task descriptions, agents' backstories or goals, and other specific attributes are collected to provide deeper insights while respecting user privacy.
@@ -22,7 +22,7 @@ It's pivotal to understand that **NO data is collected** concerning prompts, tas
- **Tool Usage**: Identifying which tools are most frequently used allows us to prioritize improvements in those areas.
### Opt-In Further Telemetry Sharing
Users can choose to share their complete telemetry data by enabling the `share_crew` attribute to `True` in their crew configurations. This opt-in approach respects user privacy and aligns with data protection standards by ensuring users have control over their data sharing preferences. Enabling `share_crew` results in the collection of detailed crew and task execution data, including `goal`, `backstory`, `context`, and `output` of tasks. This enables a deeper insight into usage patterns while respecting the user's choice to share.
Users can choose to share their complete telemetry data by enabling the `share_crew` attribute to `True` in their crew configurations. Enabling `share_crew` results in the collection of detailed crew and task execution data, including `goal`, `backstory`, `context`, and `output` of tasks. This enables a deeper insight into usage patterns while respecting the user's choice to share.
### Updates and Revisions
We are committed to maintaining the accuracy and transparency of our documentation. Regular reviews and updates are performed to ensure our documentation accurately reflects the latest developments of our codebase and telemetry practices. Users are encouraged to review this section for the most current information on our data collection practices and how they contribute to the improvement of CrewAI.

View File

@@ -29,5 +29,70 @@ To effectively use the `SerperDevTool`, follow these steps:
2. **API Key Acquisition**: Acquire a `serper.dev` API key by registering for a free account at `serper.dev`.
3. **Environment Configuration**: Store your obtained API key in an environment variable named `SERPER_API_KEY` to facilitate its use by the tool.
## Parameters
The `SerperDevTool` comes with several parameters that will be passed to the API :
- **search_url**: The URL endpoint for the search API. (Default is `https://google.serper.dev/search`)
- **country**: Optional. Specify the country for the search results.
- **location**: Optional. Specify the location for the search results.
- **locale**: Optional. Specify the locale for the search results.
- **n_results**: Number of search results to return. Default is `10`.
The values for `country`, `location`, `lovale` and `search_url` can be found on the [Serper Playground](https://serper.dev/playground).
## Example with Parameters
Here is an example demonstrating how to use the tool with additional parameters:
```python
from crewai_tools import SerperDevTool
tool = SerperDevTool(
search_url="https://google.serper.dev/scholar",
n_results=2,
)
print(tool.run(search_query="ChatGPT"))
# Using Tool: Search the internet
# Search results: Title: Role of chat gpt in public health
# Link: https://link.springer.com/article/10.1007/s10439-023-03172-7
# Snippet: … ChatGPT in public health. In this overview, we will examine the potential uses of ChatGPT in
# ---
# Title: Potential use of chat gpt in global warming
# Link: https://link.springer.com/article/10.1007/s10439-023-03171-8
# Snippet: … as ChatGPT, have the potential to play a critical role in advancing our understanding of climate
# ---
```
```python
from crewai_tools import SerperDevTool
tool = SerperDevTool(
country="fr",
locale="fr",
location="Paris, Paris, Ile-de-France, France",
n_results=2,
)
print(tool.run(search_query="Jeux Olympiques"))
# Using Tool: Search the internet
# Search results: Title: Jeux Olympiques de Paris 2024 - Actualités, calendriers, résultats
# Link: https://olympics.com/fr/paris-2024
# Snippet: Quels sont les sports présents aux Jeux Olympiques de Paris 2024 ? · Athlétisme · Aviron · Badminton · Basketball · Basketball 3x3 · Boxe · Breaking · Canoë ...
# ---
# Title: Billetterie Officielle de Paris 2024 - Jeux Olympiques et Paralympiques
# Link: https://tickets.paris2024.org/
# Snippet: Achetez vos billets exclusivement sur le site officiel de la billetterie de Paris 2024 pour participer au plus grand événement sportif au monde.
# ---
```
## Conclusion
By integrating the `SerperDevTool` into Python projects, users gain the ability to conduct real-time, relevant searches across the internet directly from their applications. By adhering to the setup and usage guidelines provided, incorporating this tool into projects is streamlined and straightforward.
By integrating the `SerperDevTool` into Python projects, users gain the ability to conduct real-time, relevant searches across the internet directly from their applications. The updated parameters allow for more customized and localized search results. By adhering to the setup and usage guidelines provided, incorporating this tool into projects is streamlined and straightforward.

View File

@@ -119,6 +119,9 @@ theme:
nav:
- Home: '/'
- Getting Started:
- Installing CrewAI: 'getting-started/Installing-CrewAI.md'
- Starting a new CrewAI project: 'getting-started/Start-a-New-CrewAI-Project-Template-Method.md'
- Core Concepts:
- Agents: 'core-concepts/Agents.md'
- Tasks: 'core-concepts/Tasks.md'
@@ -128,6 +131,8 @@ nav:
- Collaboration: 'core-concepts/Collaboration.md'
- Training: 'core-concepts/Training-Crew.md'
- Memory: 'core-concepts/Memory.md'
- Planning: 'core-concepts/Planning.md'
- Testing: 'core-concepts/Testing.md'
- Using LangChain Tools: 'core-concepts/Using-LangChain-Tools.md'
- Using LlamaIndex Tools: 'core-concepts/Using-LlamaIndex-Tools.md'
- How to Guides:
@@ -145,6 +150,8 @@ nav:
- Human Input on Execution: 'how-to/Human-Input-on-Execution.md'
- Kickoff a Crew Asynchronously: 'how-to/Kickoff-async.md'
- Kickoff a Crew for a List: 'how-to/Kickoff-for-each.md'
- Replay from a specific task from a kickoff: 'how-to/Replay-tasks-from-latest-Crew-Kickoff.md'
- Conditional Tasks: 'how-to/Conditional-Tasks.md'
- Agent Monitoring with AgentOps: 'how-to/AgentOps-Observability.md'
- Agent Monitoring with LangTrace: 'how-to/Langtrace-Observability.md'
- Tools Docs:
@@ -180,6 +187,7 @@ nav:
- Landing Page Generator: https://github.com/joaomdmoura/crewAI-examples/tree/main/landing_page_generator"
- Prepare for meetings: https://github.com/joaomdmoura/crewAI-examples/tree/main/prep-for-a-meeting"
- Telemetry: 'telemetry/Telemetry.md'
- Change Log: 'https://github.com/crewAIInc/crewAI/releases'
extra_css:
- stylesheets/output.css

1423
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "crewai"
version = "0.36.0"
version = "0.46.0"
description = "Cutting-edge framework for orchestrating role-playing, autonomous AI agents. By fostering collaborative intelligence, CrewAI empowers agents to work together seamlessly, tackling complex tasks."
authors = ["Joao Moura <joao@crewai.com>"]
readme = "README.md"
@@ -21,13 +21,14 @@ opentelemetry-sdk = "^1.22.0"
opentelemetry-exporter-otlp-proto-http = "^1.22.0"
instructor = "1.3.3"
regex = "^2023.12.25"
crewai-tools = { version = "^0.4.8", optional = true }
crewai-tools = { version = "^0.4.26", optional = true }
click = "^8.1.7"
python-dotenv = "^1.0.0"
appdirs = "^1.4.4"
jsonref = "^1.1.0"
agentops = { version = "^0.1.9", optional = true }
agentops = { version = "^0.3.0", optional = true }
embedchain = "^0.1.114"
json-repair = "^0.25.2"
[tool.poetry.extras]
tools = ["crewai-tools"]
@@ -45,12 +46,13 @@ mkdocs-material = { extras = ["imaging"], version = "^9.5.7" }
mkdocs-material-extensions = "^1.3.1"
pillow = "^10.2.0"
cairosvg = "^2.7.1"
crewai-tools = "^0.4.8"
crewai-tools = "^0.4.26"
[tool.poetry.group.test.dependencies]
pytest = "^8.0.0"
pytest-vcr = "^1.0.2"
python-dotenv = "1.0.0"
pytest-asyncio = "^0.23.7"
[tool.poetry.scripts]
crewai = "crewai.cli.cli:crewai"

View File

@@ -1,13 +1,14 @@
import os
from inspect import signature
from typing import Any, List, Optional, Tuple
from langchain.agents.agent import RunnableAgent
from langchain.agents.tools import BaseTool
from langchain.agents.tools import tool as LangChainTool
from langchain.tools.render import render_text_description
from langchain_core.agents import AgentAction
from langchain_core.callbacks import BaseCallbackHandler
from langchain_openai import ChatOpenAI
from pydantic import Field, InstanceOf, model_validator
from pydantic import Field, InstanceOf, PrivateAttr, model_validator
from crewai.agents import CacheHandler, CrewAgentExecutor, CrewAgentParser
from crewai.agents.agent_builder.base_agent import BaseAgent
@@ -56,6 +57,7 @@ class Agent(BaseAgent):
callbacks: A list of callback functions from the langchain library that are triggered during the agent's execution process
"""
_times_executed: int = PrivateAttr(default=0)
max_execution_time: Optional[int] = Field(
default=None,
description="Maximum execution time for an agent to execute a task",
@@ -96,6 +98,10 @@ class Agent(BaseAgent):
allow_code_execution: Optional[bool] = Field(
default=False, description="Enable code execution for the agent."
)
max_retry_limit: int = Field(
default=2,
description="Maximum number of retries for an agent to execute a task when an error occurs.",
)
def __init__(__pydantic_self__, **data):
config = data.pop("config", {})
@@ -167,14 +173,15 @@ class Agent(BaseAgent):
if memory.strip() != "":
task_prompt += self.i18n.slice("memory").format(memory=memory)
tools = tools or self.tools
parsed_tools = self._parse_tools(tools or []) # type: ignore # Argument 1 to "_parse_tools" of "Agent" has incompatible type "list[Any] | None"; expected "list[Any]"
tools = tools or self.tools or []
parsed_tools = self._parse_tools(tools)
self.create_agent_executor(tools=tools)
self.agent_executor.tools = parsed_tools
self.agent_executor.task = task
self.agent_executor.tools_description = render_text_description(parsed_tools)
self.agent_executor.tools_description = self._render_text_description_and_args(
parsed_tools
)
self.agent_executor.tools_names = self.__tools_names(parsed_tools)
if self.crew and self.crew._train:
@@ -182,13 +189,20 @@ class Agent(BaseAgent):
else:
task_prompt = self._use_trained_data(task_prompt=task_prompt)
result = self.agent_executor.invoke(
{
"input": task_prompt,
"tool_names": self.agent_executor.tools_names,
"tools": self.agent_executor.tools_description,
}
)["output"]
try:
result = self.agent_executor.invoke(
{
"input": task_prompt,
"tool_names": self.agent_executor.tools_names,
"tools": self.agent_executor.tools_description,
}
)["output"]
except Exception as e:
self._times_executed += 1
if self._times_executed > self.max_retry_limit:
raise e
result = self.execute_task(task, context, tools)
if self.max_rpm:
self._rpm_controller.stop_rpm_counter()
@@ -220,7 +234,7 @@ class Agent(BaseAgent):
Returns:
An instance of the CrewAgentExecutor class.
"""
tools = tools or self.tools
tools = tools or self.tools or []
agent_args = {
"input": lambda x: x["input"],
@@ -246,6 +260,7 @@ class Agent(BaseAgent):
"tools_handler": self.tools_handler,
"function_calling_llm": self.function_calling_llm,
"callbacks": self.callbacks,
"max_tokens": self.max_tokens,
}
if self._rpm_controller:
@@ -315,6 +330,7 @@ class Agent(BaseAgent):
tools_list = []
for tool in tools:
tools_list.append(tool)
return tools_list
def _training_handler(self, task_prompt: str) -> str:
@@ -341,6 +357,52 @@ class Agent(BaseAgent):
)
return task_prompt
def _render_text_description(self, tools: List[BaseTool]) -> str:
"""Render the tool name and description in plain text.
Output will be in the format of:
.. code-block:: markdown
search: This tool is used for search
calculator: This tool is used for math
"""
description = "\n".join(
[
f"Tool name: {tool.name}\nTool description:\n{tool.description}"
for tool in tools
]
)
return description
def _render_text_description_and_args(self, tools: List[BaseTool]) -> str:
"""Render the tool name, description, and args in plain text.
Output will be in the format of:
.. code-block:: markdown
search: This tool is used for search, args: {"query": {"type": "string"}}
calculator: This tool is used for math, \
args: {"expression": {"type": "string"}}
"""
tool_strings = []
for tool in tools:
args_schema = str(tool.args)
if hasattr(tool, "func") and tool.func:
sig = signature(tool.func)
description = (
f"Tool Name: {tool.name}{sig}\nTool Description: {tool.description}"
)
else:
description = (
f"Tool Name: {tool.name}\nTool Description: {tool.description}"
)
tool_strings.append(f"{description}\nTool Arguments: {args_schema}")
return "\n".join(tool_strings)
@staticmethod
def __tools_names(tools) -> str:
return ", ".join([t.name for t in tools])

View File

@@ -1,6 +1,7 @@
import uuid
from abc import ABC, abstractmethod
from copy import copy as shallow_copy
from hashlib import md5
from typing import Any, Dict, List, Optional, TypeVar
from pydantic import (
@@ -44,6 +45,7 @@ class BaseAgent(ABC, BaseModel):
i18n (I18N): Internationalization settings.
cache_handler (InstanceOf[CacheHandler]): An instance of the CacheHandler class.
tools_handler (InstanceOf[ToolsHandler]): An instance of the ToolsHandler class.
max_tokens: Maximum number of tokens for the agent to generate in a response.
Methods:
@@ -117,6 +119,9 @@ class BaseAgent(ABC, BaseModel):
tools_handler: InstanceOf[ToolsHandler] = Field(
default=None, description="An instance of the ToolsHandler class."
)
max_tokens: Optional[int] = Field(
default=None, description="Maximum number of tokens for the agent's execution."
)
_original_role: str | None = None
_original_goal: str | None = None
@@ -162,6 +167,11 @@ class BaseAgent(ABC, BaseModel):
self._token_process = TokenProcess()
return self
@property
def key(self):
source = [self.role, self.goal, self.backstory]
return md5("|".join(source).encode()).hexdigest()
@abstractmethod
def execute_task(
self,
@@ -180,7 +190,7 @@ class BaseAgent(ABC, BaseModel):
pass
@abstractmethod
def get_delegation_tools(self, agents: List["BaseAgent"]):
def get_delegation_tools(self, agents: List["BaseAgent"]) -> List[Any]:
"""Set the task tools that init BaseAgenTools class."""
pass

View File

@@ -3,7 +3,6 @@ from typing import TYPE_CHECKING, Optional
from crewai.memory.entity.entity_memory_item import EntityMemoryItem
from crewai.memory.long_term.long_term_memory_item import LongTermMemoryItem
from crewai.memory.short_term.short_term_memory_item import ShortTermMemoryItem
from crewai.utilities.converter import ConverterError
from crewai.utilities.evaluators.task_evaluator import TaskEvaluator
from crewai.utilities import I18N
@@ -39,18 +38,17 @@ class CrewAgentExecutorMixin:
and "Action: Delegate work to coworker" not in output.log
):
try:
memory = ShortTermMemoryItem(
data=output.log,
agent=self.crew_agent.role,
metadata={
"observation": self.task.description,
},
)
if (
hasattr(self.crew, "_short_term_memory")
and self.crew._short_term_memory
):
self.crew._short_term_memory.save(memory)
self.crew._short_term_memory.save(
value=output.log,
metadata={
"observation": self.task.description,
},
agent=self.crew_agent.role,
)
except Exception as e:
print(f"Failed to add to short term memory: {e}")
pass

View File

@@ -24,6 +24,7 @@ class BaseAgentTools(BaseModel, ABC):
is_list = coworker.startswith("[") and coworker.endswith("]")
if is_list:
coworker = coworker[1:-1].split(",")[0]
return coworker
def delegate_work(
@@ -40,11 +41,13 @@ class BaseAgentTools(BaseModel, ABC):
coworker = self._get_coworker(coworker, **kwargs)
return self._execute(coworker, question, context)
def _execute(self, agent: Union[str, None], task: str, context: Union[str, None]):
def _execute(
self, agent_name: Union[str, None], task: str, context: Union[str, None]
):
"""Execute the command."""
try:
if agent is None:
agent = ""
if agent_name is None:
agent_name = ""
# It is important to remove the quotes from the agent name.
# The reason we have to do this is because less-powerful LLM's
@@ -53,7 +56,7 @@ class BaseAgentTools(BaseModel, ABC):
# {"task": "....", "coworker": "....
# when it should look like this:
# {"task": "....", "coworker": "...."}
agent_name = agent.casefold().replace('"', "").replace("\n", "")
agent_name = agent_name.casefold().replace('"', "").replace("\n", "")
agent = [ # type: ignore # Incompatible types in assignment (expression has type "list[BaseAgent]", variable has type "str | None")
available_agent
@@ -75,9 +78,9 @@ class BaseAgentTools(BaseModel, ABC):
)
agent = agent[0]
task = Task( # type: ignore # Incompatible types in assignment (expression has type "Task", variable has type "str")
task_with_assigned_agent = Task( # type: ignore # Incompatible types in assignment (expression has type "Task", variable has type "str")
description=task,
agent=agent,
expected_output="Your best answer to your coworker asking you this, accounting for the context shared.",
)
return agent.execute_task(task, context) # type: ignore # "str" has no attribute "execute_task"
return agent.execute_task(task_with_assigned_agent, context)

View File

@@ -1,7 +1,7 @@
from abc import ABC, abstractmethod
from typing import Any, Optional
from pydantic import BaseModel, Field, PrivateAttr
from pydantic import BaseModel, Field
class OutputConverter(BaseModel, ABC):
@@ -21,7 +21,6 @@ class OutputConverter(BaseModel, ABC):
max_attempts (int): Maximum number of conversion attempts (default: 3).
"""
_is_gpt: bool = PrivateAttr(default=True)
text: str = Field(description="Text to be converted.")
llm: Any = Field(description="The language model to be used to convert the text.")
model: Any = Field(description="The model to be used to convert the text.")
@@ -41,7 +40,8 @@ class OutputConverter(BaseModel, ABC):
"""Convert text to json."""
pass
@abstractmethod # type: ignore # Name "_is_gpt" already defined on line 25
def _is_gpt(self, llm): # type: ignore # Name "_is_gpt" already defined on line 25
@property
@abstractmethod
def is_gpt(self) -> bool:
"""Return if llm provided is of gpt from openai."""
pass

View File

@@ -1,4 +1,4 @@
from typing import Any, Dict
from crewai.types.usage_metrics import UsageMetrics
class TokenProcess:
@@ -18,10 +18,10 @@ class TokenProcess:
def sum_successful_requests(self, requests: int):
self.successful_requests = self.successful_requests + requests
def get_summary(self) -> Dict[str, Any]:
return {
"total_tokens": self.total_tokens,
"prompt_tokens": self.prompt_tokens,
"completion_tokens": self.completion_tokens,
"successful_requests": self.successful_requests,
}
def get_summary(self) -> UsageMetrics:
return UsageMetrics(
total_tokens=self.total_tokens,
prompt_tokens=self.prompt_tokens,
completion_tokens=self.completion_tokens,
successful_requests=self.successful_requests,
)

View File

@@ -1,14 +1,6 @@
import threading
import time
from typing import (
Any,
Dict,
Iterator,
List,
Optional,
Tuple,
Union,
)
from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
from langchain.agents import AgentExecutor
from langchain.agents.agent import ExceptionTool
@@ -19,9 +11,7 @@ from langchain_core.tools import BaseTool
from langchain_core.utils.input import get_color_mapping
from pydantic import InstanceOf
from crewai.agents.agent_builder.base_agent_executor_mixin import (
CrewAgentExecutorMixin,
)
from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin
from crewai.agents.tools_handler import ToolsHandler
from crewai.tools.tool_usage import ToolUsage, ToolUsageErrorException
from crewai.utilities import I18N
@@ -66,7 +56,7 @@ class CrewAgentExecutor(AgentExecutor, CrewAgentExecutorMixin):
)
intermediate_steps: List[Tuple[AgentAction, str]] = []
# Allowing human input given task setting
if self.task.human_input:
if self.task and self.task.human_input:
self.should_ask_for_human_input = True
# Let's start tracking the number of iterations and time elapsed
@@ -252,6 +242,8 @@ class CrewAgentExecutor(AgentExecutor, CrewAgentExecutorMixin):
else:
if tool_calling.tool_name.casefold().strip() in [
name.casefold().strip() for name in name_to_tool_map
] or tool_calling.tool_name.casefold().replace("_", " ") in [
name.casefold().strip() for name in name_to_tool_map
]:
observation = tool_usage.use(tool_calling, agent_action.log)
else:

View File

@@ -1,6 +1,7 @@
import re
from typing import Any, Union
from json_repair import repair_json
from langchain.agents.output_parsers import ReActSingleInputOutputParser
from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.exceptions import OutputParserException
@@ -48,11 +49,15 @@ class CrewAgentParser(ReActSingleInputOutputParser):
raise OutputParserException(
f"{FINAL_ANSWER_AND_PARSABLE_ACTION_ERROR_MESSAGE}: {text}"
)
action = action_match.group(1).strip()
action_input = action_match.group(2)
tool_input = action_input.strip(" ")
tool_input = tool_input.strip('"')
return AgentAction(action, tool_input, text)
action = action_match.group(1)
clean_action = self._clean_action(action)
action_input = action_match.group(2).strip()
tool_input = action_input.strip(" ").strip('"')
safe_tool_input = self._safe_repair_json(tool_input)
return AgentAction(clean_action, safe_tool_input, text)
elif includes_answer:
return AgentFinish(
@@ -87,3 +92,30 @@ class CrewAgentParser(ReActSingleInputOutputParser):
llm_output=text,
send_to_llm=True,
)
def _clean_action(self, text: str) -> str:
"""Clean action string by removing non-essential formatting characters."""
return re.sub(r"^\s*\*+\s*|\s*\*+\s*$", "", text).strip()
def _safe_repair_json(self, tool_input: str) -> str:
UNABLE_TO_REPAIR_JSON_RESULTS = ['""', "{}"]
# Skip repair if the input starts and ends with square brackets
# Explanation: The JSON parser has issues handling inputs that are enclosed in square brackets ('[]').
# These are typically valid JSON arrays or strings that do not require repair. Attempting to repair such inputs
# might lead to unintended alterations, such as wrapping the entire input in additional layers or modifying
# the structure in a way that changes its meaning. By skipping the repair for inputs that start and end with
# square brackets, we preserve the integrity of these valid JSON structures and avoid unnecessary modifications.
if tool_input.startswith("[") and tool_input.endswith("]"):
return tool_input
# Before repair, handle common LLM issues:
# 1. Replace """ with " to avoid JSON parser errors
tool_input = tool_input.replace('"""', '"')
result = repair_json(tool_input)
if result in UNABLE_TO_REPAIR_JSON_RESULTS:
return tool_input
return str(result)

View File

@@ -1,7 +1,14 @@
import click
import pkg_resources
from crewai.memory.storage.kickoff_task_outputs_storage import (
KickoffTaskOutputsSQLiteStorage,
)
from .create_crew import create_crew
from .evaluate_crew import evaluate_crew
from .replay_from_task import replay_task_command
from .reset_memories_command import reset_memories_command
from .train_crew import train_crew
@@ -48,5 +55,97 @@ def train(n_iterations: int):
train_crew(n_iterations)
@crewai.command()
@click.option(
"-t",
"--task_id",
type=str,
help="Replay the crew from this task ID, including all subsequent tasks.",
)
def replay(task_id: str) -> None:
"""
Replay the crew execution from a specific task.
Args:
task_id (str): The ID of the task to replay from.
"""
try:
click.echo(f"Replaying the crew from task {task_id}")
replay_task_command(task_id)
except Exception as e:
click.echo(f"An error occurred while replaying: {e}", err=True)
@crewai.command()
def log_tasks_outputs() -> None:
"""
Retrieve your latest crew.kickoff() task outputs.
"""
try:
storage = KickoffTaskOutputsSQLiteStorage()
tasks = storage.load()
if not tasks:
click.echo(
"No task outputs found. Only crew kickoff task outputs are logged."
)
return
for index, task in enumerate(tasks, 1):
click.echo(f"Task {index}: {task['task_id']}")
click.echo(f"Description: {task['expected_output']}")
click.echo("------")
except Exception as e:
click.echo(f"An error occurred while logging task outputs: {e}", err=True)
@crewai.command()
@click.option("-l", "--long", is_flag=True, help="Reset LONG TERM memory")
@click.option("-s", "--short", is_flag=True, help="Reset SHORT TERM memory")
@click.option("-e", "--entities", is_flag=True, help="Reset ENTITIES memory")
@click.option(
"-k",
"--kickoff-outputs",
is_flag=True,
help="Reset LATEST KICKOFF TASK OUTPUTS",
)
@click.option("-a", "--all", is_flag=True, help="Reset ALL memories")
def reset_memories(long, short, entities, kickoff_outputs, all):
"""
Reset the crew memories (long, short, entity, latest_crew_kickoff_ouputs). This will delete all the data saved.
"""
try:
if not all and not (long or short or entities or kickoff_outputs):
click.echo(
"Please specify at least one memory type to reset using the appropriate flags."
)
return
reset_memories_command(long, short, entities, kickoff_outputs, all)
except Exception as e:
click.echo(f"An error occurred while resetting memories: {e}", err=True)
@crewai.command()
@click.option(
"-n",
"--n_iterations",
type=int,
default=3,
help="Number of iterations to Test the crew",
)
@click.option(
"-m",
"--model",
type=str,
default="gpt-4o-mini",
help="LLM Model to run the tests on the Crew. For now only accepting only OpenAI models.",
)
def test(n_iterations: int, model: str):
"""Test the crew and evaluate the results."""
click.echo(f"Testing the crew for {n_iterations} iterations with model {model}")
evaluate_crew(n_iterations, model)
if __name__ == "__main__":
crewai()

View File

@@ -0,0 +1,30 @@
import subprocess
import click
def evaluate_crew(n_iterations: int, model: str) -> None:
"""
Test and Evaluate the crew by running a command in the Poetry environment.
Args:
n_iterations (int): The number of iterations to test the crew.
model (str): The model to test the crew with.
"""
command = ["poetry", "run", "test", str(n_iterations), model]
try:
if n_iterations <= 0:
raise ValueError("The number of iterations must be a positive integer.")
result = subprocess.run(command, capture_output=False, text=True, check=True)
if result.stderr:
click.echo(result.stderr, err=True)
except subprocess.CalledProcessError as e:
click.echo(f"An error occurred while testing the crew: {e}", err=True)
click.echo(e.output, err=True)
except Exception as e:
click.echo(f"An unexpected error occurred: {e}", err=True)

View File

@@ -0,0 +1,24 @@
import subprocess
import click
def replay_task_command(task_id: str) -> None:
"""
Replay the crew execution from a specific task.
Args:
task_id (str): The ID of the task to replay from.
"""
command = ["poetry", "run", "replay", task_id]
try:
result = subprocess.run(command, capture_output=False, text=True, check=True)
if result.stderr:
click.echo(result.stderr, err=True)
except subprocess.CalledProcessError as e:
click.echo(f"An error occurred while replaying the task: {e}", err=True)
click.echo(e.output, err=True)
except Exception as e:
click.echo(f"An unexpected error occurred: {e}", err=True)

View File

@@ -0,0 +1,49 @@
import subprocess
import click
from crewai.memory.entity.entity_memory import EntityMemory
from crewai.memory.long_term.long_term_memory import LongTermMemory
from crewai.memory.short_term.short_term_memory import ShortTermMemory
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
def reset_memories_command(long, short, entity, kickoff_outputs, all) -> None:
"""
Reset the crew memories.
Args:
long (bool): Whether to reset the long-term memory.
short (bool): Whether to reset the short-term memory.
entity (bool): Whether to reset the entity memory.
kickoff_outputs (bool): Whether to reset the latest kickoff task outputs.
all (bool): Whether to reset all memories.
"""
try:
if all:
ShortTermMemory().reset()
EntityMemory().reset()
LongTermMemory().reset()
TaskOutputStorageHandler().reset()
click.echo("All memories have been reset.")
else:
if long:
LongTermMemory().reset()
click.echo("Long term memory has been reset.")
if short:
ShortTermMemory().reset()
click.echo("Short term memory has been reset.")
if entity:
EntityMemory().reset()
click.echo("Entity memory has been reset.")
if kickoff_outputs:
TaskOutputStorageHandler().reset()
click.echo("Latest Kickoff outputs stored has been reset.")
except subprocess.CalledProcessError as e:
click.echo(f"An error occurred while resetting the memories: {e}", err=True)
click.echo(e.output, err=True)
except Exception as e:
click.echo(f"An unexpected error occurred: {e}", err=True)

View File

@@ -5,6 +5,7 @@ research_task:
the current year is 2024.
expected_output: >
A list with 10 bullet points of the most relevant information about {topic}
agent: researcher
reporting_task:
description: >
@@ -13,3 +14,4 @@ reporting_task:
expected_output: >
A fully fledge reports with the mains topics, each with a full section of information.
Formatted as markdown without '```'
agent: reporting_analyst

View File

@@ -32,14 +32,12 @@ class {{crew_name}}Crew():
def research_task(self) -> Task:
return Task(
config=self.tasks_config['research_task'],
agent=self.researcher()
)
@task
def reporting_task(self) -> Task:
return Task(
config=self.tasks_config['reporting_task'],
agent=self.reporting_analyst(),
output_file='report.md'
)

View File

@@ -2,9 +2,15 @@
import sys
from {{folder_name}}.crew import {{crew_name}}Crew
# This main file is intended to be a way for your to run your
# crew locally, so refrain from adding necessary logic into this file.
# Replace with inputs you want to test with, it will automatically
# interpolate any tasks and agents information
def run():
# Replace with your inputs, it will automatically interpolate any tasks and agents information
"""
Run the crew.
"""
inputs = {
'topic': 'AI LLMs'
}
@@ -15,9 +21,34 @@ def train():
"""
Train the crew for a given number of iterations.
"""
inputs = {"topic": "AI LLMs"}
inputs = {
"topic": "AI LLMs"
}
try:
{{crew_name}}Crew().crew().train(n_iterations=int(sys.argv[1]), inputs=inputs)
except Exception as e:
raise Exception(f"An error occurred while training the crew: {e}")
def replay():
"""
Replay the crew execution from a specific task.
"""
try:
{{crew_name}}Crew().crew().replay(task_id=sys.argv[1])
except Exception as e:
raise Exception(f"An error occurred while replaying the crew: {e}")
def test():
"""
Test the crew execution and returns the results.
"""
inputs = {
"topic": "AI LLMs"
}
try:
{{crew_name}}Crew().crew().test(n_iterations=int(sys.argv[1]), openai_model_name=sys.argv[2], inputs=inputs)
except Exception as e:
raise Exception(f"An error occurred while replaying the crew: {e}")

View File

@@ -6,11 +6,13 @@ authors = ["Your Name <you@example.com>"]
[tool.poetry.dependencies]
python = ">=3.10,<=3.13"
crewai = { extras = ["tools"], version = "^0.35.8" }
crewai = { extras = ["tools"], version = "^0.46.0" }
[tool.poetry.scripts]
{{folder_name}} = "{{folder_name}}.main:run"
train = "{{folder_name}}.main:train"
replay = "{{folder_name}}.main:replay"
test = "{{folder_name}}.main:test"
[build-system]
requires = ["poetry-core"]

View File

@@ -2,7 +2,8 @@ import asyncio
import json
import uuid
from concurrent.futures import Future
from typing import Any, Dict, List, Optional, Tuple, Union
from hashlib import md5
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
from langchain_core.callbacks import BaseCallbackHandler
from pydantic import (
@@ -27,16 +28,21 @@ from crewai.memory.long_term.long_term_memory import LongTermMemory
from crewai.memory.short_term.short_term_memory import ShortTermMemory
from crewai.process import Process
from crewai.task import Task
from crewai.tasks.conditional_task import ConditionalTask
from crewai.tasks.task_output import TaskOutput
from crewai.telemetry import Telemetry
from crewai.tools.agent_tools import AgentTools
from crewai.types.usage_metrics import UsageMetrics
from crewai.utilities import I18N, FileHandler, Logger, RPMController
from crewai.utilities.constants import TRAINED_AGENTS_DATA_FILE, TRAINING_DATA_FILE
from crewai.utilities.evaluators.crew_evaluator_handler import CrewEvaluator
from crewai.utilities.evaluators.task_evaluator import TaskEvaluator
from crewai.utilities.formatter import (
aggregate_raw_outputs_from_task_outputs,
aggregate_raw_outputs_from_tasks,
)
from crewai.utilities.planning_handler import CrewPlanner
from crewai.utilities.task_output_storage_handler import TaskOutputStorageHandler
from crewai.utilities.training_handler import CrewTrainingHandler
try:
@@ -44,6 +50,9 @@ try:
except ImportError:
agentops = None
if TYPE_CHECKING:
from crewai.pipeline.pipeline import Pipeline
class Crew(BaseModel):
"""
@@ -67,6 +76,7 @@ class Crew(BaseModel):
task_callback: Callback to be executed after each task for every agents execution.
step_callback: Callback to be executed after each step for every agents execution.
share_crew: Whether you want to share the complete crew information and execution with crewAI to make the library better, and allow us to train models.
planning: Plan the crew execution and add the plan to the crew.
"""
__hash__ = object.__hash__ # type: ignore
@@ -80,13 +90,21 @@ class Crew(BaseModel):
_entity_memory: Optional[InstanceOf[EntityMemory]] = PrivateAttr()
_train: Optional[bool] = PrivateAttr(default=False)
_train_iteration: Optional[int] = PrivateAttr()
_inputs: Optional[Dict[str, Any]] = PrivateAttr(default=None)
_logging_color: str = PrivateAttr(
default="bold_purple",
)
_task_output_handler: TaskOutputStorageHandler = PrivateAttr(
default_factory=TaskOutputStorageHandler
)
name: Optional[str] = Field(default=None)
cache: bool = Field(default=True)
model_config = ConfigDict(arbitrary_types_allowed=True)
tasks: List[Task] = Field(default_factory=list)
agents: List[BaseAgent] = Field(default_factory=list)
process: Process = Field(default=Process.sequential)
verbose: Union[int, bool] = Field(default=0)
verbose: int = Field(default=0)
memory: bool = Field(
default=False,
description="Whether the crew should use memory to store memories of it's execution",
@@ -95,7 +113,7 @@ class Crew(BaseModel):
default={"provider": "openai"},
description="Configuration for the embedder to be used for the crew.",
)
usage_metrics: Optional[dict] = Field(
usage_metrics: Optional[UsageMetrics] = Field(
default=None,
description="Metrics for the LLM usage during all tasks execution.",
)
@@ -131,10 +149,26 @@ class Crew(BaseModel):
default=None,
description="Path to the prompt json file to be used for the crew.",
)
output_log_file: Optional[Union[bool, str]] = Field(
default=False,
output_log_file: Optional[str] = Field(
default=None,
description="output_log_file",
)
planning: Optional[bool] = Field(
default=False,
description="Plan the crew execution and add the plan to the crew.",
)
planning_llm: Optional[Any] = Field(
default=None,
description="Language model that will run the AgentPlanner if planning is True.",
)
task_execution_output_json_files: Optional[List[str]] = Field(
default=None,
description="List of file paths for task execution JSON files.",
)
execution_logs: List[Dict[str, Any]] = Field(
default=[],
description="List of execution logs for tasks",
)
@field_validator("id", mode="before")
@classmethod
@@ -170,7 +204,6 @@ class Crew(BaseModel):
self._rpm_controller = RPMController(max_rpm=self.max_rpm, logger=self._logger)
self._telemetry = Telemetry()
self._telemetry.set_tracer()
self._telemetry.crew_creation(self)
return self
@model_validator(mode="after")
@@ -240,20 +273,6 @@ class Crew(BaseModel):
return self
@model_validator(mode="after")
def check_tasks_in_hierarchical_process_not_async(self):
"""Validates that the tasks in hierarchical process are not flagged with async_execution."""
if self.process == Process.hierarchical:
for task in self.tasks:
if task.async_execution:
raise PydanticCustomError(
"async_execution_in_hierarchical_process",
"Hierarchical process error: Tasks cannot be flagged with async_execution.",
{},
)
return self
@model_validator(mode="after")
def validate_end_with_at_most_one_async_task(self):
"""Validates that the crew ends with at most one asynchronous task."""
@@ -275,6 +294,29 @@ class Crew(BaseModel):
return self
@model_validator(mode="after")
def validate_first_task(self) -> "Crew":
"""Ensure the first task is not a ConditionalTask."""
if self.tasks and isinstance(self.tasks[0], ConditionalTask):
raise PydanticCustomError(
"invalid_first_task",
"The first task cannot be a ConditionalTask.",
{},
)
return self
@model_validator(mode="after")
def validate_async_tasks_not_async(self) -> "Crew":
"""Ensure that ConditionalTask is not async."""
for task in self.tasks:
if task.async_execution and isinstance(task, ConditionalTask):
raise PydanticCustomError(
"invalid_async_conditional_task",
f"Conditional Task: {task.description} , cannot be executed asynchronously.", # type: ignore # Argument of type "str" cannot be assigned to parameter "message_template" of type "LiteralString"
{},
)
return self
@model_validator(mode="after")
def validate_async_task_cannot_include_sequential_async_tasks_in_context(self):
"""
@@ -311,6 +353,13 @@ class Crew(BaseModel):
)
return self
@property
def key(self) -> str:
source = [agent.key for agent in self.agents] + [
task.key for task in self.tasks
]
return md5("|".join(source).encode()).hexdigest()
def _setup_from_config(self):
assert self.config is not None, "Config should not be None."
@@ -377,7 +426,11 @@ class Crew(BaseModel):
) -> CrewOutput:
"""Starts the crew to work on its assigned tasks."""
self._execution_span = self._telemetry.crew_execution_span(self, inputs)
self._task_output_handler.reset()
self._logging_color = "bold_purple"
if inputs is not None:
self._inputs = inputs
self._interpolate_inputs(inputs)
self._set_tasks_callbacks()
@@ -399,21 +452,25 @@ class Crew(BaseModel):
agent.create_agent_executor()
metrics = []
if self.planning:
self._handle_crew_planning()
metrics: List[UsageMetrics] = []
if self.process == Process.sequential:
result = self._run_sequential_process()
elif self.process == Process.hierarchical:
result = self._run_hierarchical_process() # type: ignore # Incompatible types in assignment (expression has type "str | dict[str, Any]", variable has type "str")
result = self._run_hierarchical_process()
else:
raise NotImplementedError(
f"The process '{self.process}' is not implemented yet."
)
metrics += [agent._token_process.get_summary() for agent in self.agents]
self.usage_metrics = {
key: sum([m[key] for m in metrics if m is not None]) for key in metrics[0]
}
self.usage_metrics = UsageMetrics()
for metric in metrics:
self.usage_metrics.add_usage_metrics(metric)
return result
@@ -422,12 +479,7 @@ class Crew(BaseModel):
results: List[CrewOutput] = []
# Initialize the parent crew's usage metrics
total_usage_metrics = {
"total_tokens": 0,
"prompt_tokens": 0,
"completion_tokens": 0,
"successful_requests": 0,
}
total_usage_metrics = UsageMetrics()
for input_data in inputs:
crew = self.copy()
@@ -435,12 +487,12 @@ class Crew(BaseModel):
output = crew.kickoff(inputs=input_data)
if crew.usage_metrics:
for key in total_usage_metrics:
total_usage_metrics[key] += crew.usage_metrics.get(key, 0)
total_usage_metrics.add_usage_metrics(crew.usage_metrics)
results.append(output)
self.usage_metrics = total_usage_metrics
self._task_output_handler.reset()
return results
async def kickoff_async(self, inputs: Optional[Dict[str, Any]] = {}) -> CrewOutput:
@@ -464,131 +516,64 @@ class Crew(BaseModel):
results = await asyncio.gather(*tasks)
total_usage_metrics = {
"total_tokens": 0,
"prompt_tokens": 0,
"completion_tokens": 0,
"successful_requests": 0,
}
total_usage_metrics = UsageMetrics()
for crew in crew_copies:
if crew.usage_metrics:
for key in total_usage_metrics:
total_usage_metrics[key] += crew.usage_metrics.get(key, 0)
total_usage_metrics.add_usage_metrics(crew.usage_metrics)
self.usage_metrics = total_usage_metrics
total_usage_metrics = {
"total_tokens": 0,
"prompt_tokens": 0,
"completion_tokens": 0,
"successful_requests": 0,
}
for crew in crew_copies:
if crew.usage_metrics:
for key in total_usage_metrics:
total_usage_metrics[key] += crew.usage_metrics.get(key, 0)
self.usage_metrics = total_usage_metrics
self._task_output_handler.reset()
return results
def _handle_crew_planning(self):
"""Handles the Crew planning."""
self._logger.log("info", "Planning the crew execution")
result = CrewPlanner(
tasks=self.tasks, planning_agent_llm=self.planning_llm
)._handle_crew_planning()
for task, step_plan in zip(self.tasks, result.list_of_plans_per_task):
task.description += step_plan
def _store_execution_log(
self,
task: Task,
output: TaskOutput,
task_index: int,
was_replayed: bool = False,
):
if self._inputs:
inputs = self._inputs
else:
inputs = {}
log = {
"task": task,
"output": {
"description": output.description,
"summary": output.summary,
"raw": output.raw,
"pydantic": output.pydantic,
"json_dict": output.json_dict,
"output_format": output.output_format,
"agent": output.agent,
},
"task_index": task_index,
"inputs": inputs,
"was_replayed": was_replayed,
}
self._task_output_handler.update(task_index, log)
def _run_sequential_process(self) -> CrewOutput:
"""Executes tasks sequentially and returns the final output."""
task_outputs: List[TaskOutput] = []
futures: List[Tuple[Task, Future[TaskOutput]]] = []
return self._execute_tasks(self.tasks)
for task in self.tasks:
if task.agent and task.agent.allow_delegation:
agents_for_delegation = [
agent for agent in self.agents if agent != task.agent
]
if len(self.agents) > 1 and len(agents_for_delegation) > 0:
task.tools += task.agent.get_delegation_tools(agents_for_delegation)
role = task.agent.role if task.agent is not None else "None"
self._logger.log("debug", f"== Working Agent: {role}", color="bold_purple")
self._logger.log(
"info", f"== Starting Task: {task.description}", color="bold_purple"
)
if self.output_log_file:
self._file_handler.log(
agent=role, task=task.description, status="started"
)
if task.async_execution:
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
future = task.execute_async(
agent=task.agent, context=context, tools=task.tools
)
futures.append((task, future))
else:
# Before executing a synchronous task, wait for all async tasks to complete
if futures:
# Clear task_outputs before processing async tasks
task_outputs = []
for future_task, future in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
# Clear the futures list after processing all async results
futures.clear()
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
task_output = task.execute_sync(
agent=task.agent, context=context, tools=task.tools
)
task_outputs = [task_output]
self._process_task_result(task, task_output)
if futures:
# Clear task_outputs before processing async tasks
task_outputs = []
for future_task, future in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
# Important: There should only be one task output in the list
# If there are more or 0, something went wrong.
if len(task_outputs) != 1:
raise ValueError(
"Something went wrong. Kickoff should return only one task output."
)
final_task_output = task_outputs[0]
final_string_output = final_task_output.raw
self._finish_execution(final_string_output)
token_usage = self.calculate_usage_metrics()
return CrewOutput(
raw=final_task_output.raw,
pydantic=final_task_output.pydantic,
json_dict=final_task_output.json_dict,
tasks_output=[task.output for task in self.tasks if task.output],
token_usage=token_usage,
)
def _process_task_result(self, task: Task, output: TaskOutput) -> None:
role = task.agent.role if task.agent is not None else "None"
self._logger.log("debug", f"== [{role}] Task output: {output}\n\n")
if self.output_log_file:
self._file_handler.log(agent=role, task=output, status="completed")
# TODO: @joao, Breaking change. Changed return type. Usage metrics is included in crewoutput
def _run_hierarchical_process(self) -> CrewOutput:
"""Creates and assigns a manager agent to make sure the crew completes the tasks."""
self._create_manager_agent()
return self._execute_tasks(self.tasks)
def _create_manager_agent(self):
i18n = I18N(prompt_file=self.prompt_file)
if self.manager_agent is not None:
self.manager_agent.allow_delegation = True
@@ -607,74 +592,186 @@ class Crew(BaseModel):
)
self.manager_agent = manager
def _execute_tasks(
self,
tasks: List[Task],
start_index: Optional[int] = 0,
was_replayed: bool = False,
) -> CrewOutput:
"""Executes tasks sequentially and returns the final output.
Args:
tasks (List[Task]): List of tasks to execute
manager (Optional[BaseAgent], optional): Manager agent to use for delegation. Defaults to None.
Returns:
CrewOutput: Final output of the crew
"""
task_outputs: List[TaskOutput] = []
futures: List[Tuple[Task, Future[TaskOutput]]] = []
futures: List[Tuple[Task, Future[TaskOutput], int]] = []
last_sync_output: Optional[TaskOutput] = None
# TODO: IF USER OVERRIDE THE CONTEXT, PASS THAT
for task in self.tasks:
self._logger.log("debug", f"Working Agent: {manager.role}")
self._logger.log("info", f"Starting Task: {task.description}")
for task_index, task in enumerate(tasks):
if start_index is not None and task_index < start_index:
if task.output:
if task.async_execution:
task_outputs.append(task.output)
else:
task_outputs = [task.output]
last_sync_output = task.output
continue
if self.output_log_file:
self._file_handler.log(
agent=manager.role, task=task.description, status="started"
agent_to_use = self._get_agent_to_use(task)
if agent_to_use is None:
raise ValueError(
f"No agent available for task: {task.description}. Ensure that either the task has an assigned agent or a manager agent is provided."
)
self._prepare_agent_tools(task)
self._log_task_start(task, agent_to_use.role)
if isinstance(task, ConditionalTask):
skipped_task_output = self._handle_conditional_task(
task, task_outputs, futures, task_index, was_replayed
)
if skipped_task_output:
continue
if task.async_execution:
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
context = self._get_context(
task, [last_sync_output] if last_sync_output else []
)
future = task.execute_async(
agent=manager, context=context, tools=manager.tools
agent=agent_to_use,
context=context,
tools=agent_to_use.tools,
)
futures.append((task, future))
futures.append((task, future, task_index))
else:
# Before executing a synchronous task, wait for all async tasks to complete
if futures:
# Clear task_outputs before processing async tasks
task_outputs = []
for future_task, future in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
# Clear the futures list after processing all async results
task_outputs = self._process_async_tasks(futures, was_replayed)
futures.clear()
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
context = self._get_context(task, task_outputs)
task_output = task.execute_sync(
agent=manager, context=context, tools=manager.tools
agent=agent_to_use,
context=context,
tools=agent_to_use.tools,
)
task_outputs = [task_output]
self._process_task_result(task, task_output)
self._store_execution_log(task, task_output, task_index, was_replayed)
# Process any remaining async results
if futures:
# Clear task_outputs before processing async tasks
task_outputs = []
for future_task, future in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
task_outputs = self._process_async_tasks(futures, was_replayed)
# Important: There should only be one task output in the list
# If there are more or 0, something went wrong.
return self._create_crew_output(task_outputs)
def _handle_conditional_task(
self,
task: ConditionalTask,
task_outputs: List[TaskOutput],
futures: List[Tuple[Task, Future[TaskOutput], int]],
task_index: int,
was_replayed: bool,
) -> Optional[TaskOutput]:
if futures:
task_outputs = self._process_async_tasks(futures, was_replayed)
futures.clear()
previous_output = task_outputs[task_index - 1] if task_outputs else None
if previous_output is not None and not task.should_execute(previous_output):
self._logger.log(
"debug",
f"Skipping conditional task: {task.description}",
color="yellow",
)
skipped_task_output = task.get_skipped_task_output()
if not was_replayed:
self._store_execution_log(task, skipped_task_output, task_index)
return skipped_task_output
return None
def _prepare_agent_tools(self, task: Task):
if self.process == Process.hierarchical:
if self.manager_agent:
self._update_manager_tools(task)
else:
raise ValueError("Manager agent is required for hierarchical process.")
elif task.agent and task.agent.allow_delegation:
self._add_delegation_tools(task)
def _get_agent_to_use(self, task: Task) -> Optional[BaseAgent]:
if self.process == Process.hierarchical:
return self.manager_agent
return task.agent
def _add_delegation_tools(self, task: Task):
agents_for_delegation = [agent for agent in self.agents if agent != task.agent]
if len(self.agents) > 1 and len(agents_for_delegation) > 0 and task.agent:
delegation_tools = task.agent.get_delegation_tools(agents_for_delegation)
# Add tools if they are not already in task.tools
for new_tool in delegation_tools:
# Find the index of the tool with the same name
existing_tool_index = next(
(
index
for index, tool in enumerate(task.tools or [])
if tool.name == new_tool.name
),
None,
)
if not task.tools:
task.tools = []
if existing_tool_index is not None:
# Replace the existing tool
task.tools[existing_tool_index] = new_tool
else:
# Add the new tool
task.tools.append(new_tool)
def _log_task_start(self, task: Task, role: str = "None"):
color = self._logging_color
self._logger.log("debug", f"== Working Agent: {role}", color=color)
self._logger.log("info", f"== Starting Task: {task.description}", color=color)
if self.output_log_file:
self._file_handler.log(agent=role, task=task.description, status="started")
def _update_manager_tools(self, task: Task):
if self.manager_agent:
if task.agent:
self.manager_agent.tools = task.agent.get_delegation_tools([task.agent])
else:
self.manager_agent.tools = self.manager_agent.get_delegation_tools(
self.agents
)
def _get_context(self, task: Task, task_outputs: List[TaskOutput]):
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
return context
def _process_task_result(self, task: Task, output: TaskOutput) -> None:
role = task.agent.role if task.agent is not None else "None"
self._logger.log("debug", f"== [{role}] Task output: {output}\n\n")
if self.output_log_file:
self._file_handler.log(agent=role, task=output, status="completed")
def _create_crew_output(self, task_outputs: List[TaskOutput]) -> CrewOutput:
if len(task_outputs) != 1:
raise ValueError(
"Something went wrong. Kickoff should return only one task output."
)
final_task_output = task_outputs[0]
final_string_output = final_task_output.raw
self._finish_execution(final_string_output)
token_usage = self.calculate_usage_metrics()
return CrewOutput(
@@ -685,6 +782,74 @@ class Crew(BaseModel):
token_usage=token_usage,
)
def _process_async_tasks(
self,
futures: List[Tuple[Task, Future[TaskOutput], int]],
was_replayed: bool = False,
) -> List[TaskOutput]:
task_outputs: List[TaskOutput] = []
for future_task, future, task_index in futures:
task_output = future.result()
task_outputs.append(task_output)
self._process_task_result(future_task, task_output)
self._store_execution_log(
future_task, task_output, task_index, was_replayed
)
return task_outputs
def _find_task_index(
self, task_id: str, stored_outputs: List[Any]
) -> Optional[int]:
return next(
(
index
for (index, d) in enumerate(stored_outputs)
if d["task_id"] == str(task_id)
),
None,
)
def replay(
self, task_id: str, inputs: Optional[Dict[str, Any]] = None
) -> CrewOutput:
stored_outputs = self._task_output_handler.load()
if not stored_outputs:
raise ValueError(f"Task with id {task_id} not found in the crew's tasks.")
start_index = self._find_task_index(task_id, stored_outputs)
if start_index is None:
raise ValueError(f"Task with id {task_id} not found in the crew's tasks.")
replay_inputs = (
inputs if inputs is not None else stored_outputs[start_index]["inputs"]
)
self._inputs = replay_inputs
if replay_inputs:
self._interpolate_inputs(replay_inputs)
if self.process == Process.hierarchical:
self._create_manager_agent()
for i in range(start_index):
stored_output = stored_outputs[i][
"output"
] # for adding context to the task
task_output = TaskOutput(
description=stored_output["description"],
agent=stored_output["agent"],
raw=stored_output["raw"],
pydantic=stored_output["pydantic"],
json_dict=stored_output["json_dict"],
output_format=stored_output["output_format"],
)
self.tasks[i].output = task_output
self._logging_color = "bold_blue"
result = self._execute_tasks(self.tasks, start_index, True)
return result
def copy(self):
"""Create a deep copy of the Crew."""
@@ -745,27 +910,47 @@ class Crew(BaseModel):
)
self._telemetry.end_crew(self, final_string_output)
def calculate_usage_metrics(self) -> Dict[str, int]:
def calculate_usage_metrics(self) -> UsageMetrics:
"""Calculates and returns the usage metrics."""
total_usage_metrics = {
"total_tokens": 0,
"prompt_tokens": 0,
"completion_tokens": 0,
"successful_requests": 0,
}
total_usage_metrics = UsageMetrics()
for agent in self.agents:
if hasattr(agent, "_token_process"):
token_sum = agent._token_process.get_summary()
for key in total_usage_metrics:
total_usage_metrics[key] += token_sum.get(key, 0)
total_usage_metrics.add_usage_metrics(token_sum)
if self.manager_agent and hasattr(self.manager_agent, "_token_process"):
token_sum = self.manager_agent._token_process.get_summary()
for key in total_usage_metrics:
total_usage_metrics[key] += token_sum.get(key, 0)
total_usage_metrics.add_usage_metrics(token_sum)
return total_usage_metrics
def test(
self,
n_iterations: int,
openai_model_name: str,
inputs: Optional[Dict[str, Any]] = None,
) -> None:
"""Test and evaluate the Crew with the given inputs for n iterations."""
evaluator = CrewEvaluator(self, openai_model_name)
for i in range(1, n_iterations + 1):
evaluator.set_iteration(i)
self.kickoff(inputs=inputs)
evaluator.print_crew_evaluation_result()
def __rshift__(self, other: "Crew") -> "Pipeline":
"""
Implements the >> operator to add another Crew to an existing Pipeline.
"""
from crewai.pipeline.pipeline import Pipeline
if not isinstance(other, Crew):
raise TypeError(
f"Unsupported operand type for >>: '{type(self).__name__}' and '{type(other).__name__}'"
)
return Pipeline(stages=[self, other])
def __repr__(self):
return f"Crew(id={self.id}, process={self.process}, number_of_agents={len(self.agents)}, number_of_tasks={len(self.tasks)})"

View File

@@ -5,6 +5,7 @@ from pydantic import BaseModel, Field
from crewai.tasks.output_format import OutputFormat
from crewai.tasks.task_output import TaskOutput
from crewai.types.usage_metrics import UsageMetrics
class CrewOutput(BaseModel):
@@ -20,21 +21,7 @@ class CrewOutput(BaseModel):
tasks_output: list[TaskOutput] = Field(
description="Output of each task", default=[]
)
token_usage: Dict[str, Any] = Field(
description="Processed token summary", default={}
)
# TODO: Joao - Adding this safety check breakes when people want to see
# The full output of a CrewOutput.
# @property
# def pydantic(self) -> Optional[BaseModel]:
# # Check if the final task output included a pydantic model
# if self.tasks_output[-1].output_format != OutputFormat.PYDANTIC:
# raise ValueError(
# "No pydantic model found in the final task. Please make sure to set the output_pydantic property in the final task in your crew."
# )
# return self._pydantic
token_usage: UsageMetrics = Field(description="Processed token summary", default={})
@property
def json(self) -> Optional[str]:
@@ -46,11 +33,13 @@ class CrewOutput(BaseModel):
return json.dumps(self.json_dict)
def to_dict(self) -> Dict[str, Any]:
"""Convert json_output and pydantic_output to a dictionary."""
output_dict = {}
if self.json_dict:
return self.json_dict
if self.pydantic:
return self.pydantic.model_dump()
raise ValueError("No output to convert to dictionary")
output_dict.update(self.json_dict)
elif self.pydantic:
output_dict.update(self.pydantic.model_dump())
return output_dict
def __str__(self):
if self.pydantic:

View File

@@ -23,3 +23,9 @@ class EntityMemory(Memory):
"""Saves an entity item into the SQLite storage."""
data = f"{item.name}({item.type}): {item.description}"
super().save(data, item.metadata)
def reset(self) -> None:
try:
self.storage.reset()
except Exception as e:
raise Exception(f"An error occurred while resetting the entity memory: {e}")

View File

@@ -30,3 +30,6 @@ class LongTermMemory(Memory):
def search(self, task: str, latest_n: int = 3) -> Dict[str, Any]:
return self.storage.load(task, latest_n) # type: ignore # BUG?: "Storage" has no attribute "load"
def reset(self) -> None:
self.storage.reset()

View File

@@ -1,3 +1,4 @@
from typing import Any, Dict, Optional
from crewai.memory.memory import Memory
from crewai.memory.short_term.short_term_memory_item import ShortTermMemoryItem
from crewai.memory.storage.rag_storage import RAGStorage
@@ -18,8 +19,23 @@ class ShortTermMemory(Memory):
)
super().__init__(storage)
def save(self, item: ShortTermMemoryItem) -> None: # type: ignore # BUG?: Signature of "save" incompatible with supertype "Memory"
super().save(item.data, item.metadata, item.agent)
def save(
self,
value: Any,
metadata: Optional[Dict[str, Any]] = None,
agent: Optional[str] = None,
) -> None:
item = ShortTermMemoryItem(data=value, metadata=metadata, agent=agent)
super().save(value=item.data, metadata=item.metadata, agent=item.agent)
def search(self, query: str, score_threshold: float = 0.35):
return self.storage.search(query=query, score_threshold=score_threshold) # type: ignore # BUG? The reference is to the parent class, but the parent class does not have this parameters
def reset(self) -> None:
try:
self.storage.reset()
except Exception as e:
raise Exception(
f"An error occurred while resetting the short-term memory: {e}"
)

View File

@@ -3,7 +3,10 @@ from typing import Any, Dict, Optional
class ShortTermMemoryItem:
def __init__(
self, data: Any, agent: str, metadata: Optional[Dict[str, Any]] = None
self,
data: Any,
agent: Optional[str] = None,
metadata: Optional[Dict[str, Any]] = None,
):
self.data = data
self.agent = agent

View File

@@ -4,8 +4,11 @@ from typing import Any, Dict
class Storage:
"""Abstract base class defining the storage interface"""
def save(self, key: str, value: Any, metadata: Dict[str, Any]) -> None:
def save(self, value: Any, metadata: Dict[str, Any]) -> None:
pass
def search(self, key: str) -> Dict[str, Any]: # type: ignore
pass
def reset(self) -> None:
pass

View File

@@ -0,0 +1,166 @@
import json
import sqlite3
from typing import Any, Dict, List, Optional
from crewai.task import Task
from crewai.utilities import Printer
from crewai.utilities.crew_json_encoder import CrewJSONEncoder
from crewai.utilities.paths import db_storage_path
class KickoffTaskOutputsSQLiteStorage:
"""
An updated SQLite storage class for kickoff task outputs storage.
"""
def __init__(
self, db_path: str = f"{db_storage_path()}/latest_kickoff_task_outputs.db"
) -> None:
self.db_path = db_path
self._printer: Printer = Printer()
self._initialize_db()
def _initialize_db(self):
"""
Initializes the SQLite database and creates LTM table
"""
try:
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute(
"""
CREATE TABLE IF NOT EXISTS latest_kickoff_task_outputs (
task_id TEXT PRIMARY KEY,
expected_output TEXT,
output JSON,
task_index INTEGER,
inputs JSON,
was_replayed BOOLEAN,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
)
"""
)
conn.commit()
except sqlite3.Error as e:
self._printer.print(
content=f"SAVING KICKOFF TASK OUTPUTS ERROR: An error occurred during database initialization: {e}",
color="red",
)
def add(
self,
task: Task,
output: Dict[str, Any],
task_index: int,
was_replayed: bool = False,
inputs: Dict[str, Any] = {},
):
try:
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute(
"""
INSERT OR REPLACE INTO latest_kickoff_task_outputs
(task_id, expected_output, output, task_index, inputs, was_replayed)
VALUES (?, ?, ?, ?, ?, ?)
""",
(
str(task.id),
task.expected_output,
json.dumps(output, cls=CrewJSONEncoder),
task_index,
json.dumps(inputs),
was_replayed,
),
)
conn.commit()
except sqlite3.Error as e:
self._printer.print(
content=f"SAVING KICKOFF TASK OUTPUTS ERROR: An error occurred during database initialization: {e}",
color="red",
)
def update(
self,
task_index: int,
**kwargs,
):
"""
Updates an existing row in the latest_kickoff_task_outputs table based on task_index.
"""
try:
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
fields = []
values = []
for key, value in kwargs.items():
fields.append(f"{key} = ?")
values.append(
json.dumps(value, cls=CrewJSONEncoder)
if isinstance(value, dict)
else value
)
query = f"UPDATE latest_kickoff_task_outputs SET {', '.join(fields)} WHERE task_index = ?"
values.append(task_index)
cursor.execute(query, tuple(values))
conn.commit()
if cursor.rowcount == 0:
self._printer.print(
f"No row found with task_index {task_index}. No update performed.",
color="red",
)
except sqlite3.Error as e:
self._printer.print(f"UPDATE KICKOFF TASK OUTPUTS ERROR: {e}", color="red")
def load(self) -> Optional[List[Dict[str, Any]]]:
try:
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute("""
SELECT *
FROM latest_kickoff_task_outputs
ORDER BY task_index
""")
rows = cursor.fetchall()
results = []
for row in rows:
result = {
"task_id": row[0],
"expected_output": row[1],
"output": json.loads(row[2]),
"task_index": row[3],
"inputs": json.loads(row[4]),
"was_replayed": row[5],
"timestamp": row[6],
}
results.append(result)
return results
except sqlite3.Error as e:
self._printer.print(
content=f"LOADING KICKOFF TASK OUTPUTS ERROR: An error occurred while querying kickoff task outputs: {e}",
color="red",
)
return None
def delete_all(self):
"""
Deletes all rows from the latest_kickoff_task_outputs table.
"""
try:
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute("DELETE FROM latest_kickoff_task_outputs")
conn.commit()
except sqlite3.Error as e:
self._printer.print(
content=f"ERROR: Failed to delete all kickoff task outputs: {e}",
color="red",
)

View File

@@ -103,3 +103,20 @@ class LTMSQLiteStorage:
color="red",
)
return None
def reset(
self,
) -> None:
"""Resets the LTM table with error handling."""
try:
with sqlite3.connect(self.db_path) as conn:
cursor = conn.cursor()
cursor.execute("DELETE FROM long_term_memories")
conn.commit()
except sqlite3.Error as e:
self._printer.print(
content=f"MEMORY ERROR: An error occurred while deleting all rows in LTM: {e}",
color="red",
)
return None

View File

@@ -2,6 +2,7 @@ import contextlib
import io
import logging
import os
import shutil
from typing import Any, Dict, List, Optional
from embedchain import App
@@ -71,13 +72,13 @@ class RAGStorage(Storage):
if embedder_config:
config["embedder"] = embedder_config
self.type = type
self.app = App.from_config(config=config)
self.app.llm = FakeLLM()
if allow_reset:
self.app.reset()
def save(self, value: Any, metadata: Dict[str, Any]) -> None: # type: ignore # BUG?: Should be save(key, value, metadata) Signature of "save" incompatible with supertype "Storage"
def save(self, value: Any, metadata: Dict[str, Any]) -> None:
self._generate_embedding(value, metadata)
def search( # type: ignore # BUG?: Signature of "search" incompatible with supertype "Storage"
@@ -102,3 +103,11 @@ class RAGStorage(Storage):
def _generate_embedding(self, text: str, metadata: Dict[str, Any]) -> Any:
with suppress_logging():
self.app.add(text, data_type="text", metadata=metadata)
def reset(self) -> None:
try:
shutil.rmtree(f"{db_storage_path()}/{self.type}")
except Exception as e:
raise Exception(
f"An error occurred while resetting the {self.type} memory: {e}"
)

View File

@@ -0,0 +1,3 @@
from crewai.pipeline.pipeline import Pipeline
__all__ = ["Pipeline"]

View File

@@ -0,0 +1,371 @@
import asyncio
import copy
from typing import Any, Dict, List, Tuple, Union
from pydantic import BaseModel, Field, model_validator
from crewai.crew import Crew
from crewai.crews.crew_output import CrewOutput
from crewai.pipeline.pipeline_kickoff_result import PipelineKickoffResult
from crewai.types.usage_metrics import UsageMetrics
Trace = Union[Union[str, Dict[str, Any]], List[Union[str, Dict[str, Any]]]]
"""
Developer Notes:
This module defines a Pipeline class that represents a sequence of operations (stages)
to process inputs. Each stage can be either sequential or parallel, and the pipeline
can process multiple kickoffs concurrently.
Core Loop Explanation:
1. The `process_kickoffs` method processes multiple kickoffs in parallel, each going through
all pipeline stages.
2. The `process_single_kickoff` method handles the processing of a single kickouff through
all stages, updating metrics and input data along the way.
3. The `_process_stage` method determines whether a stage is sequential or parallel
and processes it accordingly.
4. The `_process_single_crew` and `_process_parallel_crews` methods handle the
execution of single and parallel crew stages.
5. The `_update_metrics_and_input` method updates usage metrics and the current input
with the outputs from a stage.
6. The `_build_pipeline_kickoff_results` method constructs the final results of the
pipeline kickoff, including traces and outputs.
Handling Traces and Crew Outputs:
- During the processing of stages, we handle the results (traces and crew outputs)
for all stages except the last one differently from the final stage.
- For intermediate stages, the primary focus is on passing the input data between stages.
This involves merging the output dictionaries from all crews in a stage into a single
dictionary and passing it to the next stage. This merged dictionary allows for smooth
data flow between stages.
- For the final stage, in addition to passing the input data, we also need to prepare
the final outputs and traces to be returned as the overall result of the pipeline kickoff.
In this case, we do not merge the results, as each result needs to be included
separately in its own pipeline kickoff result.
Pipeline Terminology:
- Pipeline: The overall structure that defines a sequence of operations.
- Stage: A distinct part of the pipeline, which can be either sequential or parallel.
- Kickoff: A specific execution of the pipeline for a given set of inputs, representing a single instance of processing through the pipeline.
- Branch: Parallel executions within a stage (e.g., concurrent crew operations).
- Trace: The journey of an individual input through the entire pipeline.
Example pipeline structure:
crew1 >> crew2 >> crew3
This represents a pipeline with three sequential stages:
1. crew1 is the first stage, which processes the input and passes its output to crew2.
2. crew2 is the second stage, which takes the output from crew1 as its input, processes it, and passes its output to crew3.
3. crew3 is the final stage, which takes the output from crew2 as its input and produces the final output of the pipeline.
Each input creates its own kickoff, flowing through all stages of the pipeline.
Multiple kickoffss can be processed concurrently, each following the defined pipeline structure.
Another example pipeline structure:
crew1 >> [crew2, crew3] >> crew4
This represents a pipeline with three stages:
1. A sequential stage (crew1)
2. A parallel stage with two branches (crew2 and crew3 executing concurrently)
3. Another sequential stage (crew4)
Each input creates its own kickoff, flowing through all stages of the pipeline.
Multiple kickoffs can be processed concurrently, each following the defined pipeline structure.
"""
class Pipeline(BaseModel):
stages: List[Union[Crew, List[Crew]]] = Field(
..., description="List of crews representing stages to be executed in sequence"
)
@model_validator(mode="before")
@classmethod
def validate_stages(cls, values):
"""
Validates the stages to ensure correct nesting and types.
Args:
values (dict): Dictionary containing the pipeline stages.
Returns:
dict: Validated stages.
"""
stages = values.get("stages", [])
def check_nesting_and_type(item, depth=0):
if depth > 1:
raise ValueError("Double nesting is not allowed in pipeline stages")
if isinstance(item, list):
for sub_item in item:
check_nesting_and_type(sub_item, depth + 1)
elif not isinstance(item, Crew):
raise ValueError(
f"Expected Crew instance or list of Crews, got {type(item)}"
)
for stage in stages:
check_nesting_and_type(stage)
return values
async def kickoff(
self, inputs: List[Dict[str, Any]]
) -> List[PipelineKickoffResult]:
"""
Processes multiple runs in parallel, each going through all pipeline stages.
Args:
inputs (List[Dict[str, Any]]): List of inputs for each run.
Returns:
List[PipelineKickoffResult]: List of results from each run.
"""
pipeline_results: List[PipelineKickoffResult] = []
# Process all runs in parallel
all_run_results = await asyncio.gather(
*(self.process_single_kickoff(input_data) for input_data in inputs)
)
# Flatten the list of lists into a single list of results
pipeline_results.extend(
result for run_result in all_run_results for result in run_result
)
return pipeline_results
async def process_single_kickoff(
self, kickoff_input: Dict[str, Any]
) -> List[PipelineKickoffResult]:
"""
Processes a single run through all pipeline stages.
Args:
input (Dict[str, Any]): The input for the run.
Returns:
List[PipelineKickoffResult]: The results of processing the run.
"""
initial_input = copy.deepcopy(kickoff_input)
current_input = copy.deepcopy(kickoff_input)
pipeline_usage_metrics: Dict[str, UsageMetrics] = {}
all_stage_outputs: List[List[CrewOutput]] = []
traces: List[List[Union[str, Dict[str, Any]]]] = [[initial_input]]
for stage in self.stages:
stage_input = copy.deepcopy(current_input)
stage_outputs, stage_trace = await self._process_stage(stage, stage_input)
self._update_metrics_and_input(
pipeline_usage_metrics, current_input, stage, stage_outputs
)
traces.append(stage_trace)
all_stage_outputs.append(stage_outputs)
return self._build_pipeline_kickoff_results(
all_stage_outputs, traces, pipeline_usage_metrics
)
async def _process_stage(
self, stage: Union[Crew, List[Crew]], current_input: Dict[str, Any]
) -> Tuple[List[CrewOutput], List[Union[str, Dict[str, Any]]]]:
"""
Processes a single stage of the pipeline, which can be either sequential or parallel.
Args:
stage (Union[Crew, List[Crew]]): The stage to process.
current_input (Dict[str, Any]): The input for the stage.
Returns:
Tuple[List[CrewOutput], List[Union[str, Dict[str, Any]]]]: The outputs and trace of the stage.
"""
if isinstance(stage, Crew):
return await self._process_single_crew(stage, current_input)
else:
return await self._process_parallel_crews(stage, current_input)
async def _process_single_crew(
self, crew: Crew, current_input: Dict[str, Any]
) -> Tuple[List[CrewOutput], List[Union[str, Dict[str, Any]]]]:
"""
Processes a single crew.
Args:
crew (Crew): The crew to process.
current_input (Dict[str, Any]): The input for the crew.
Returns:
Tuple[List[CrewOutput], List[Union[str, Dict[str, Any]]]]: The output and trace of the crew.
"""
output = await crew.kickoff_async(inputs=current_input)
return [output], [crew.name or str(crew.id)]
async def _process_parallel_crews(
self, crews: List[Crew], current_input: Dict[str, Any]
) -> Tuple[List[CrewOutput], List[Union[str, Dict[str, Any]]]]:
"""
Processes multiple crews in parallel.
Args:
crews (List[Crew]): The list of crews to process in parallel.
current_input (Dict[str, Any]): The input for the crews.
Returns:
Tuple[List[CrewOutput], List[Union[str, Dict[str, Any]]]]: The outputs and traces of the crews.
"""
parallel_outputs = await asyncio.gather(
*[crew.kickoff_async(inputs=current_input) for crew in crews]
)
return parallel_outputs, [crew.name or str(crew.id) for crew in crews]
def _update_metrics_and_input(
self,
usage_metrics: Dict[str, UsageMetrics],
current_input: Dict[str, Any],
stage: Union[Crew, List[Crew]],
outputs: List[CrewOutput],
) -> None:
"""
Updates metrics and current input with the outputs of a stage.
Args:
usage_metrics (Dict[str, Any]): The usage metrics to update.
current_input (Dict[str, Any]): The current input to update.
stage (Union[Crew, List[Crew]]): The stage that was processed.
outputs (List[CrewOutput]): The outputs of the stage.
"""
for crew, output in zip([stage] if isinstance(stage, Crew) else stage, outputs):
usage_metrics[crew.name or str(crew.id)] = output.token_usage
current_input.update(output.to_dict())
def _build_pipeline_kickoff_results(
self,
all_stage_outputs: List[List[CrewOutput]],
traces: List[List[Union[str, Dict[str, Any]]]],
token_usage: Dict[str, UsageMetrics],
) -> List[PipelineKickoffResult]:
"""
Builds the results of a pipeline run.
Args:
all_stage_outputs (List[List[CrewOutput]]): All stage outputs.
traces (List[List[Union[str, Dict[str, Any]]]]): All traces.
token_usage (Dict[str, Any]): Token usage metrics.
Returns:
List[PipelineKickoffResult]: The results of the pipeline run.
"""
formatted_traces = self._format_traces(traces)
formatted_crew_outputs = self._format_crew_outputs(all_stage_outputs)
return [
PipelineKickoffResult(
token_usage=token_usage,
trace=formatted_trace,
raw=crews_outputs[-1].raw,
pydantic=crews_outputs[-1].pydantic,
json_dict=crews_outputs[-1].json_dict,
crews_outputs=crews_outputs,
)
for crews_outputs, formatted_trace in zip(
formatted_crew_outputs, formatted_traces
)
]
def _format_traces(
self, traces: List[List[Union[str, Dict[str, Any]]]]
) -> List[List[Trace]]:
"""
Formats the traces of a pipeline run.
Args:
traces (List[List[Union[str, Dict[str, Any]]]]): The traces to format.
Returns:
List[List[Trace]]: The formatted traces.
"""
formatted_traces: List[Trace] = self._format_single_trace(traces[:-1])
return self._format_multiple_traces(formatted_traces, traces[-1])
def _format_single_trace(
self, traces: List[List[Union[str, Dict[str, Any]]]]
) -> List[Trace]:
"""
Formats single traces.
Args:
traces (List[List[Union[str, Dict[str, Any]]]]): The traces to format.
Returns:
List[Trace]: The formatted single traces.
"""
formatted_traces: List[Trace] = []
for trace in traces:
formatted_traces.append(trace[0] if len(trace) == 1 else trace)
return formatted_traces
def _format_multiple_traces(
self,
formatted_traces: List[Trace],
final_trace: List[Union[str, Dict[str, Any]]],
) -> List[List[Trace]]:
"""
Formats multiple traces.
Args:
formatted_traces (List[Trace]): The formatted single traces.
final_trace (List[Union[str, Dict[str, Any]]]): The final trace to format.
Returns:
List[List[Trace]]: The formatted multiple traces.
"""
traces_to_return: List[List[Trace]] = []
if len(final_trace) == 1:
formatted_traces.append(final_trace[0])
traces_to_return.append(formatted_traces)
else:
for trace in final_trace:
copied_traces = formatted_traces.copy()
copied_traces.append(trace)
traces_to_return.append(copied_traces)
return traces_to_return
def _format_crew_outputs(
self, all_stage_outputs: List[List[CrewOutput]]
) -> List[List[CrewOutput]]:
"""
Formats the outputs of all stages into a list of crew outputs.
Args:
all_stage_outputs (List[List[CrewOutput]]): All stage outputs.
Returns:
List[List[CrewOutput]]: Formatted crew outputs.
"""
crew_outputs: List[CrewOutput] = [
output
for stage_outputs in all_stage_outputs[:-1]
for output in stage_outputs
]
return [crew_outputs + [output] for output in all_stage_outputs[-1]]
def __rshift__(self, other: Any) -> "Pipeline":
"""
Implements the >> operator to add another Stage (Crew or List[Crew]) to an existing Pipeline.
Args:
other (Any): The stage to add.
Returns:
Pipeline: A new pipeline with the added stage.
"""
if isinstance(other, Crew):
return type(self)(stages=self.stages + [other])
elif isinstance(other, list) and all(isinstance(crew, Crew) for crew in other):
return type(self)(stages=self.stages + [other])
else:
raise TypeError(
f"Unsupported operand type for >>: '{type(self).__name__}' and '{type(other).__name__}'"
)

View File

@@ -0,0 +1,61 @@
import json
import uuid
from typing import Any, Dict, List, Optional, Union
from pydantic import UUID4, BaseModel, Field
from crewai.crews.crew_output import CrewOutput
from crewai.types.usage_metrics import UsageMetrics
class PipelineKickoffResult(BaseModel):
"""Class that represents the result of a pipeline run."""
id: UUID4 = Field(
default_factory=uuid.uuid4,
frozen=True,
description="Unique identifier for the object, not set by user.",
)
raw: str = Field(description="Raw output of the pipeline run", default="")
pydantic: Any = Field(
description="Pydantic output of the pipeline run", default=None
)
json_dict: Union[Dict[str, Any], None] = Field(
description="JSON dict output of the pipeline run", default={}
)
token_usage: Dict[str, UsageMetrics] = Field(
description="Token usage for each crew in the run"
)
trace: List[Any] = Field(
description="Trace of the journey of inputs through the run"
)
crews_outputs: List[CrewOutput] = Field(
description="Output from each crew in the run",
default=[],
)
@property
def json(self) -> Optional[str]:
if self.crews_outputs[-1].tasks_output[-1].output_format != "json":
raise ValueError(
"No JSON output found in the final task of the final crew. Please make sure to set the output_json property in the final task in your crew."
)
return json.dumps(self.json_dict)
def to_dict(self) -> Dict[str, Any]:
"""Convert json_output and pydantic_output to a dictionary."""
output_dict = {}
if self.json_dict:
output_dict.update(self.json_dict)
elif self.pydantic:
output_dict.update(self.pydantic.model_dump())
return output_dict
def __str__(self):
if self.pydantic:
return str(self.pydantic)
if self.json_dict:
return str(self.json_dict)
return self.raw

View File

@@ -0,0 +1,20 @@
import uuid
from typing import List
from pydantic import UUID4, BaseModel, Field
from crewai.pipeline.pipeline_kickoff_result import PipelineKickoffResult
class PipelineOutput(BaseModel):
id: UUID4 = Field(
default_factory=uuid.uuid4,
frozen=True,
description="Unique identifier for the object, not set by user.",
)
run_results: List[PipelineKickoffResult] = Field(
description="List of results for each run through the pipeline", default=[]
)
def add_run_result(self, result: PipelineKickoffResult):
self.run_results.append(result)

View File

@@ -1,2 +1,25 @@
from .annotations import agent, crew, task
from .annotations import (
agent,
crew,
task,
output_json,
output_pydantic,
tool,
callback,
llm,
cache_handler,
)
from .crew_base import CrewBase
__all__ = [
"agent",
"crew",
"task",
"output_json",
"output_pydantic",
"tool",
"callback",
"CrewBase",
"llm",
"cache_handler",
]

View File

@@ -30,6 +30,37 @@ def agent(func):
return func
def llm(func):
func.is_llm = True
func = memoize(func)
return func
def output_json(cls):
cls.is_output_json = True
return cls
def output_pydantic(cls):
cls.is_output_pydantic = True
return cls
def tool(func):
func.is_tool = True
return memoize(func)
def callback(func):
func.is_callback = True
return memoize(func)
def cache_handler(func):
func.is_cache_handler = True
return memoize(func)
def crew(func):
def wrapper(self, *args, **kwargs):
instantiated_tasks = []

View File

@@ -1,6 +1,7 @@
import inspect
import os
from pathlib import Path
from typing import Any, Callable, Dict
import yaml
from dotenv import load_dotenv
@@ -20,11 +21,6 @@ def CrewBase(cls):
base_directory = Path(frame_info.filename).parent.resolve()
break
if base_directory is None:
raise Exception(
"Unable to dynamically determine the project's base directory, you must run it from the project's root directory."
)
original_agents_config_path = getattr(
cls, "agents_config", "config/agents.yaml"
)
@@ -32,12 +28,20 @@ def CrewBase(cls):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.base_directory is None:
raise Exception(
"Unable to dynamically determine the project's base directory, you must run it from the project's root directory."
)
self.agents_config = self.load_yaml(
os.path.join(self.base_directory, self.original_agents_config_path)
)
self.tasks_config = self.load_yaml(
os.path.join(self.base_directory, self.original_tasks_config_path)
)
self.map_all_agent_variables()
self.map_all_task_variables()
@staticmethod
def load_yaml(config_path: str):
@@ -45,4 +49,138 @@ def CrewBase(cls):
# parsedContent = YamlParser.parse(file) # type: ignore # Argument 1 to "parse" has incompatible type "TextIOWrapper"; expected "YamlParser"
return yaml.safe_load(file)
def _get_all_functions(self):
return {
name: getattr(self, name)
for name in dir(self)
if callable(getattr(self, name))
}
def _filter_functions(
self, functions: Dict[str, Callable], attribute: str
) -> Dict[str, Callable]:
return {
name: func
for name, func in functions.items()
if hasattr(func, attribute)
}
def map_all_agent_variables(self) -> None:
all_functions = self._get_all_functions()
llms = self._filter_functions(all_functions, "is_llm")
tool_functions = self._filter_functions(all_functions, "is_tool")
cache_handler_functions = self._filter_functions(
all_functions, "is_cache_handler"
)
callbacks = self._filter_functions(all_functions, "is_callback")
agents = self._filter_functions(all_functions, "is_agent")
for agent_name, agent_info in self.agents_config.items():
self._map_agent_variables(
agent_name,
agent_info,
agents,
llms,
tool_functions,
cache_handler_functions,
callbacks,
)
def _map_agent_variables(
self,
agent_name: str,
agent_info: Dict[str, Any],
agents: Dict[str, Callable],
llms: Dict[str, Callable],
tool_functions: Dict[str, Callable],
cache_handler_functions: Dict[str, Callable],
callbacks: Dict[str, Callable],
) -> None:
if llm := agent_info.get("llm"):
self.agents_config[agent_name]["llm"] = llms[llm]()
if tools := agent_info.get("tools"):
self.agents_config[agent_name]["tools"] = [
tool_functions[tool]() for tool in tools
]
if function_calling_llm := agent_info.get("function_calling_llm"):
self.agents_config[agent_name]["function_calling_llm"] = agents[
function_calling_llm
]()
if step_callback := agent_info.get("step_callback"):
self.agents_config[agent_name]["step_callback"] = callbacks[
step_callback
]()
if cache_handler := agent_info.get("cache_handler"):
self.agents_config[agent_name]["cache_handler"] = (
cache_handler_functions[cache_handler]()
)
def map_all_task_variables(self) -> None:
all_functions = self._get_all_functions()
agents = self._filter_functions(all_functions, "is_agent")
tasks = self._filter_functions(all_functions, "is_task")
output_json_functions = self._filter_functions(
all_functions, "is_output_json"
)
tool_functions = self._filter_functions(all_functions, "is_tool")
callback_functions = self._filter_functions(all_functions, "is_callback")
output_pydantic_functions = self._filter_functions(
all_functions, "is_output_pydantic"
)
for task_name, task_info in self.tasks_config.items():
self._map_task_variables(
task_name,
task_info,
agents,
tasks,
output_json_functions,
tool_functions,
callback_functions,
output_pydantic_functions,
)
def _map_task_variables(
self,
task_name: str,
task_info: Dict[str, Any],
agents: Dict[str, Callable],
tasks: Dict[str, Callable],
output_json_functions: Dict[str, Callable],
tool_functions: Dict[str, Callable],
callback_functions: Dict[str, Callable],
output_pydantic_functions: Dict[str, Callable],
) -> None:
if context_list := task_info.get("context"):
self.tasks_config[task_name]["context"] = [
tasks[context_task_name]() for context_task_name in context_list
]
if tools := task_info.get("tools"):
self.tasks_config[task_name]["tools"] = [
tool_functions[tool]() for tool in tools
]
if agent_name := task_info.get("agent"):
self.tasks_config[task_name]["agent"] = agents[agent_name]()
if output_json := task_info.get("output_json"):
self.tasks_config[task_name]["output_json"] = output_json_functions[
output_json
]
if output_pydantic := task_info.get("output_pydantic"):
self.tasks_config[task_name]["output_pydantic"] = (
output_pydantic_functions[output_pydantic]
)
if callbacks := task_info.get("callbacks"):
self.tasks_config[task_name]["callbacks"] = [
callback_functions[callback]() for callback in callbacks
]
return WrappedClass

View File

@@ -1,13 +1,13 @@
import datetime
import json
import os
import re
import threading
import uuid
from concurrent.futures import Future
from copy import copy
from hashlib import md5
from typing import Any, Dict, List, Optional, Tuple, Type, Union
from langchain_openai import ChatOpenAI
from opentelemetry.trace import Span
from pydantic import UUID4, BaseModel, Field, field_validator, model_validator
from pydantic_core import PydanticCustomError
@@ -16,10 +16,8 @@ from crewai.agents.agent_builder.base_agent import BaseAgent
from crewai.tasks.output_format import OutputFormat
from crewai.tasks.task_output import TaskOutput
from crewai.telemetry.telemetry import Telemetry
from crewai.utilities.converter import Converter, ConverterError
from crewai.utilities.converter import Converter, convert_to_model
from crewai.utilities.i18n import I18N
from crewai.utilities.printer import Printer
from crewai.utilities.pydantic_schema_parser import PydanticSchemaParser
class Task(BaseModel):
@@ -49,6 +47,7 @@ class Task(BaseModel):
tools_errors: int = 0
delegations: int = 0
i18n: I18N = I18N()
name: Optional[str] = Field(default=None)
prompt_context: Optional[str] = None
description: str = Field(description="Description of the actual task.")
expected_output: str = Field(
@@ -110,6 +109,7 @@ class Task(BaseModel):
_original_description: str | None = None
_original_expected_output: str | None = None
_thread: threading.Thread | None = None
_execution_time: float | None = None
def __init__(__pydantic_self__, **data):
config = data.pop("config", {})
@@ -123,9 +123,15 @@ class Task(BaseModel):
"may_not_set_field", "This field is not to be set by the user.", {}
)
def _set_start_execution_time(self) -> float:
return datetime.datetime.now().timestamp()
def _set_end_execution_time(self, start_time: float) -> None:
self._execution_time = datetime.datetime.now().timestamp() - start_time
@field_validator("output_file")
@classmethod
def output_file_validattion(cls, value: str) -> str:
def output_file_validation(cls, value: str) -> str:
"""Validate the output file path by removing the / from the beginning of the path."""
if value.startswith("/"):
return value[1:]
@@ -173,6 +179,14 @@ class Task(BaseModel):
"""Execute the task synchronously."""
return self._execute_core(agent, context, tools)
@property
def key(self) -> str:
description = self._original_description or self.description
expected_output = self._original_expected_output or self.expected_output
source = [description, expected_output]
return md5("|".join(source).encode()).hexdigest()
def execute_async(
self,
agent: BaseAgent | None = None,
@@ -205,11 +219,13 @@ class Task(BaseModel):
) -> TaskOutput:
"""Run the core execution logic of the task."""
agent = agent or self.agent
self.agent = agent
if not agent:
raise Exception(
f"The task '{self.description}' has no agent assigned, therefore it can't be executed directly and should be executed in a Crew using a specific process that support that, like hierarchical."
)
start_time = self._set_start_execution_time()
self._execution_span = self._telemetry.task_started(crew=agent.crew, task=self)
self.prompt_context = context
@@ -233,18 +249,21 @@ class Task(BaseModel):
)
self.output = task_output
self._set_end_execution_time(start_time)
if self.callback:
self.callback(self.output)
if self._execution_span:
self._telemetry.task_ended(self._execution_span, self)
self._telemetry.task_ended(self._execution_span, self, agent.crew)
self._execution_span = None
if self.output_file:
content = (
json_output
if json_output
else pydantic_output.model_dump_json() if pydantic_output else result
else pydantic_output.model_dump_json()
if pydantic_output
else result
)
self._save_file(content)
@@ -314,13 +333,6 @@ class Task(BaseModel):
return copied_task
def _create_converter(self, *args, **kwargs) -> Converter:
"""Create a converter instance."""
converter = self.agent.get_output_converter(*args, **kwargs)
if self.converter_cls:
converter = self.converter_cls(*args, **kwargs)
return converter
def _export_output(
self, result: str
) -> Tuple[Optional[BaseModel], Optional[Dict[str, Any]]]:
@@ -328,75 +340,26 @@ class Task(BaseModel):
json_output: Optional[Dict[str, Any]] = None
if self.output_pydantic or self.output_json:
model_output = self._convert_to_model(result)
pydantic_output = (
model_output if isinstance(model_output, BaseModel) else None
model_output = convert_to_model(
result,
self.output_pydantic,
self.output_json,
self.agent,
self.converter_cls,
)
if isinstance(model_output, str):
if isinstance(model_output, BaseModel):
pydantic_output = model_output
elif isinstance(model_output, dict):
json_output = model_output
elif isinstance(model_output, str):
try:
json_output = json.loads(model_output)
except json.JSONDecodeError:
json_output = None
else:
json_output = model_output if isinstance(model_output, dict) else None
return pydantic_output, json_output
def _convert_to_model(self, result: str) -> Union[dict, BaseModel, str]:
model = self.output_pydantic or self.output_json
if model is None:
return result
try:
return self._validate_model(result, model)
except Exception:
return self._handle_partial_json(result, model)
def _validate_model(
self, result: str, model: Type[BaseModel]
) -> Union[dict, BaseModel]:
exported_result = model.model_validate_json(result)
if self.output_json:
return exported_result.model_dump()
return exported_result
def _handle_partial_json(
self, result: str, model: Type[BaseModel]
) -> Union[dict, BaseModel, str]:
match = re.search(r"({.*})", result, re.DOTALL)
if match:
try:
exported_result = model.model_validate_json(match.group(0))
if self.output_json:
return exported_result.model_dump()
return exported_result
except Exception:
pass
return self._convert_with_instructions(result, model)
def _convert_with_instructions(
self, result: str, model: Type[BaseModel]
) -> Union[dict, BaseModel, str]:
llm = self.agent.function_calling_llm or self.agent.llm
instructions = self._get_conversion_instructions(model, llm)
converter = self._create_converter(
llm=llm, text=result, model=model, instructions=instructions
)
exported_result = (
converter.to_pydantic() if self.output_pydantic else converter.to_json()
)
if isinstance(exported_result, ConverterError):
Printer().print(
content=f"{exported_result.message} Using raw output instead.",
color="red",
)
return result
return exported_result
def _get_output_format(self) -> OutputFormat:
if self.output_json:
return OutputFormat.JSON
@@ -404,34 +367,22 @@ class Task(BaseModel):
return OutputFormat.PYDANTIC
return OutputFormat.RAW
def _get_conversion_instructions(self, model: Type[BaseModel], llm: Any) -> str:
instructions = "I'm gonna convert this raw text into valid JSON."
if not self._is_gpt(llm):
model_schema = PydanticSchemaParser(model=model).get_schema()
instructions = f"{instructions}\n\nThe json should have the following structure, with the following keys:\n{model_schema}"
return instructions
def _save_output(self, content: str) -> None:
if not self.output_file:
raise Exception("Output file path is not set.")
directory = os.path.dirname(self.output_file)
if directory and not os.path.exists(directory):
os.makedirs(directory)
with open(self.output_file, "w", encoding="utf-8") as file:
file.write(content)
def _is_gpt(self, llm) -> bool:
return isinstance(llm, ChatOpenAI) and llm.openai_api_base is None
def _save_file(self, result: Any) -> None:
if self.output_file is None:
raise ValueError("output_file is not set.")
directory = os.path.dirname(self.output_file) # type: ignore # Value of type variable "AnyOrLiteralStr" of "dirname" cannot be "str | None"
if directory and not os.path.exists(directory):
os.makedirs(directory)
with open(self.output_file, "w", encoding="utf-8") as file: # type: ignore # Argument 1 to "open" has incompatible type "str | None"; expected "int | str | bytes | PathLike[str] | PathLike[bytes]"
file.write(result)
with open(self.output_file, "w", encoding="utf-8") as file:
if isinstance(result, dict):
import json
json.dump(result, file, ensure_ascii=False, indent=2)
else:
file.write(str(result))
return None
def __repr__(self):

View File

@@ -0,0 +1,47 @@
from typing import Any, Callable
from pydantic import Field
from crewai.task import Task
from crewai.tasks.output_format import OutputFormat
from crewai.tasks.task_output import TaskOutput
class ConditionalTask(Task):
"""
A task that can be conditionally executed based on the output of another task.
Note: This cannot be the only task you have in your crew and cannot be the first since its needs context from the previous task.
"""
condition: Callable[[TaskOutput], bool] = Field(
default=None,
description="Maximum number of retries for an agent to execute a task when an error occurs.",
)
def __init__(
self,
condition: Callable[[Any], bool],
**kwargs,
):
super().__init__(**kwargs)
self.condition = condition
def should_execute(self, context: TaskOutput) -> bool:
"""
Determines whether the conditional task should be executed based on the provided context.
Args:
context (Any): The context or output from the previous task that will be evaluated by the condition.
Returns:
bool: True if the task should be executed, False otherwise.
"""
return self.condition(context)
def get_skipped_task_output(self):
return TaskOutput(
description=self.description,
raw="",
agent=self.agent.role if self.agent else "",
output_format=OutputFormat.RAW,
)

View File

@@ -11,9 +11,7 @@ class TaskOutput(BaseModel):
description: str = Field(description="Description of the task")
summary: Optional[str] = Field(description="Summary of the task", default=None)
raw: str = Field(
description="Raw output of the task", default=""
) # TODO: @joao: breaking change, by renaming raw_output to raw, but now consistent with CrewOutput
raw: str = Field(description="Raw output of the task", default="")
pydantic: Optional[BaseModel] = Field(
description="Pydantic output of task", default=None
)
@@ -32,22 +30,6 @@ class TaskOutput(BaseModel):
self.summary = f"{excerpt}..."
return self
# TODO: Joao - Adding this safety check breakes when people want to see
# The full output of a TaskOutput or CrewOutput.
# @property
# def pydantic(self) -> Optional[BaseModel]:
# # Check if the final task output included a pydantic model
# if self.output_format != OutputFormat.PYDANTIC:
# raise ValueError(
# """
# Invalid output format requested.
# If you would like to access the pydantic model,
# please make sure to set the output_pydantic property for the task.
# """
# )
# return self._pydantic
@property
def json(self) -> Optional[str]:
if self.output_format != OutputFormat.JSON:
@@ -66,7 +48,7 @@ class TaskOutput(BaseModel):
output_dict = {}
if self.json_dict:
output_dict.update(self.json_dict)
if self.pydantic:
elif self.pydantic:
output_dict.update(self.pydantic.model_dump())
return output_dict

View File

@@ -40,7 +40,7 @@ class Telemetry:
- Roles of agents in a crew
- Tools names available
Users can opt-in to sharing more complete data suing the `share_crew`
Users can opt-in to sharing more complete data using the `share_crew`
attribute in the Crew class.
"""
@@ -80,7 +80,7 @@ class Telemetry:
self.ready = False
self.trace_set = False
def crew_creation(self, crew):
def crew_creation(self, crew: Crew, inputs: dict[str, Any] | None):
"""Records the creation of a crew."""
if self.ready:
try:
@@ -92,6 +92,7 @@ class Telemetry:
pkg_resources.get_distribution("crewai").version,
)
self._add_attribute(span, "python_version", platform.python_version())
self._add_attribute(span, "crew_key", crew.key)
self._add_attribute(span, "crew_id", str(crew.id))
self._add_attribute(span, "crew_process", crew.process)
self._add_attribute(span, "crew_memory", crew.memory)
@@ -103,6 +104,7 @@ class Telemetry:
json.dumps(
[
{
"key": agent.key,
"id": str(agent.id),
"role": agent.role,
"goal": agent.goal,
@@ -114,7 +116,7 @@ class Telemetry:
"llm": json.dumps(self._safe_llm_attributes(agent.llm)),
"delegation_enabled?": agent.allow_delegation,
"tools_names": [
tool.name.casefold() for tool in agent.tools
tool.name.casefold() for tool in agent.tools or []
],
}
for agent in crew.agents
@@ -127,19 +129,21 @@ class Telemetry:
json.dumps(
[
{
"key": task.key,
"id": str(task.id),
"description": task.description,
"expected_output": task.expected_output,
"async_execution?": task.async_execution,
"human_input?": task.human_input,
"agent_role": task.agent.role if task.agent else "None",
"agent_key": task.agent.key if task.agent else None,
"context": (
[task.description for task in task.context]
if task.context
else None
),
"tools_names": [
tool.name.casefold() for tool in task.tools
tool.name.casefold() for tool in task.tools or []
],
}
for task in crew.tasks
@@ -151,6 +155,12 @@ class Telemetry:
self._add_attribute(span, "platform_system", platform.system())
self._add_attribute(span, "platform_version", platform.version())
self._add_attribute(span, "cpus", os.cpu_count())
if crew.share_crew:
self._add_attribute(
span, "crew_inputs", json.dumps(inputs) if inputs else None
)
span.set_status(Status(StatusCode.OK))
span.end()
except Exception:
@@ -161,10 +171,12 @@ class Telemetry:
if self.ready:
try:
tracer = trace.get_tracer("crewai.telemetry")
span = tracer.start_span("Task Execution")
created_span = tracer.start_span("Task Created")
self._add_attribute(created_span, "crew_key", crew.key)
self._add_attribute(created_span, "crew_id", str(crew.id))
self._add_attribute(created_span, "task_key", task.key)
self._add_attribute(created_span, "task_id", str(task.id))
if crew.share_crew:
@@ -178,6 +190,11 @@ class Telemetry:
created_span.set_status(Status(StatusCode.OK))
created_span.end()
span = tracer.start_span("Task Execution")
self._add_attribute(span, "crew_key", crew.key)
self._add_attribute(span, "crew_id", str(crew.id))
self._add_attribute(span, "task_key", task.key)
self._add_attribute(span, "task_id", str(task.id))
if crew.share_crew:
@@ -192,13 +209,16 @@ class Telemetry:
return None
def task_ended(self, span: Span, task: Task):
def task_ended(self, span: Span, task: Task, crew: Crew):
"""Records task execution in a crew."""
if self.ready:
try:
self._add_attribute(
span, "output", task.output.raw_output if task.output else ""
)
if crew.share_crew:
self._add_attribute(
span,
"task_output",
task.output.raw if task.output else "",
)
span.set_status(Status(StatusCode.OK))
span.end()
@@ -273,6 +293,8 @@ class Telemetry:
"""Records the complete execution of a crew.
This is only collected if the user has opted-in to share the crew.
"""
self.crew_creation(crew, inputs)
if (self.ready) and (crew.share_crew):
try:
tracer = trace.get_tracer("crewai.telemetry")
@@ -282,14 +304,18 @@ class Telemetry:
"crewai_version",
pkg_resources.get_distribution("crewai").version,
)
self._add_attribute(span, "crew_key", crew.key)
self._add_attribute(span, "crew_id", str(crew.id))
self._add_attribute(span, "inputs", json.dumps(inputs))
self._add_attribute(
span, "crew_inputs", json.dumps(inputs) if inputs else None
)
self._add_attribute(
span,
"crew_agents",
json.dumps(
[
{
"key": agent.key,
"id": str(agent.id),
"role": agent.role,
"goal": agent.goal,
@@ -320,6 +346,7 @@ class Telemetry:
"async_execution?": task.async_execution,
"human_input?": task.human_input,
"agent_role": task.agent.role if task.agent else "None",
"agent_key": task.agent.key if task.agent else None,
"context": (
[task.description for task in task.context]
if task.context

View File

@@ -7,7 +7,7 @@ class AgentTools(BaseAgentTools):
"""Default tools around agent delegation"""
def tools(self):
coworkers = f"[{', '.join([f'{agent.role}' for agent in self.agents])}]"
coworkers = ", ".join([f"{agent.role}" for agent in self.agents])
tools = [
StructuredTool.from_function(
func=self.delegate_work,

View File

@@ -86,7 +86,8 @@ class ToolUsage:
) -> str:
if isinstance(calling, ToolUsageErrorException):
error = calling.message
self._printer.print(content=f"\n\n{error}\n", color="red")
if self.agent.verbose:
self._printer.print(content=f"\n\n{error}\n", color="red")
self.task.increment_tools_errors()
return error
@@ -96,7 +97,8 @@ class ToolUsage:
except Exception as e:
error = getattr(e, "message", str(e))
self.task.increment_tools_errors()
self._printer.print(content=f"\n\n{error}\n", color="red")
if self.agent.verbose:
self._printer.print(content=f"\n\n{error}\n", color="red")
return error
return f"{self._use(tool_string=tool_string, tool=tool, calling=calling)}" # type: ignore # BUG?: "_use" of "ToolUsage" does not return a value (it only ever returns None)
@@ -112,7 +114,8 @@ class ToolUsage:
result = self._i18n.errors("task_repeated_usage").format(
tool_names=self.tools_names
)
self._printer.print(content=f"\n\n{result}\n", color="purple")
if self.agent.verbose:
self._printer.print(content=f"\n\n{result}\n", color="purple")
self._telemetry.tool_repeated_usage(
llm=self.function_calling_llm,
tool_name=tool.name,
@@ -151,16 +154,12 @@ class ToolUsage:
for k, v in calling.arguments.items()
if k in acceptable_args
}
result = tool._run(**arguments)
result = tool.invoke(input=arguments)
except Exception:
if tool.args_schema:
arguments = calling.arguments
result = tool._run(**arguments)
else:
arguments = calling.arguments.values() # type: ignore # Incompatible types in assignment (expression has type "dict_values[str, Any]", variable has type "dict[str, Any]")
result = tool._run(*arguments)
arguments = calling.arguments
result = tool.invoke(input=arguments)
else:
result = tool._run()
result = tool.invoke(input={})
except Exception as e:
self._run_attempts += 1
if self._run_attempts > self._max_parsing_attempts:
@@ -172,7 +171,10 @@ class ToolUsage:
f'\n{error_message}.\nMoving on then. {self._i18n.slice("format").format(tool_names=self.tools_names)}'
).message
self.task.increment_tools_errors()
self._printer.print(content=f"\n\n{error_message}\n", color="red")
if self.agent.verbose:
self._printer.print(
content=f"\n\n{error_message}\n", color="red"
)
return error # type: ignore # No return value expected
self.task.increment_tools_errors()
@@ -196,7 +198,8 @@ class ToolUsage:
calling=calling, output=result, should_cache=should_cache
)
self._printer.print(content=f"\n\n{result}\n", color="purple")
if self.agent.verbose:
self._printer.print(content=f"\n\n{result}\n", color="purple")
if agentops:
agentops.record(tool_event)
self._telemetry.tool_usage(
@@ -350,7 +353,8 @@ class ToolUsage:
if self._run_attempts > self._max_parsing_attempts:
self._telemetry.tool_usage_error(llm=self.function_calling_llm)
self.task.increment_tools_errors()
self._printer.print(content=f"\n\n{e}\n", color="red")
if self.agent.verbose:
self._printer.print(content=f"\n\n{e}\n", color="red")
return ToolUsageErrorException( # type: ignore # Incompatible return value type (got "ToolUsageErrorException", expected "ToolCalling | InstructorToolCalling")
f'{self._i18n.errors("tool_usage_error").format(error=e)}\nMoving on then. {self._i18n.slice("format").format(tool_names=self.tools_names)}'
)

View File

View File

@@ -0,0 +1,36 @@
from pydantic import BaseModel, Field
class UsageMetrics(BaseModel):
"""
Model to track usage metrics for the crew's execution.
Attributes:
total_tokens: Total number of tokens used.
prompt_tokens: Number of tokens used in prompts.
completion_tokens: Number of tokens used in completions.
successful_requests: Number of successful requests made.
"""
total_tokens: int = Field(default=0, description="Total number of tokens used.")
prompt_tokens: int = Field(
default=0, description="Number of tokens used in prompts."
)
completion_tokens: int = Field(
default=0, description="Number of tokens used in completions."
)
successful_requests: int = Field(
default=0, description="Number of successful requests made."
)
def add_usage_metrics(self, usage_metrics: "UsageMetrics"):
"""
Add the usage metrics from another UsageMetrics object.
Args:
usage_metrics (UsageMetrics): The usage metrics to add.
"""
self.total_tokens += usage_metrics.total_tokens
self.prompt_tokens += usage_metrics.prompt_tokens
self.completion_tokens += usage_metrics.completion_tokens
self.successful_requests += usage_metrics.successful_requests

View File

@@ -1,11 +1,14 @@
import json
import re
from typing import Any, Optional, Type, Union
from langchain.schema import HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
from pydantic import model_validator
from crewai.agents.agent_builder.utilities.base_output_converter_base import (
OutputConverter,
)
from pydantic import BaseModel, ValidationError
from crewai.agents.agent_builder.utilities.base_output_converter import OutputConverter
from crewai.utilities.printer import Printer
from crewai.utilities.pydantic_schema_parser import PydanticSchemaParser
class ConverterError(Exception):
@@ -19,15 +22,10 @@ class ConverterError(Exception):
class Converter(OutputConverter):
"""Class that converts text into either pydantic or json."""
@model_validator(mode="after")
def check_llm_provider(self):
if not self._is_gpt(self.llm):
self._is_gpt = False
def to_pydantic(self, current_attempt=1):
"""Convert text to pydantic."""
try:
if self._is_gpt:
if self.is_gpt:
return self._create_instructor().to_pydantic()
else:
return self._create_chain().invoke({})
@@ -41,14 +39,14 @@ class Converter(OutputConverter):
def to_json(self, current_attempt=1):
"""Convert text to json."""
try:
if self._is_gpt:
if self.is_gpt:
return self._create_instructor().to_json()
else:
return json.dumps(self._create_chain().invoke({}).model_dump())
except Exception:
except Exception as e:
if current_attempt < self.max_attempts:
return self.to_json(current_attempt + 1)
return ConverterError("Failed to convert text into JSON.")
return ConverterError(f"Failed to convert text into JSON, error: {e}.")
def _create_instructor(self):
"""Create an instructor."""
@@ -75,5 +73,157 @@ class Converter(OutputConverter):
)
return new_prompt | self.llm | parser
def _is_gpt(self, llm) -> bool: # type: ignore # BUG? Name "_is_gpt" defined on line 20 hides name from outer scope
return isinstance(llm, ChatOpenAI) and llm.openai_api_base is None
@property
def is_gpt(self) -> bool:
"""Return if llm provided is of gpt from openai."""
return isinstance(self.llm, ChatOpenAI) and self.llm.openai_api_base is None
def convert_to_model(
result: str,
output_pydantic: Optional[Type[BaseModel]],
output_json: Optional[Type[BaseModel]],
agent: Any,
converter_cls: Optional[Type[Converter]] = None,
) -> Union[dict, BaseModel, str]:
model = output_pydantic or output_json
if model is None:
return result
try:
escaped_result = json.dumps(json.loads(result, strict=False))
return validate_model(escaped_result, model, bool(output_json))
except json.JSONDecodeError as e:
Printer().print(
content=f"Error parsing JSON: {e}. Attempting to handle partial JSON.",
color="yellow",
)
return handle_partial_json(
result, model, bool(output_json), agent, converter_cls
)
except ValidationError as e:
Printer().print(
content=f"Pydantic validation error: {e}. Attempting to handle partial JSON.",
color="yellow",
)
return handle_partial_json(
result, model, bool(output_json), agent, converter_cls
)
except Exception as e:
Printer().print(
content=f"Unexpected error during model conversion: {type(e).__name__}: {e}. Returning original result.",
color="red",
)
return result
def validate_model(
result: str, model: Type[BaseModel], is_json_output: bool
) -> Union[dict, BaseModel]:
exported_result = model.model_validate_json(result)
if is_json_output:
return exported_result.model_dump()
return exported_result
def handle_partial_json(
result: str,
model: Type[BaseModel],
is_json_output: bool,
agent: Any,
converter_cls: Optional[Type[Converter]] = None,
) -> Union[dict, BaseModel, str]:
match = re.search(r"({.*})", result, re.DOTALL)
if match:
try:
exported_result = model.model_validate_json(match.group(0))
if is_json_output:
return exported_result.model_dump()
return exported_result
except json.JSONDecodeError as e:
Printer().print(
content=f"Error parsing JSON: {e}. The extracted JSON-like string is not valid JSON. Attempting alternative conversion method.",
color="yellow",
)
except ValidationError as e:
Printer().print(
content=f"Pydantic validation error: {e}. The JSON structure doesn't match the expected model. Attempting alternative conversion method.",
color="yellow",
)
except Exception as e:
Printer().print(
content=f"Unexpected error during partial JSON handling: {type(e).__name__}: {e}. Attempting alternative conversion method.",
color="red",
)
return convert_with_instructions(
result, model, is_json_output, agent, converter_cls
)
def convert_with_instructions(
result: str,
model: Type[BaseModel],
is_json_output: bool,
agent: Any,
converter_cls: Optional[Type[Converter]] = None,
) -> Union[dict, BaseModel, str]:
llm = agent.function_calling_llm or agent.llm
instructions = get_conversion_instructions(model, llm)
converter = create_converter(
agent=agent,
converter_cls=converter_cls,
llm=llm,
text=result,
model=model,
instructions=instructions,
)
exported_result = (
converter.to_pydantic() if not is_json_output else converter.to_json()
)
if isinstance(exported_result, ConverterError):
Printer().print(
content=f"{exported_result.message} Using raw output instead.",
color="red",
)
return result
return exported_result
def get_conversion_instructions(model: Type[BaseModel], llm: Any) -> str:
instructions = "I'm gonna convert this raw text into valid JSON."
if not is_gpt(llm):
model_schema = PydanticSchemaParser(model=model).get_schema()
instructions = f"{instructions}\n\nThe json should have the following structure, with the following keys:\n{model_schema}"
return instructions
def is_gpt(llm: Any) -> bool:
from langchain_openai import ChatOpenAI
return isinstance(llm, ChatOpenAI) and llm.openai_api_base is None
def create_converter(
agent: Optional[Any] = None,
converter_cls: Optional[Type[Converter]] = None,
*args,
**kwargs,
) -> Converter:
if agent and not converter_cls:
if hasattr(agent, "get_output_converter"):
converter = agent.get_output_converter(*args, **kwargs)
else:
raise AttributeError("Agent does not have a 'get_output_converter' method")
elif converter_cls:
converter = converter_cls(*args, **kwargs)
else:
raise ValueError("Either agent or converter_cls must be provided")
if not converter:
raise Exception("No output converter found or set.")
return converter

View File

@@ -0,0 +1,31 @@
from datetime import datetime
import json
from uuid import UUID
from pydantic import BaseModel
class CrewJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, BaseModel):
return self._handle_pydantic_model(obj)
elif isinstance(obj, UUID):
return str(obj)
elif isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
def _handle_pydantic_model(self, obj):
try:
data = obj.model_dump()
# Remove circular references
for key, value in data.items():
if isinstance(value, BaseModel):
data[key] = str(
value
) # Convert nested models to string representation
return data
except RecursionError:
return str(
obj
) # Fall back to string representation if circular reference is detected

View File

@@ -1,5 +1,5 @@
import json
from typing import Any, List, Type, Union
from typing import Any, List, Type
import regex
from langchain.output_parsers import PydanticOutputParser
@@ -7,19 +7,24 @@ from langchain_core.exceptions import OutputParserException
from langchain_core.outputs import Generation
from langchain_core.pydantic_v1 import ValidationError
from pydantic import BaseModel
from pydantic.v1 import BaseModel as V1BaseModel
class CrewPydanticOutputParser(PydanticOutputParser):
"""Parses the text into pydantic models"""
pydantic_object: Union[Type[BaseModel], Type[V1BaseModel]]
pydantic_object: Type[BaseModel]
def parse_result(self, result: List[Generation], *, partial: bool = False) -> Any:
def parse_result(self, result: List[Generation]) -> Any:
result[0].text = self._transform_in_valid_json(result[0].text)
json_object = super().parse_result(result)
# Treating edge case of function calling llm returning the name instead of tool_name
json_object = json.loads(result[0].text)
if "tool_name" not in json_object:
json_object["tool_name"] = json_object.get("name", "")
result[0].text = json.dumps(json_object)
try:
return self.pydantic_object.parse_obj(json_object)
return self.pydantic_object.model_validate(json_object)
except ValidationError as e:
name = self.pydantic_object.__name__
msg = f"Failed to parse {name} from completion {json_object}. Got: {e}"

View File

@@ -0,0 +1,163 @@
from collections import defaultdict
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from rich.console import Console
from rich.table import Table
from crewai.agent import Agent
from crewai.task import Task
from crewai.tasks.task_output import TaskOutput
class TaskEvaluationPydanticOutput(BaseModel):
quality: float = Field(
description="A score from 1 to 10 evaluating on completion, quality, and overall performance from the task_description and task_expected_output to the actual Task Output."
)
class CrewEvaluator:
"""
A class to evaluate the performance of the agents in the crew based on the tasks they have performed.
Attributes:
crew (Crew): The crew of agents to evaluate.
openai_model_name (str): The model to use for evaluating the performance of the agents (for now ONLY OpenAI accepted).
tasks_scores (defaultdict): A dictionary to store the scores of the agents for each task.
iteration (int): The current iteration of the evaluation.
"""
tasks_scores: defaultdict = defaultdict(list)
run_execution_times: defaultdict = defaultdict(list)
iteration: int = 0
def __init__(self, crew, openai_model_name: str):
self.crew = crew
self.openai_model_name = openai_model_name
self._setup_for_evaluating()
def _setup_for_evaluating(self) -> None:
"""Sets up the crew for evaluating."""
for task in self.crew.tasks:
task.callback = self.evaluate
def _evaluator_agent(self):
return Agent(
role="Task Execution Evaluator",
goal=(
"Your goal is to evaluate the performance of the agents in the crew based on the tasks they have performed using score from 1 to 10 evaluating on completion, quality, and overall performance."
),
backstory="Evaluator agent for crew evaluation with precise capabilities to evaluate the performance of the agents in the crew based on the tasks they have performed",
verbose=False,
llm=ChatOpenAI(model=self.openai_model_name),
)
def _evaluation_task(
self, evaluator_agent: Agent, task_to_evaluate: Task, task_output: str
) -> Task:
return Task(
description=(
"Based on the task description and the expected output, compare and evaluate the performance of the agents in the crew based on the Task Output they have performed using score from 1 to 10 evaluating on completion, quality, and overall performance."
f"task_description: {task_to_evaluate.description} "
f"task_expected_output: {task_to_evaluate.expected_output} "
f"agent: {task_to_evaluate.agent.role if task_to_evaluate.agent else None} "
f"agent_goal: {task_to_evaluate.agent.goal if task_to_evaluate.agent else None} "
f"Task Output: {task_output}"
),
expected_output="Evaluation Score from 1 to 10 based on the performance of the agents on the tasks",
agent=evaluator_agent,
output_pydantic=TaskEvaluationPydanticOutput,
)
def set_iteration(self, iteration: int) -> None:
self.iteration = iteration
def print_crew_evaluation_result(self) -> None:
"""
Prints the evaluation result of the crew in a table.
A Crew with 2 tasks using the command crewai test -n 2
will output the following table:
Task Scores
(1-10 Higher is better)
┏━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━┓
┃ Tasks/Crew ┃ Run 1 ┃ Run 2 ┃ Avg. Total ┃
┡━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━┩
│ Task 1 │ 10.0 │ 9.0 │ 9.5 │
│ Task 2 │ 9.0 │ 9.0 │ 9.0 │
│ Crew │ 9.5 │ 9.0 │ 9.2 │
└────────────┴───────┴───────┴────────────┘
"""
task_averages = [
sum(scores) / len(scores) for scores in zip(*self.tasks_scores.values())
]
crew_average = sum(task_averages) / len(task_averages)
# Create a table
table = Table(title="Tasks Scores \n (1-10 Higher is better)")
# Add columns for the table
table.add_column("Tasks/Crew")
for run in range(1, len(self.tasks_scores) + 1):
table.add_column(f"Run {run}")
table.add_column("Avg. Total")
# Add rows for each task
for task_index in range(len(task_averages)):
task_scores = [
self.tasks_scores[run][task_index]
for run in range(1, len(self.tasks_scores) + 1)
]
avg_score = task_averages[task_index]
table.add_row(
f"Task {task_index + 1}", *map(str, task_scores), f"{avg_score:.1f}"
)
# Add a row for the crew average
crew_scores = [
sum(self.tasks_scores[run]) / len(self.tasks_scores[run])
for run in range(1, len(self.tasks_scores) + 1)
]
table.add_row("Crew", *map(str, crew_scores), f"{crew_average:.1f}")
run_exec_times = [
int(sum(tasks_exec_times))
for _, tasks_exec_times in self.run_execution_times.items()
]
execution_time_avg = int(sum(run_exec_times) / len(run_exec_times))
table.add_row(
"Execution Time (s)",
*map(str, run_exec_times),
f"{execution_time_avg}",
)
# Display the table in the terminal
console = Console()
console.print(table)
def evaluate(self, task_output: TaskOutput):
"""Evaluates the performance of the agents in the crew based on the tasks they have performed."""
current_task = None
for task in self.crew.tasks:
if task.description == task_output.description:
current_task = task
break
if not current_task or not task_output:
raise ValueError(
"Task to evaluate and task output are required for evaluation"
)
evaluator_agent = self._evaluator_agent()
evaluation_task = self._evaluation_task(
evaluator_agent, current_task, task_output.raw
)
evaluation_result = evaluation_task.execute_sync()
if isinstance(evaluation_result.pydantic, TaskEvaluationPydanticOutput):
self.tasks_scores[self.iteration].append(evaluation_result.pydantic.quality)
self.run_execution_times[self.iteration].append(
current_task._execution_time
)
else:
raise ValueError("Evaluation result is not in the expected format")

View File

@@ -54,23 +54,23 @@ class TaskEvaluator:
def __init__(self, original_agent):
self.llm = original_agent.llm
def evaluate(self, task, ouput) -> TaskEvaluation:
def evaluate(self, task, output) -> TaskEvaluation:
evaluation_query = (
f"Assess the quality of the task completed based on the description, expected output, and actual results.\n\n"
f"Task Description:\n{task.description}\n\n"
f"Expected Output:\n{task.expected_output}\n\n"
f"Actual Output:\n{ouput}\n\n"
f"Actual Output:\n{output}\n\n"
"Please provide:\n"
"- Bullet points suggestions to improve future similar tasks\n"
"- A score from 0 to 10 evaluating on completion, quality, and overall performance"
"- Entities extracted from the task output, if any, their type, description, and relationships"
)
instructions = "I'm gonna convert this raw text into valid JSON."
instructions = "Convert all responses into valid JSON output."
if not self._is_gpt(self.llm):
model_schema = PydanticSchemaParser(model=TaskEvaluation).get_schema()
instructions = f"{instructions}\n\nThe json should have the following structure, with the following keys:\n{model_schema}"
instructions = f"{instructions}\n\nReturn only valid JSON with the following schema:\n```json\n{model_schema}\n```"
converter = Converter(
llm=self.llm,

View File

@@ -1,5 +1,7 @@
import os
import pickle
from datetime import datetime

View File

@@ -1,17 +1,28 @@
import re
class YamlParser:
@staticmethod
def parse(file):
"""
Parses a YAML file, modifies specific patterns, and checks for unsupported 'context' usage.
Args:
file (file object): The YAML file to parse.
Returns:
str: The modified content of the YAML file.
Raises:
ValueError: If 'context:' is used incorrectly.
"""
content = file.read()
# Replace single { and } with doubled ones, while leaving already doubled ones intact and the other special characters {# and {%
modified_content = re.sub(r"(?<!\{){(?!\{)(?!\#)(?!\%)", "{{", content)
modified_content = re.sub(
r"(?<!\})(?<!\%)(?<!\#)\}(?!})", "}}", modified_content
)
modified_content = re.sub(r"(?<!\})(?<!\%)(?<!\#)\}(?!})", "}}", modified_content)
# Check for 'context:' not followed by '[' and raise an error
if re.search(r"context:(?!\s*\[)", modified_content):
raise ValueError(
"Context is currently only supported in code when creating a task. Please use the 'context' key in the task configuration."
"Context is currently only supported in code when creating a task. "
"Please use the 'context' key in the task configuration."
)
return modified_content

View File

@@ -0,0 +1,76 @@
from typing import Any, List, Optional
from langchain_openai import ChatOpenAI
from pydantic import BaseModel
from crewai.agent import Agent
from crewai.task import Task
class PlannerTaskPydanticOutput(BaseModel):
list_of_plans_per_task: List[str]
class CrewPlanner:
def __init__(self, tasks: List[Task], planning_agent_llm: Optional[Any] = None):
self.tasks = tasks
if planning_agent_llm is None:
self.planning_agent_llm = ChatOpenAI(model="gpt-4o-mini")
else:
self.planning_agent_llm = planning_agent_llm
def _handle_crew_planning(self) -> PlannerTaskPydanticOutput:
"""Handles the Crew planning by creating detailed step-by-step plans for each task."""
planning_agent = self._create_planning_agent()
tasks_summary = self._create_tasks_summary()
planner_task = self._create_planner_task(planning_agent, tasks_summary)
result = planner_task.execute_sync()
if isinstance(result.pydantic, PlannerTaskPydanticOutput):
return result.pydantic
raise ValueError("Failed to get the Planning output")
def _create_planning_agent(self) -> Agent:
"""Creates the planning agent for the crew planning."""
return Agent(
role="Task Execution Planner",
goal=(
"Your goal is to create an extremely detailed, step-by-step plan based on the tasks and tools "
"available to each agent so that they can perform the tasks in an exemplary manner"
),
backstory="Planner agent for crew planning",
llm=self.planning_agent_llm,
)
def _create_planner_task(self, planning_agent: Agent, tasks_summary: str) -> Task:
"""Creates the planner task using the given agent and tasks summary."""
return Task(
description=(
f"Based on these tasks summary: {tasks_summary} \n Create the most descriptive plan based on the tasks "
"descriptions, tools available, and agents' goals for them to execute their goals with perfection."
),
expected_output="Step by step plan on how the agents can execute their tasks using the available tools with mastery",
agent=planning_agent,
output_pydantic=PlannerTaskPydanticOutput,
)
def _create_tasks_summary(self) -> str:
"""Creates a summary of all tasks."""
tasks_summary = []
for idx, task in enumerate(self.tasks):
tasks_summary.append(
f"""
Task Number {idx + 1} - {task.description}
"task_description": {task.description}
"task_expected_output": {task.expected_output}
"agent": {task.agent.role if task.agent else "None"}
"agent_goal": {task.agent.goal if task.agent else "None"}
"task_tools": {task.tools}
"agent_tools": {task.agent.tools if task.agent else "None"}
"""
)
return " ".join(tasks_summary)

View File

@@ -8,6 +8,10 @@ class Printer:
self._print_bold_green(content)
elif color == "bold_purple":
self._print_bold_purple(content)
elif color == "bold_blue":
self._print_bold_blue(content)
elif color == "yellow":
self._print_yellow(content)
else:
print(content)
@@ -22,3 +26,9 @@ class Printer:
def _print_red(self, content):
print("\033[91m {}\033[00m".format(content))
def _print_bold_blue(self, content):
print("\033[1m\033[94m {}\033[00m".format(content))
def _print_yellow(self, content):
print("\033[93m {}\033[00m".format(content))

View File

@@ -16,11 +16,13 @@ class PydanticSchemaParser(BaseModel):
return self._get_model_schema(self.model)
def _get_model_schema(self, model, depth=0) -> str:
lines = []
indent = " " * depth
lines = [f"{indent}{{"]
for field_name, field in model.model_fields.items():
field_type_str = self._get_field_type(field, depth + 1)
lines.append(f"{' ' * 4 * depth}- {field_name}: {field_type_str}")
lines.append(f"{indent} {field_name}: {field_type_str},")
lines[-1] = lines[-1].rstrip(",") # Remove trailing comma from last item
lines.append(f"{indent}}}")
return "\n".join(lines)
def _get_field_type(self, field, depth) -> str:
@@ -35,6 +37,6 @@ class PydanticSchemaParser(BaseModel):
else:
return f"List[{list_item_type.__name__}]"
elif issubclass(field_type, BaseModel):
return f"\n{self._get_model_schema(field_type, depth)}"
return self._get_model_schema(field_type, depth)
else:
return field_type.__name__

View File

@@ -0,0 +1,61 @@
from pydantic import BaseModel, Field
from datetime import datetime
from typing import Dict, Any, Optional, List
from crewai.memory.storage.kickoff_task_outputs_storage import (
KickoffTaskOutputsSQLiteStorage,
)
from crewai.task import Task
class ExecutionLog(BaseModel):
task_id: str
expected_output: Optional[str] = None
output: Dict[str, Any]
timestamp: datetime = Field(default_factory=datetime.now)
task_index: int
inputs: Dict[str, Any] = Field(default_factory=dict)
was_replayed: bool = False
def __getitem__(self, key: str) -> Any:
return getattr(self, key)
class TaskOutputStorageHandler:
def __init__(self) -> None:
self.storage = KickoffTaskOutputsSQLiteStorage()
def update(self, task_index: int, log: Dict[str, Any]):
saved_outputs = self.load()
if saved_outputs is None:
raise ValueError("Logs cannot be None")
if log.get("was_replayed", False):
replayed = {
"task_id": str(log["task"].id),
"expected_output": log["task"].expected_output,
"output": log["output"],
"was_replayed": log["was_replayed"],
"inputs": log["inputs"],
}
self.storage.update(
task_index,
**replayed,
)
else:
self.storage.add(**log)
def add(
self,
task: Task,
output: Dict[str, Any],
task_index: int,
inputs: Dict[str, Any] = {},
was_replayed: bool = False,
):
self.storage.add(task, output, task_index, was_replayed, inputs)
def reset(self):
self.storage.delete_all()
def load(self) -> Optional[List[Dict[str, Any]]]:
return self.storage.load()

View File

@@ -397,7 +397,7 @@ def test_agent_moved_on_after_max_iterations():
)
task = Task(
description="The final answer is 42. But don't give it yet, instead keep using the `get_final_answer` tool over and over until you're told you can give yout final answer.",
description="The final answer is 42. But don't give it yet, instead keep using the `get_final_answer` tool over and over until you're told you can give your final answer.",
expected_output="The final answer",
)
output = agent.execute_task(
@@ -948,7 +948,7 @@ def test_agent_use_trained_data(crew_training_handler):
crew_training_handler().load.return_value = {
agent.role: {
"suggestions": [
"The result of the math operatio must be right.",
"The result of the math operation must be right.",
"Result must be better than 1.",
]
}
@@ -958,8 +958,59 @@ def test_agent_use_trained_data(crew_training_handler):
assert (
result == "What is 1 + 1?You MUST follow these feedbacks: \n "
"The result of the math operatio must be right.\n - Result must be better than 1."
"The result of the math operation must be right.\n - Result must be better than 1."
)
crew_training_handler.assert_has_calls(
[mock.call(), mock.call("trained_agents_data.pkl"), mock.call().load()]
)
def test_agent_max_retry_limit():
agent = Agent(
role="test role",
goal="test goal",
backstory="test backstory",
max_retry_limit=1,
)
task = Task(
agent=agent,
description="Say the word: Hi",
expected_output="The word: Hi",
human_input=True,
)
error_message = "Error happening while sending prompt to model."
with patch.object(
CrewAgentExecutor, "invoke", wraps=agent.agent_executor.invoke
) as invoke_mock:
invoke_mock.side_effect = Exception(error_message)
assert agent._times_executed == 0
assert agent.max_retry_limit == 1
with pytest.raises(Exception) as e:
agent.execute_task(
task=task,
)
assert e.value.args[0] == error_message
assert agent._times_executed == 2
invoke_mock.assert_has_calls(
[
mock.call(
{
"input": "Say the word: Hi\n\nThis is the expect criteria for your final answer: The word: Hi \n you MUST return the actual complete content as the final answer, not a summary.",
"tool_names": "",
"tools": "",
}
),
mock.call(
{
"input": "Say the word: Hi\n\nThis is the expect criteria for your final answer: The word: Hi \n you MUST return the actual complete content as the final answer, not a summary.",
"tool_names": "",
"tools": "",
}
),
]
)

0
tests/agents/__init__.py Normal file
View File

View File

@@ -0,0 +1,36 @@
import hashlib
from typing import Any, List, Optional
from crewai.agents.agent_builder.base_agent import BaseAgent
from pydantic import BaseModel
class TestAgent(BaseAgent):
def execute_task(
self,
task: Any,
context: Optional[str] = None,
tools: Optional[List[Any]] = None,
) -> str:
return ""
def create_agent_executor(self, tools=None) -> None: ...
def _parse_tools(self, tools: List[Any]) -> List[Any]:
return []
def get_delegation_tools(self, agents: List["BaseAgent"]): ...
def get_output_converter(
self, llm: Any, text: str, model: type[BaseModel] | None, instructions: str
): ...
def test_key():
agent = TestAgent(
role="test role",
goal="test goal",
backstory="test backstory",
)
hash = hashlib.md5("test role|test goal|test backstory".encode()).hexdigest()
assert agent.key == hash

View File

@@ -0,0 +1,378 @@
import pytest
from crewai.agents.parser import CrewAgentParser
from langchain_core.agents import AgentAction, AgentFinish
from langchain_core.exceptions import OutputParserException
@pytest.fixture
def parser():
p = CrewAgentParser()
p.agent = MockAgent()
return p
def test_valid_action_parsing_special_characters(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: what's the temperature in SF?"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what's the temperature in SF?"
def test_valid_action_parsing_with_json_tool_input(parser):
text = """
Thought: Let's find the information
Action: query
Action Input: ** {"task": "What are some common challenges or barriers that you have observed or experienced when implementing AI-powered solutions in healthcare settings?", "context": "As we've discussed recent advancements in AI applications in healthcare, it's crucial to acknowledge the potential hurdles. Some possible obstacles include...", "coworker": "Senior Researcher"}
"""
result = parser.parse(text)
assert isinstance(result, AgentAction)
expected_tool_input = '{"task": "What are some common challenges or barriers that you have observed or experienced when implementing AI-powered solutions in healthcare settings?", "context": "As we\'ve discussed recent advancements in AI applications in healthcare, it\'s crucial to acknowledge the potential hurdles. Some possible obstacles include...", "coworker": "Senior Researcher"}'
assert result.tool == "query"
assert result.tool_input == expected_tool_input
def test_valid_action_parsing_with_quotes(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: "temperature in SF"'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "temperature in SF"
def test_valid_action_parsing_with_curly_braces(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: {temperature in SF}"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "{temperature in SF}"
def test_valid_action_parsing_with_angle_brackets(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: <temperature in SF>"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "<temperature in SF>"
def test_valid_action_parsing_with_parentheses(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: (temperature in SF)"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "(temperature in SF)"
def test_valid_action_parsing_with_mixed_brackets(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: [temperature in {SF}]"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "[temperature in {SF}]"
def test_valid_action_parsing_with_nested_quotes(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: \"what's the temperature in 'SF'?\""
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what's the temperature in 'SF'?"
def test_valid_action_parsing_with_incomplete_json(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: {"query": "temperature in SF"'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == '{"query": "temperature in SF"}'
def test_valid_action_parsing_with_special_characters(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: what is the temperature in SF? @$%^&*"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF? @$%^&*"
def test_valid_action_parsing_with_combination(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: "[what is the temperature in SF?]"'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "[what is the temperature in SF?]"
def test_valid_action_parsing_with_mixed_quotes(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: \"what's the temperature in SF?\""
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what's the temperature in SF?"
def test_valid_action_parsing_with_newlines(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: what is\nthe temperature in SF?"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is\nthe temperature in SF?"
def test_valid_action_parsing_with_escaped_characters(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: what is the temperature in SF? \\n"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF? \\n"
def test_valid_action_parsing_with_json_string(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: {"query": "temperature in SF"}'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == '{"query": "temperature in SF"}'
def test_valid_action_parsing_with_unbalanced_quotes(parser):
text = "Thought: Let's find the temperature\nAction: search\nAction Input: \"what is the temperature in SF?"
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF?"
def test_clean_action_no_formatting(parser):
action = "Ask question to senior researcher"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_leading_asterisks(parser):
action = "** Ask question to senior researcher"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_trailing_asterisks(parser):
action = "Ask question to senior researcher **"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_leading_and_trailing_asterisks(parser):
action = "** Ask question to senior researcher **"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_multiple_leading_asterisks(parser):
action = "**** Ask question to senior researcher"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_multiple_trailing_asterisks(parser):
action = "Ask question to senior researcher ****"
cleaned_action = parser._clean_action(action)
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_spaces_and_asterisks(parser):
action = " ** Ask question to senior researcher ** "
cleaned_action = parser._clean_action(action)
print(f"Original action: '{action}'")
print(f"Cleaned action: '{cleaned_action}'")
assert cleaned_action == "Ask question to senior researcher"
def test_clean_action_with_only_asterisks(parser):
action = "****"
cleaned_action = parser._clean_action(action)
assert cleaned_action == ""
def test_clean_action_with_empty_string(parser):
action = ""
cleaned_action = parser._clean_action(action)
assert cleaned_action == ""
def test_valid_final_answer_parsing(parser):
text = (
"Thought: I found the information\nFinal Answer: The temperature is 100 degrees"
)
result = parser.parse(text)
assert isinstance(result, AgentFinish)
assert result.return_values["output"] == "The temperature is 100 degrees"
def test_missing_action_error(parser):
text = "Thought: Let's find the temperature\nAction Input: what is the temperature in SF?"
with pytest.raises(OutputParserException) as exc_info:
parser.parse(text)
assert "Could not parse LLM output" in str(exc_info.value)
def test_missing_action_input_error(parser):
text = "Thought: Let's find the temperature\nAction: search"
with pytest.raises(OutputParserException) as exc_info:
parser.parse(text)
assert "Could not parse LLM output" in str(exc_info.value)
def test_action_and_final_answer_error(parser):
text = "Thought: I found the information\nAction: search\nAction Input: what is the temperature in SF?\nFinal Answer: The temperature is 100 degrees"
with pytest.raises(OutputParserException) as exc_info:
parser.parse(text)
assert "both perform Action and give a Final Answer" in str(exc_info.value)
def test_safe_repair_json(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": Senior Researcher'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_unrepairable(parser):
invalid_json = "{invalid_json"
result = parser._safe_repair_json(invalid_json)
print("result:", invalid_json)
assert result == invalid_json # Should return the original if unrepairable
def test_safe_repair_json_missing_quotes(parser):
invalid_json = (
'{task: "Research XAI", context: "Explainable AI", coworker: Senior Researcher}'
)
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_unclosed_brackets(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_extra_commas(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher",}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_trailing_commas(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher",}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_single_quotes(parser):
invalid_json = "{'task': 'Research XAI', 'context': 'Explainable AI', 'coworker': 'Senior Researcher'}"
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_mixed_quotes(parser):
invalid_json = "{'task': \"Research XAI\", 'context': \"Explainable AI\", 'coworker': 'Senior Researcher'}"
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_unescaped_characters(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher\n"}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
print("result:", result)
assert result == expected_repaired_json
def test_safe_repair_json_missing_colon(parser):
invalid_json = '{"task" "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_missing_comma(parser):
invalid_json = '{"task": "Research XAI" "context": "Explainable AI", "coworker": "Senior Researcher"}'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_unexpected_trailing_characters(parser):
invalid_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"} random text'
expected_repaired_json = '{"task": "Research XAI", "context": "Explainable AI", "coworker": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_safe_repair_json_special_characters_key(parser):
invalid_json = '{"task!@#": "Research XAI", "context$%^": "Explainable AI", "coworker&*()": "Senior Researcher"}'
expected_repaired_json = '{"task!@#": "Research XAI", "context$%^": "Explainable AI", "coworker&*()": "Senior Researcher"}'
result = parser._safe_repair_json(invalid_json)
assert result == expected_repaired_json
def test_parsing_with_whitespace(parser):
text = " Thought: Let's find the temperature \n Action: search \n Action Input: what is the temperature in SF? "
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF?"
def test_parsing_with_special_characters(parser):
text = 'Thought: Let\'s find the temperature\nAction: search\nAction Input: "what is the temperature in SF?"'
result = parser.parse(text)
assert isinstance(result, AgentAction)
assert result.tool == "search"
assert result.tool_input == "what is the temperature in SF?"
def test_integration_valid_and_invalid(parser):
text = """
Thought: Let's find the temperature
Action: search
Action Input: what is the temperature in SF?
Thought: I found the information
Final Answer: The temperature is 100 degrees
Thought: Missing action
Action Input: invalid
Thought: Missing action input
Action: invalid
"""
parts = text.strip().split("\n\n")
results = []
for part in parts:
try:
result = parser.parse(part.strip())
results.append(result)
except OutputParserException as e:
results.append(e)
assert isinstance(results[0], AgentAction)
assert isinstance(results[1], AgentFinish)
assert isinstance(results[2], OutputParserException)
assert isinstance(results[3], OutputParserException)
class MockAgent:
def increment_formatting_errors(self):
pass
# TODO: ADD TEST TO MAKE SURE ** REMOVAL DOESN'T MESS UP ANYTHING

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,151 @@
interactions:
- request:
body: '{"messages": [{"content": "You are Researcher. You''re an expert researcher,
specialized in technology, software engineering, AI and startups. You work as
a freelancer and is now working on doing research and analysis for a new customer.\nYour
personal goal is: Make the best research and analysis on content about AI and
AI agentsTo give my best complete final answer to the task use the exact following
format:\n\nThought: I now can give a great answer\nFinal Answer: my best complete
final answer to the task.\nYour 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!\nCurrent Task: Say Hi\n\nThis is the expect criteria for
your final answer: Hi \n you 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:\n",
"role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"], "stream":
true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1072'
content-type:
- application/json
cookie:
- _cfuvid=Nxp5RE8CN2EyHxMIvB_SaTizIH5w0eWt9SPilMuIjMk-1721227661802-0.0.1.1-604800000;
__cf_bm=jadAYV2gh7qPDzgKO9A4JzJTaI9c2fnnjxloIQZeOIw-1721227661-1.0.1.1-apaA8kQyGiEV3kOuXHe8z1zeyvxd_jBHCQpdqWirUlylrUo.uRZjRDueI.sSXS4hXoWkyIW6kIMt7lamQM2mdw
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.10
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.10
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.12.3
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9m0FB4Oy6X0apYX2wcQ30rTBkmtxT","object":"chat.completion.chunk","created":1721227709,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a4b087e7d024593-ATL
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Wed, 17 Jul 2024 14:48:29 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '142'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=15552000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999753'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_75100793afc289eaf8b56127e1cc0532
status:
code: 200
message: OK
version: 1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,262 @@
interactions:
- request:
body: '{"messages": [{"content": "You are Scorer. You''re an expert scorer, specialized
in scoring titles.\nYour personal goal is: Score the titleTo give my best complete
final answer to the task use the exact following format:\n\nThought: I now can
give a great answer\nFinal Answer: my best complete final answer to the task.\nYour
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!\nCurrent
Task: Give me an integer score between 1-5 for the following title: ''The impact
of AI in the future of work''\n\nThis is the expect criteria for your final
answer: The score of the title. \n you 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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"],
"stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '997'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.14
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.14
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltULlJQMDDjI2f7PpkjJ7DsxWjEQ","object":"chat.completion.chunk","created":1721201741,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a488e81aa7f0c7e-EWR
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Wed, 17 Jul 2024 07:35:41 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=Ypr9N3lq.OD8hpimnkpN61rAsWyk216I8Tq7RA8.uwQ-1721201741-1.0.1.1-6Cj4aX9I96QHMmPwJBpO1iCFOJsvzq_agUIrl3XS.YhlPuGyA4K9sDONExvLn.cDe3W_p_1ET7Pt_hxjtHPAXQ;
path=/; expires=Wed, 17-Jul-24 08:05:41 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=NLa1BaUsRvD7shojIzUH9YSRXQIEzaoJVcq2_gNwqm0-1721201741646-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '106'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=15552000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999771'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_e52461a1ab2702e360f6303fbcb4cc3c
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "user", "content": "4"}, {"role": "system", "content":
"I''m gonna convert this raw text into valid JSON."}], "model": "gpt-4o", "tool_choice":
{"type": "function", "function": {"name": "ScoreOutput"}}, "tools": [{"type":
"function", "function": {"name": "ScoreOutput", "description": "Correctly extracted
`ScoreOutput` with all the required parameters with correct types", "parameters":
{"properties": {"score": {"title": "Score", "type": "integer"}}, "required":
["score"], "type": "object"}}}]}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '519'
content-type:
- application/json
cookie:
- __cf_bm=Ypr9N3lq.OD8hpimnkpN61rAsWyk216I8Tq7RA8.uwQ-1721201741-1.0.1.1-6Cj4aX9I96QHMmPwJBpO1iCFOJsvzq_agUIrl3XS.YhlPuGyA4K9sDONExvLn.cDe3W_p_1ET7Pt_hxjtHPAXQ;
_cfuvid=NLa1BaUsRvD7shojIzUH9YSRXQIEzaoJVcq2_gNwqm0-1721201741646-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.14
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.14
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: !!binary |
H4sIAAAAAAAAA2xS22rjMBB991eIeY6LHTubrR9LKYUttKWUvbUYRRnb6sqSVhqTJiH/vshxYzes
H8QwZ86FGe8jxkCuoWAgGk6itSq+VPR8d8O/vXXZbiOzx13S5D9/PNwSv8nvYBYYZvWGgj5YF8K0
ViFJo4+wcMgJg2q6nKfzJF3maQ+0Zo0q0GpLcW7ieTLP42QRp9lAbIwU6KFgvyPGGNv3b4io1/gO
BUtmH50Wvec1QnEaYgycUaED3HvpiWuC2QgKowl1SK07pSYAGaNKwZUajY/fflKPe+JKlVe/nqvV
98vNtslul3/Xj7vrzaZ6StOJ31F6a/tAVafFaT8T/NQvzswYA83bnvskjMP7jmxHZ3TGgLu6a1FT
iA77F/Bh+AWK/ACfRg/R/+rXoTqc1qpMbZ1Z+bMtQSW19E3pkPs+LXgy9mgR5F7783WfLgLWmdZS
SeYP6iD4dbgejP/LCC4GjAxxNeEsoiEe+K0nbMtK6hqddbI/JVS2FDkuVl8qnqUQHaJ/AAAA//8D
ACb4o2zTAgAA
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a488e858ca50c7e-EWR
Connection:
- keep-alive
Content-Encoding:
- gzip
Content-Type:
- application/json
Date:
- Wed, 17 Jul 2024 07:35:42 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '241'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=15552000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999968'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_01c2f40fe9c73f883b7ed5b60c8067e5
status:
code: 200
message: OK
version: 1

View File

@@ -1,296 +1,266 @@
interactions:
- request:
body: '{"messages": [{"role": "user", "content": "You are test role. test backstory\nYour
personal goal is: test goal\n\nYou ONLY have access to the following tools,
and should NEVER make up tools that are not listed here:\n\nmultiplier: multiplier(first_number:
int, second_number: int) -> float - Useful for when you need to multiply two
numbers together.\n\nUse the following format:\n\nThought: you should always
think about what to do\nAction: the action to take, only one name of [multiplier],
just the name, exactly as it''s written.\nAction Input: the input to the action,
just a simple a python dictionary using \" to wrap keys and values.\nObservation:
the result of the action\n\nOnce all necessary information is gathered:\n\nThought:
I now know the final answer\nFinal Answer: the final answer to the original
input question\n\n\nCurrent Task: What is 3 times 4?\n\nThis is the expect criteria
for your final answer: The result of the multiplication. \n you 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: \n"}], "model": "gpt-4", "n": 1, "stop":
body: '{"messages": [{"content": "You are test role. test backstory\nYour personal
goal is: test goal\nYou ONLY have access to the following tools, and should
NEVER make up tools that are not listed here:\n\nmultiplier(first_number: int,
second_number: int) -> float - Useful for when you need to multiply two numbers
together.\n\nUse the following format:\n\nThought: you should always think about
what to do\nAction: the action to take, only one name of [multiplier], just
the name, exactly as it''s written.\nAction Input: the input to the action,
just a simple python dictionary, enclosed in curly braces, using \" to wrap
keys and values.\nObservation: the result of the action\n\nOnce all necessary
information is gathered:\n\nThought: I now know the final answer\nFinal Answer:
the final answer to the original input question\n\nCurrent Task: What is 3 times
4?\n\nThis is the expect criteria for your final answer: The result of the multiplication.
\n you 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:\n", "role": "user"}], "model": "gpt-4o",
"n": 1, "stop": ["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '1277'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.10
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.10
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
need"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
to"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
determine"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
the"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
product"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
and"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":".\n\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Action"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
multiplier"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Action"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Input"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
{\""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"first"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"_number"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":","},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
\""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"second"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"_number"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"}"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFmdFjejvg8ErQVjcpCsY8q7QbBI","object":"chat.completion.chunk","created":1720810787,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a2345bd1ffd742e-MIA
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:59:47 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=EvHnbspWLzEWYmRV1sLsvFlp1S5ePQd_KIGldEvula4-1720810787-1.0.1.1-fcfgfphTZearpEpqAdn5vCov8FO3hERf4Zij0dZmjoTuHkfcpXthynLGlq2sBt7SpE72ogziXHDlNZsSvmBQzA;
path=/; expires=Fri, 12-Jul-24 19:29:47 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=QoRToNVlfxPsZucAm6jmW5xUqoEucDbQTYK4SkSwmUc-1720810787746-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '90'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999703'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_f9575c9cc6494a463ddd5681e599b56d
status:
code: 200
message: OK
- request:
body: '{"messages": [{"content": "You are test role. test backstory\nYour personal
goal is: test goal\nYou ONLY have access to the following tools, and should
NEVER make up tools that are not listed here:\n\nmultiplier(first_number: int,
second_number: int) -> float - Useful for when you need to multiply two numbers
together.\n\nUse the following format:\n\nThought: you should always think about
what to do\nAction: the action to take, only one name of [multiplier], just
the name, exactly as it''s written.\nAction Input: the input to the action,
just a simple python dictionary, enclosed in curly braces, using \" to wrap
keys and values.\nObservation: the result of the action\n\nOnce all necessary
information is gathered:\n\nThought: I now know the final answer\nFinal Answer:
the final answer to the original input question\n\nCurrent Task: What is 3 times
4?\n\nThis is the expect criteria for your final answer: The result of the multiplication.
\n you 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:\nI need to determine the product
of 3 and 4.\n\nAction: multiplier\nAction Input: {\"first_number\": 3, \"second_number\":
4}\nObservation: 12\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop":
["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
- gzip, deflate
connection:
- keep-alive
content-length:
- '1268'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.12.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.12.0
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
need"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
to"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
calculate"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
the"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
product"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
and"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":".\n\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Action"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"multi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"plier"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Action"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
Input"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"{\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
\""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"first"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"_number"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"3"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":",\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
\""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"second"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"_number"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"4"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"}\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQXsDdREkfWKHVzRsYPnQXOyQNX","object":"chat.completion.chunk","created":1709396581,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 85e2ba970e5851e6-GRU
Cache-Control:
- no-cache, must-revalidate
Connection:
- keep-alive
Content-Type:
- text/event-stream
Date:
- Sat, 02 Mar 2024 16:23:01 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=C0VdYjpV_Hv7CqW8v18fK47fudXVna82_U1z_FcZ1Ng-1709396581-1.0.1.1-3mcMHbUjGImAUy9c5jtpPwFU1NQDoziKGjF8PNiFaGvST9S6PAOQVvyo4vHhKkznZM38Rs39YASCuQyyHRlkUg;
path=/; expires=Sat, 02-Mar-24 16:53:01 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=XwSpHIa8bLFKjduTc6qVKOscgm9TIoxw5Nm7uklFgXw-1709396581628-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
access-control-allow-origin:
- '*'
alt-svc:
- h3=":443"; ma=86400
openai-model:
- gpt-4-0613
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '360'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=15724800; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '300000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '299706'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 58ms
x-request-id:
- req_e3515cf2ba7a535d68b03019b57dfbf1
status:
code: 200
message: OK
- request:
body: '{"messages": [{"role": "user", "content": "You are test role. test backstory\nYour
personal goal is: test goal\n\nYou ONLY have access to the following tools,
and should NEVER make up tools that are not listed here:\n\nmultiplier: multiplier(first_number:
int, second_number: int) -> float - Useful for when you need to multiply two
numbers together.\n\nUse the following format:\n\nThought: you should always
think about what to do\nAction: the action to take, only one name of [multiplier],
just the name, exactly as it''s written.\nAction Input: the input to the action,
just a simple a python dictionary using \" to wrap keys and values.\nObservation:
the result of the action\n\nOnce all necessary information is gathered:\n\nThought:
I now know the final answer\nFinal Answer: the final answer to the original
input question\n\n\nCurrent Task: What is 3 times 4?\n\nThis is the expect criteria
for your final answer: The result of the multiplication. \n you 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: \nI need to calculate the product of 3 and
4.\n\nAction: \nmultiplier\n\nAction Input: \n{\n \"first_number\": 3,\n \"second_number\":
4\n}\n\nObservation: 12\n"}], "model": "gpt-4", "n": 1, "stop": ["\nObservation"],
"stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '1428'
- '1420'
content-type:
- application/json
cookie:
- __cf_bm=C0VdYjpV_Hv7CqW8v18fK47fudXVna82_U1z_FcZ1Ng-1709396581-1.0.1.1-3mcMHbUjGImAUy9c5jtpPwFU1NQDoziKGjF8PNiFaGvST9S6PAOQVvyo4vHhKkznZM38Rs39YASCuQyyHRlkUg;
_cfuvid=XwSpHIa8bLFKjduTc6qVKOscgm9TIoxw5Nm7uklFgXw-1709396581628-0.0.1.1-604800000
- __cf_bm=EvHnbspWLzEWYmRV1sLsvFlp1S5ePQd_KIGldEvula4-1720810787-1.0.1.1-fcfgfphTZearpEpqAdn5vCov8FO3hERf4Zij0dZmjoTuHkfcpXthynLGlq2sBt7SpE72ogziXHDlNZsSvmBQzA;
_cfuvid=QoRToNVlfxPsZucAm6jmW5xUqoEucDbQTYK4SkSwmUc-1720810787746-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.12.0
- OpenAI/Python 1.35.10
x-stainless-arch:
- arm64
x-stainless-async:
@@ -300,7 +270,7 @@ interactions:
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.12.0
- 1.35.10
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
@@ -309,60 +279,60 @@ interactions:
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
string: 'data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
know"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
the"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{"content":"12"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"12"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-8yMQZOVWWNho7BfFEeCd0GJq4Qstq","object":"chat.completion.chunk","created":1709396583,"model":"gpt-4-0613","system_fingerprint":null,"choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: {"id":"chatcmpl-9kFme2PvSyqdXzFbvYY0WXafqzr5K","object":"chat.completion.chunk","created":1720810788,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
@@ -373,47 +343,41 @@ interactions:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 85e2baa3593951e6-GRU
Cache-Control:
- no-cache, must-revalidate
- 8a2345c21e0b742e-MIA
Connection:
- keep-alive
Content-Type:
- text/event-stream
- text/event-stream; charset=utf-8
Date:
- Sat, 02 Mar 2024 16:23:03 GMT
- Fri, 12 Jul 2024 18:59:48 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
access-control-allow-origin:
- '*'
alt-svc:
- h3=":443"; ma=86400
openai-model:
- gpt-4-0613
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '321'
- '133'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=15724800; includeSubDomains
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '300000'
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '299670'
- '21999671'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 65ms
- 0s
x-request-id:
- req_5670da4792b11cfa6dd8ed3b6dd85cbc
- req_be7165ee4924469e40e6a6b89a758b39
status:
code: 200
message: OK

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,697 @@
interactions:
- request:
body: '{"messages": [{"content": "You are Researcher. You''re an expert researcher,
specialized in technology, software engineering, AI and startups. You work as
a freelancer and is now working on doing research and analysis for a new customer.\nYour
personal goal is: Make the best research and analysis on content about AI and
AI agentsTo give my best complete final answer to the task use the exact following
format:\n\nThought: I now can give a great answer\nFinal Answer: my best complete
final answer to the task.\nYour 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!\nCurrent Task: Generate a list of 5 interesting ideas
to explore for an article, where each bulletpoint is under 15 words.\n\nThis
is the expect criteria for your final answer: Bullet point list of 5 important
events. No additional commentary. \n you 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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"],
"stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '1237'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Ethical"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
implications"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
decision"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-making"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
healthcare"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
agents"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
revolution"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"izing"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
customer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
service"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
e"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-commerce"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Advances"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-driven"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
predictive"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
maintenance"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
for"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
industries"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
The"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
role"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
autonomous"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
vehicle"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
safety"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":".\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
personalized"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
education"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Adaptive"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
learning"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
technologies"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"."},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7QxB9Y779gwWcC1EK2JtcMZ7vCS","object":"chat.completion.chunk","created":1720540363,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a097b99ad909e50-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Tue, 09 Jul 2024 15:52:44 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=3B5vxI0ieroGmK5h7cD7a8bCSrrPh4hLjrbw87J9XRE-1720540364-1.0.1.1-BXhaEwefXZ7Ez0Fg7.8O4AAnOoPc5b7O.4CdzhLnbo9WIF30RlsTzH58YBRxoQipeSCQMxhePm2HaNR6nNfWEQ;
path=/; expires=Tue, 09-Jul-24 16:22:44 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=D7VkuRYil_ytD3F4vcJzvO0gmVHyb3ZlnhCIjCrlyWE-1720540364005-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- user-soijsnuwuk3xvbf91w0jc33c
openai-processing-ms:
- '114'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '5000'
x-ratelimit-limit-tokens:
- '450000'
x-ratelimit-remaining-requests:
- '4999'
x-ratelimit-remaining-tokens:
- '449712'
x-ratelimit-reset-requests:
- 12ms
x-ratelimit-reset-tokens:
- 38ms
x-request-id:
- req_94f0907cc8b2065f1e223070d2be2a85
status:
code: 200
message: OK
- request:
body: '{"messages": [{"content": "You are Researcher. You''re an expert researcher,
specialized in technology, software engineering, AI and startups. You work as
a freelancer and is now working on doing research and analysis for a new customer.\nYour
personal goal is: Make the best research and analysis on content about AI and
AI agentsTo give my best complete final answer to the task use the exact following
format:\n\nThought: I now can give a great answer\nFinal Answer: my best complete
final answer to the task.\nYour 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!\nCurrent Task: Generate a list of 5 interesting ideas
to explore for an article, where each bulletpoint is under 15 words.\n\nThis
is the expect criteria for your final answer: Bullet point list of 5 important
events. No additional commentary. \n you 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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"],
"stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '1237'
content-type:
- application/json
cookie:
- __cf_bm=3B5vxI0ieroGmK5h7cD7a8bCSrrPh4hLjrbw87J9XRE-1720540364-1.0.1.1-BXhaEwefXZ7Ez0Fg7.8O4AAnOoPc5b7O.4CdzhLnbo9WIF30RlsTzH58YBRxoQipeSCQMxhePm2HaNR6nNfWEQ;
_cfuvid=D7VkuRYil_ytD3F4vcJzvO0gmVHyb3ZlnhCIjCrlyWE-1720540364005-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Evolution"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Agents"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Customer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Service"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
in"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Healthcare"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Transform"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"ing"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Diagnostics"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
and"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Treatment"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Ethical"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Imp"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"lications"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
of"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Autonomous"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Systems"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"Driven"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Start"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"ups"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Dis"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"ruption"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
and"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Innovation"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"-"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
and"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Cyber"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"security"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Def"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"ending"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Against"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Modern"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"
Threat"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{"content":"s"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9j7Qz3vXpsGKDVKeZa6oBvQ1PkdmE","object":"chat.completion.chunk","created":1720540365,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_ce0793330f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a097ba2bc449e50-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Tue, 09 Jul 2024 15:52:45 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- user-soijsnuwuk3xvbf91w0jc33c
openai-processing-ms:
- '117'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '5000'
x-ratelimit-limit-tokens:
- '450000'
x-ratelimit-remaining-requests:
- '4999'
x-ratelimit-remaining-tokens:
- '449712'
x-ratelimit-reset-requests:
- 12ms
x-ratelimit-reset-tokens:
- 38ms
x-request-id:
- req_a28d912698f7b75be87900d3a64bc91f
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,161 @@
interactions:
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Test Task\n\nThis is the
expect criteria for your final answer: Say Hi to John \n you MUST return the
actual complete content as the final answer, not a summary.\n\nThis is the context
you''re working with:\ncontext raw output\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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop":
["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '918'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kFSxQSL63v0sL4iqWFRWkul8QbhP","object":"chat.completion.chunk","created":1720809567,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a2327f1190467c1-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:39:27 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=df.hIcEr2QTS045wWa7HSF0ATx6AeLAoPPW0FoIx7W4-1720809567-1.0.1.1-1Y2nQ4DHdc5HUHFO08LdQOoWZykmQ0xe67vzmv2dS4OnnKEHYd9GMzcq.vWODTXoI.BoSxQiRrylKYuuO2t8Tw;
path=/; expires=Fri, 12-Jul-24 19:09:27 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=Zmb0XRHa49q2R664FqlS3F.aojtATJKKGnkUiQoH92I-1720809567257-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '83'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999792'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_4fd8c7c8d47e20be017fb8de1ccb07c9
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,159 @@
interactions:
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Test Task\n\nThis is the
expect criteria for your final answer: Say Hi \n you MUST return the actual
complete content as the final answer, not a summary.\n\nThis is the context
you''re working with:\ncontext raw output\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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop":
["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '910'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.14
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.14
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9ltUKsvuhS55Ng70kOmxKNQcksxm4","object":"chat.completion.chunk","created":1721201740,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_c4e5b6fa31","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a488e7859304288-EWR
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Wed, 17 Jul 2024 07:35:40 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=tBullt04HIYduv1QEpAn86_ghx9PQ4DMe9LwLp7.bu4-1721201740-1.0.1.1-sGn3OYi9ntPGIzwuC4RH0UTUQFVy.BUFIvy9v9IrjorYeAsecsuuuREs7b19i4dXygWnZZEkH6cxvnQeJ62g7g;
path=/; expires=Wed, 17-Jul-24 08:05:40 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=uSSEccAecytxcWKGJoaQXLVBAwHLrZ.QckpcK..rN48-1721201740355-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '83'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=15552000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999793'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_89b4947eaf51788bd7a69d6cc0da6c08
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,472 @@
interactions:
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Context Task\n\nThis is
the expect criteria for your final answer: Say John \n you 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:\n", "role": "user"}], "model": "gpt-4o", "n":
1, "stop": ["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '851'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Say"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4hrEQNmcSJd7kCqA2oxUWQ4qOr","object":"chat.completion.chunk","created":1720808063,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a23033dc9abce48-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:14:23 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=iykqFZ5ecR102MDyK48cHc9Ge3aXJBNKkesB4w9tCz4-1720808063-1.0.1.1-Eg_rjCINHV9hw7HzDFtJgxfwBfr9SahyJnbyo.JfBNFYax9M.ZcSVwmQwySE6AzVg.5AaLC05iljPfXmN26FrA;
path=/; expires=Fri, 12-Jul-24 18:44:23 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=KWM5AhkXkvM2JvJ6J7QHiC9iposfEkI9eZRl8w6aVTY-1720808063923-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '84'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999807'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_e6b4b9610f2f254a228ad44dda349115
status:
code: 200
message: OK
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Test Task\n\nThis is the
expect criteria for your final answer: Say Hi to John \n you MUST return the
actual complete content as the final answer, not a summary.\n\nThis is the context
you''re working with:\nSay John\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:\n",
"role": "user"}], "model": "gpt-4o", "n": 1, "stop": ["\nObservation"], "stream":
true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '908'
content-type:
- application/json
cookie:
- __cf_bm=iykqFZ5ecR102MDyK48cHc9Ge3aXJBNKkesB4w9tCz4-1720808063-1.0.1.1-Eg_rjCINHV9hw7HzDFtJgxfwBfr9SahyJnbyo.JfBNFYax9M.ZcSVwmQwySE6AzVg.5AaLC05iljPfXmN26FrA;
_cfuvid=KWM5AhkXkvM2JvJ6J7QHiC9iposfEkI9eZRl8w6aVTY-1720808063923-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iocDiUNkL6NucVvumIQYikY61","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_298125635f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a230340ec4cce48-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:14:24 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '69'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999795'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_f3233314439a85e7a197be3d067c6d1c
status:
code: 200
message: OK
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Test Task\n\nThis is the
expect criteria for your final answer: Say Hi to John \n you MUST return the
actual complete content as the final answer, not a summary.\n\nThis is the context
you''re working with:\ncontext raw output\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:\n", "role": "user"}], "model": "gpt-4o", "n": 1, "stop":
["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, br
connection:
- keep-alive
content-length:
- '918'
content-type:
- application/json
cookie:
- __cf_bm=iykqFZ5ecR102MDyK48cHc9Ge3aXJBNKkesB4w9tCz4-1720808063-1.0.1.1-Eg_rjCINHV9hw7HzDFtJgxfwBfr9SahyJnbyo.JfBNFYax9M.ZcSVwmQwySE6AzVg.5AaLC05iljPfXmN26FrA;
_cfuvid=KWM5AhkXkvM2JvJ6J7QHiC9iposfEkI9eZRl8w6aVTY-1720808063923-0.0.1.1-604800000
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.35.3
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.35.3
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.5
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9kF4iAwQ2K0M2fy86qpF660mrclmY","object":"chat.completion.chunk","created":1720808064,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_d33f7b429e","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a2303443f0cce48-SJC
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Fri, 12 Jul 2024 18:14:24 GMT
Server:
- cloudflare
Transfer-Encoding:
- chunked
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '86'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=31536000; includeSubDomains
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '22000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '21999791'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_649687e24793d5b5782ecf58bc76386a
status:
code: 200
message: OK
version: 1

View File

@@ -0,0 +1,163 @@
interactions:
- request:
body: '{"messages": [{"content": "You are test_agent. Test Description\nYour personal
goal is: Test GoalTo give my best complete final answer to the task use the
exact following format:\n\nThought: I now can give a great answer\nFinal Answer:
my best complete final answer to the task.\nYour 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!\nCurrent Task: Test Task\n\nThis is the
expect criteria for your final answer: Say Hi to John \n you MUST return the
actual complete content as the final answer, not a summary.\n\nThis is the context
you''re working with:\ncontext raw output\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:\n", "role": "user"}], "model": "gpt-4o", "logprobs": false,
"n": 1, "stop": ["\nObservation"], "stream": true, "temperature": 0.7}'
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate
connection:
- keep-alive
content-length:
- '937'
content-type:
- application/json
host:
- api.openai.com
user-agent:
- OpenAI/Python 1.36.0
x-stainless-arch:
- arm64
x-stainless-async:
- 'false'
x-stainless-lang:
- python
x-stainless-os:
- MacOS
x-stainless-package-version:
- 1.36.0
x-stainless-runtime:
- CPython
x-stainless-runtime-version:
- 3.11.7
method: POST
uri: https://api.openai.com/v1/chat/completions
response:
body:
string: 'data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"Thought"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
I"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
now"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
can"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
give"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
a"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
great"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"\n"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"Final"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
Answer"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":":"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
Hi"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{"content":"
John"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-9n6wQ7bzZKcXAmiNgs4nn5Of0EFiM","object":"chat.completion.chunk","created":1721491782,"model":"gpt-4o-2024-05-13","system_fingerprint":"fp_400f27fa1f","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
'
headers:
CF-Cache-Status:
- DYNAMIC
CF-RAY:
- 8a643794fe0341e9-EWR
Connection:
- keep-alive
Content-Type:
- text/event-stream; charset=utf-8
Date:
- Sat, 20 Jul 2024 16:09:42 GMT
Server:
- cloudflare
Set-Cookie:
- __cf_bm=7kfE3khl2E.6zM44yel5nToHzdtz0QeQ4wkLuGYyqSs-1721491782-1.0.1.1-XUb95eXTriHvSUSCH.TCyAmCGCbPK6L7p_tRTDBon8Fo6ns8TDbDoDGA.wVCFI4MTXSxkqrjD0GpYDj4GBTeSQ;
path=/; expires=Sat, 20-Jul-24 16:39:42 GMT; domain=.api.openai.com; HttpOnly;
Secure; SameSite=None
- _cfuvid=iN41lAEk.DjpRMAtG.K0NEvIN0xB9eS0CUCU2iWmjv4-1721491782137-0.0.1.1-604800000;
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
Transfer-Encoding:
- chunked
X-Content-Type-Options:
- nosniff
alt-svc:
- h3=":443"; ma=86400
openai-organization:
- crewai-iuxna1
openai-processing-ms:
- '104'
openai-version:
- '2020-10-01'
strict-transport-security:
- max-age=15552000; includeSubDomains; preload
x-ratelimit-limit-requests:
- '10000'
x-ratelimit-limit-tokens:
- '30000000'
x-ratelimit-remaining-requests:
- '9999'
x-ratelimit-remaining-tokens:
- '29999791'
x-ratelimit-reset-requests:
- 6ms
x-ratelimit-reset-tokens:
- 0s
x-request-id:
- req_4d90924dd28a0fb48c857f03515f0ca8
status:
code: 200
message: OK
version: 1

Some files were not shown because too many files have changed in this diff Show More