Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: PrefectHQ/ControlFlow
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.9.2
Choose a base ref
...
head repository: PrefectHQ/ControlFlow
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref

Commits on Sep 12, 2024

  1. Copy the full SHA
    69ef1d1 View commit details
  2. Fix tests

    jlowin committed Sep 12, 2024
    Copy the full SHA
    2764e15 View commit details
  3. Set env vars for tests

    jlowin committed Sep 12, 2024
    Copy the full SHA
    8a507bc View commit details
  4. Merge pull request #308 from PrefectHQ/model

    Support automatic model configuration on agents
    jlowin authored Sep 12, 2024
    Copy the full SHA
    ad2b455 View commit details

Commits on Sep 13, 2024

  1. Improve gemini support

    jlowin committed Sep 13, 2024
    Copy the full SHA
    a0ef300 View commit details
  2. Update tools.py

    jlowin committed Sep 13, 2024
    Copy the full SHA
    c3046bf View commit details
  3. Merge pull request #309 from PrefectHQ/gemini

    Improve gemini support
    jlowin authored Sep 13, 2024
    Copy the full SHA
    4a22fb8 View commit details
  4. Update guides

    jlowin committed Sep 13, 2024
    Copy the full SHA
    7064be0 View commit details
  5. Merge pull request #310 from PrefectHQ/guides

    Update guides
    jlowin authored Sep 13, 2024
    Copy the full SHA
    a234180 View commit details
  6. Remove Prefect overrides

    jlowin committed Sep 13, 2024
    Copy the full SHA
    aad68ae View commit details

Commits on Sep 17, 2024

  1. update tests

    zzstoatzz committed Sep 17, 2024
    Copy the full SHA
    699b276 View commit details
  2. Copy the full SHA
    816d180 View commit details
  3. update deprecated things

    zzstoatzz committed Sep 17, 2024
    Copy the full SHA
    7bfe4ba View commit details

Commits on Sep 18, 2024

  1. Pin below langchain core 0.3

    jlowin committed Sep 18, 2024
    Copy the full SHA
    341e2e3 View commit details
  2. Merge pull request #318 from PrefectHQ/lc-pin

    Pin below langchain core 0.3
    jlowin authored Sep 18, 2024
    Copy the full SHA
    fcfb94d View commit details
  3. Add docs for multiple labels

    jlowin committed Sep 18, 2024
    Copy the full SHA
    f9c334f View commit details
  4. Merge pull request #320 from PrefectHQ/docs

    Add docs for multiple labels
    jlowin authored Sep 18, 2024
    Copy the full SHA
    38f7c44 View commit details
  5. Copy the full SHA
    a1393dc View commit details
  6. Set lower bound on LC

    jlowin committed Sep 18, 2024
    Copy the full SHA
    1d0c9ea View commit details
  7. Update test_tasks.py

    jlowin committed Sep 18, 2024
    Copy the full SHA
    7940567 View commit details
  8. Merge pull request #312 from PrefectHQ/small-updates

    remove old `typer` extra and update `json` -> `model_dump_json`
    jlowin authored Sep 18, 2024
    Copy the full SHA
    623e485 View commit details
  9. Support langchain 0.3

    jlowin committed Sep 18, 2024
    Copy the full SHA
    e44ee78 View commit details
  10. Fix validation

    jlowin committed Sep 18, 2024
    Copy the full SHA
    d5da71f View commit details
  11. Merge pull request #321 from PrefectHQ/lc-03

    Support langchain 0.3
    jlowin authored Sep 18, 2024
    Copy the full SHA
    91c8bc7 View commit details

Commits on Sep 19, 2024

  1. Copy the full SHA
    8ed1abd View commit details
  2. Update prompt_templates.py

    jlowin committed Sep 19, 2024
    Copy the full SHA
    5065e09 View commit details
  3. Merge pull request #322 from PrefectHQ/llm-instructions

    Add llm-specific prompt instructions
    jlowin authored Sep 19, 2024
    Copy the full SHA
    bbf9c20 View commit details

Commits on Sep 21, 2024

  1. Copy the full SHA
    1eae5de View commit details

Commits on Sep 22, 2024

  1. Add agent memories

    jlowin committed Sep 22, 2024
    Copy the full SHA
    d5c9811 View commit details

Commits on Sep 23, 2024

  1. Add memory docs

    jlowin committed Sep 23, 2024
    Copy the full SHA
    3cbb837 View commit details
  2. Merge pull request #324 from ahuang11/patch-1

    Remove comma from pip install
    jlowin authored Sep 23, 2024
    Copy the full SHA
    61e756e View commit details
  3. Add memory

    jlowin committed Sep 23, 2024
    Copy the full SHA
    77ce8e7 View commit details
  4. Fix history

    jlowin committed Sep 23, 2024
    Copy the full SHA
    8cf9d5f View commit details
  5. Add chroma default

    jlowin committed Sep 23, 2024
    Copy the full SHA
    a802baa View commit details
  6. Add tests

    jlowin committed Sep 23, 2024
    Copy the full SHA
    ecc5ebd View commit details
  7. Update tests

    jlowin committed Sep 23, 2024
    Copy the full SHA
    a5c3f47 View commit details
  8. Copy the full SHA
    f7e5dd2 View commit details
  9. Update memory.mdx

    jlowin committed Sep 23, 2024
    Copy the full SHA
    fa80229 View commit details
  10. Copy the full SHA
    b45a361 View commit details
  11. Merge pull request #326 from PrefectHQ/memories

    Add agent memories
    jlowin authored Sep 23, 2024
    Copy the full SHA
    25c6498 View commit details
  12. Copy the full SHA
    50b4714 View commit details
  13. Bump langchain versions

    jlowin committed Sep 23, 2024
    Copy the full SHA
    e1bcaa6 View commit details
  14. Merge pull request #327 from PrefectHQ/raise_on_failure

    Change raise_on_error to raise_on_failure
    jlowin authored Sep 23, 2024
    Copy the full SHA
    8ac8a76 View commit details
  15. Copy the full SHA
    fb63206 View commit details
  16. Merge pull request #328 from PrefectHQ/pin-versions

    Bump langchain versions
    jlowin authored Sep 23, 2024
    Copy the full SHA
    eac3c56 View commit details
  17. Add version badges

    jlowin committed Sep 23, 2024
    Copy the full SHA
    bc4f9af View commit details

Commits on Sep 24, 2024

  1. Copy the full SHA
    793cb5f View commit details
  2. Copy the full SHA
    78357d7 View commit details
  3. Merge pull request #329 from PrefectHQ/version

    Add version badges
    jlowin authored Sep 24, 2024
    Copy the full SHA
    168b90e View commit details
  4. Copy the full SHA
    d5aad0a View commit details
Showing with 12,873 additions and 2,033 deletions.
  1. +17 −0 .github/ai-labeler.yml
  2. +8 −2 .github/labeler.yml
  3. +21 −0 .github/workflows/ai-labeler.yml
  4. +1 −0 .gitignore
  5. +1 −1 README.md
  6. +35 −5 docs/concepts/agents.mdx
  7. +7 −8 docs/concepts/flows.mdx
  8. +71 −18 docs/concepts/tasks.mdx
  9. +1 −2 docs/examples/call-routing.mdx
  10. +102 −0 docs/examples/features/early-termination.mdx
  11. +101 −0 docs/examples/features/memory.mdx
  12. +2 −7 docs/examples/features/multi-llm.mdx
  13. +1 −1 docs/examples/features/private-flows.mdx
  14. +1 −1 docs/examples/features/tools.mdx
  15. +2 −3 docs/examples/headline-categorization.mdx
  16. +0 −18 docs/examples/library.mdx
  17. +2 −3 docs/examples/named-entity-recognition.mdx
  18. +127 −0 docs/examples/seinfeld-conversation.mdx
  19. +2 −3 docs/examples/sentiment-classifier.mdx
  20. +50 −55 docs/guides/{llms.mdx → configure-llms.mdx}
  21. +3 −2 docs/guides/default-agent.mdx
  22. +62 −0 docs/guides/default-memory.mdx
  23. +1 −1 docs/guides/settings.mdx
  24. +1 −1 docs/installation.mdx
  25. 0 docs/{examples → llm-guides}/examples-guide.md
  26. +427 −0 docs/llm-guides/llm-guide.md
  27. 0 docs/{style_guide.mdx → llm-guides/style-guide.md}
  28. +11 −5 docs/mint.json
  29. +283 −0 docs/patterns/memory.mdx
  30. +123 −28 docs/patterns/running-tasks.mdx
  31. +252 −0 docs/patterns/streaming.mdx
  32. +82 −12 docs/patterns/task-results.mdx
  33. +2 −2 docs/patterns/tools.mdx
  34. +6 −10 docs/quickstart.mdx
  35. +9 −0 docs/snippets/version-badge.mdx
  36. +17 −0 docs/style.css
  37. +1 −1 docs/welcome.mdx
  38. +30 −0 examples/anonymization.py
  39. +55 −0 examples/asyncpg-memory.py
  40. +0 −38 examples/business_headline_sentiment.py
  41. +78 −0 examples/call_routing.py
  42. +0 −16 examples/choose_a_number.py
  43. +31 −0 examples/code_explanation.py
  44. +0 −96 examples/controlflow_docs.py
  45. +52 −0 examples/early_termination.py
  46. +0 −76 examples/engineer/engineer.py
  47. +0 −37 examples/engineer/instructions.md
  48. +26 −0 examples/generate_people.py
  49. +24 −0 examples/headline_categorization.py
  50. +75 −0 examples/language_tutor.py
  51. +37 −0 examples/memory.py
  52. +0 −20 examples/memory_between_flows.py
  53. +47 −0 examples/named_entity_recognition.py
  54. +47 −0 examples/pg-memory.py
  55. +33 −0 examples/pineapple_pizza.py
  56. +0 −43 examples/poem.py
  57. +30 −0 examples/private_flows.py
  58. +118 −0 examples/reasoning.py
  59. +0 −34 examples/restaurant_recs.py
  60. +35 −0 examples/rock_paper_scissors.py
  61. +11 −2 examples/{multi_agent_conversation.py → seinfeld.py}
  62. +29 −0 examples/sentiment_classifier.py
  63. +16 −0 examples/slackbot/Dockerfile
  64. 0 examples/slackbot/__init__.py
  65. +156 −0 examples/slackbot/agents.py
  66. +54 −0 examples/slackbot/custom_types.py
  67. BIN examples/slackbot/diagram.png
  68. +61 −0 examples/slackbot/main.py
  69. +70 −0 examples/slackbot/moderation.py
  70. +4 −0 examples/slackbot/requirements.txt
  71. +15 −0 examples/slackbot/settings.py
  72. +63 −0 examples/slackbot/tools.py
  73. +38 −0 examples/standardize_addresses.py
  74. +40 −0 examples/summarization.py
  75. +0 −34 examples/task_dag.py
  76. +0 −34 examples/teacher_student.py
  77. +25 −0 examples/translation.py
  78. +0 −30 examples/write_and_critique_paper.py
  79. +19 −8 pyproject.toml
  80. +5 −2 src/controlflow/__init__.py
  81. +0 −1 src/controlflow/agents/__init__.py
  82. +118 −60 src/controlflow/agents/agent.py
  83. +0 −99 src/controlflow/agents/memory.py
  84. +10 −3 src/controlflow/cli/dev.py
  85. +73 −53 src/controlflow/decorators.py
  86. +16 −7 src/controlflow/defaults.py
  87. +8 −4 src/controlflow/events/base.py
  88. +140 −27 src/controlflow/events/events.py
  89. +23 −18 src/controlflow/events/history.py
  90. +27 −17 src/controlflow/events/message_compiler.py
  91. +18 −9 src/controlflow/events/orchestrator_events.py
  92. +33 −0 src/controlflow/events/task_events.py
  93. +35 −27 src/controlflow/flows/flow.py
  94. +1 −1 src/controlflow/flows/graph.py
  95. 0 src/controlflow/handlers/__init__.py
  96. +24 −0 src/controlflow/handlers/callback_handler.py
  97. +402 −0 src/controlflow/handlers/print_handler.py
  98. +56 −0 src/controlflow/handlers/queue_handler.py
  99. +31 −12 src/controlflow/llm/models.py
  100. +32 −7 src/controlflow/llm/rules.py
  101. +2 −0 src/controlflow/memory/__init__.py
  102. +149 −0 src/controlflow/memory/async_memory.py
  103. +183 −0 src/controlflow/memory/memory.py
  104. 0 src/controlflow/memory/providers/__init__.py
  105. +77 −0 src/controlflow/memory/providers/chroma.py
  106. +74 −0 src/controlflow/memory/providers/lance.py
  107. +457 −0 src/controlflow/memory/providers/postgres.py
  108. +1 −0 src/controlflow/orchestration/__init__.py
  109. +166 −0 src/controlflow/orchestration/conditions.py
  110. +53 −10 src/controlflow/orchestration/handler.py
  111. +387 −203 src/controlflow/orchestration/orchestrator.py
  112. +0 −204 src/controlflow/orchestration/print_handler.py
  113. +19 −1 src/controlflow/orchestration/prompt_templates.py
  114. +1 −1 src/controlflow/orchestration/prompt_templates/flow.jinja
  115. +1 −1 src/controlflow/orchestration/prompt_templates/instructions.jinja
  116. +9 −0 src/controlflow/orchestration/prompt_templates/llm_instructions.jinja
  117. +12 −0 src/controlflow/orchestration/prompt_templates/memories.jinja
  118. +7 −1 src/controlflow/orchestration/prompt_templates/task.jinja
  119. +25 −10 src/controlflow/orchestration/prompt_templates/tasks.jinja
  120. +9 −9 src/controlflow/orchestration/turn_strategies.py
  121. +1 −1 src/controlflow/plan.py
  122. +0 −216 src/controlflow/planning/auto_tasks.py
  123. +91 −39 src/controlflow/run.py
  124. +67 −21 src/controlflow/settings.py
  125. +118 −0 src/controlflow/stream.py
  126. +248 −69 src/controlflow/tasks/task.py
  127. +39 −24 src/controlflow/tools/tools.py
  128. +30 −0 src/controlflow/utilities/general.py
  129. +23 −7 src/controlflow/utilities/testing.py
  130. +48 −8 tests/agents/test_agents.py
  131. +0 −20 tests/conftest.py
  132. +55 −22 tests/events/test_history.py
  133. +43 −2 tests/fixtures/controlflow.py
  134. 0 tests/llm/__init__.py
  135. +72 −0 tests/llm/test_models.py
  136. 0 tests/memory/__init__.py
  137. +46 −0 tests/memory/test_memory.py
  138. +161 −74 tests/orchestration/test_orchestrator.py
  139. +61 −0 tests/orchestration/test_rules.py
  140. +0 −45 tests/tasks/test_decorator.py
  141. +202 −21 tests/tasks/test_tasks.py
  142. +167 −0 tests/test_decorator.py
  143. +2 −1 tests/test_defaults.py
  144. +250 −4 tests/test_run.py
  145. +4 −1 tests/test_settings.py
  146. +3 −3 tests/tools/test_lc_tools.py
  147. +72 −5 tests/tools/test_tools.py
  148. +41 −0 tests/utilities/test_general.py
  149. +7 −6 tests/utilities/test_testing.py
  150. +5,187 −0 uv.lock
17 changes: 17 additions & 0 deletions .github/ai-labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
labels:
- bug
- breaking change
- documentation
- feature
- enhancement
- question
- example
- good first issue
- tests
- ignore in release notes:
description: "Ignore this PR in release notes"
instructions: |
Administrative changes that don't need to be mentioned in release notes,
such as CI configuration changes. Small changes, including typos, SHOULD
be kept in the release notes; only changes that aren't relevant to
behavior should be ignored.
10 changes: 8 additions & 2 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
documentation:
- changed-files:
- any-glob-to-any-file: "docs/*"
- any-glob-to-any-file: "docs/**"

example:
- changed-files:
- any-glob-to-any-file:
- "examples/**"
- "docs/examples/**"

tests:
- changed-files:
- any-glob-to-any-file: "tests/*"
- any-glob-to-any-file: "tests/**"
21 changes: 21 additions & 0 deletions .github/workflows/ai-labeler.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: AI Labeler

on:
issues:
types: [opened, reopened]
pull_request:
types: [opened, reopened]

jobs:
ai-labeler:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: jlowin/ai-labeler@v0.4.0
with:
include-repo-labels: true
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -174,3 +174,4 @@ cython_debug/
src/controlflow/_version.py
all_code.md
all_docs.md
llm_guides.md
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -54,7 +54,7 @@ Next, configure your LLM provider. ControlFlow's default provider is OpenAI, whi
export OPENAI_API_KEY=your-api-key
```

To use a different LLM provider, [see the LLM configuration docs](https://controlflow.ai/guides/llms).
To use a different LLM provider, [see the LLM configuration docs](https://controlflow.ai/guides/configure-llms).


## Workflow Example
40 changes: 35 additions & 5 deletions docs/concepts/agents.mdx
Original file line number Diff line number Diff line change
@@ -4,6 +4,8 @@ description: The intelligent workers in your AI workflows.
icon: robot
---

import { VersionBadge } from '/snippets/version-badge.mdx'

Agents are the intelligent, autonomous entities that power your AI workflows in ControlFlow. They represent AI models capable of understanding instructions, making decisions, and completing tasks.

```python
@@ -31,7 +33,6 @@ A more complex agent can be created by providing additional configuration. This

```python
import controlflow as cf
from langchain_openai import ChatOpenAI

agent = cf.Agent(
name="Data Analyst",
@@ -41,7 +42,7 @@ agent = cf.Agent(
"Browse the web for data and use Python to analyze it."
),
tools=[cf.tools.web.get_url, cf.tools.code.python],
model=ChatpOpenAI('gpt-4o-mini'),
model="openai/gpt-4o",
interactive=True,
)
```
@@ -68,7 +69,36 @@ Tools are Python functions that the agent can call to perform specific actions o

Each agent has a model, which is the LLM that powers the agent responses. This allows you to choose the most suitable model for your needs, based on factors such as performance, latency, and cost.

ControlFlow supports any LangChain LLM that supports chat and function calling. For more details on how to configure models, see the [LLMs guide](/guides/llms).
ControlFlow supports any LangChain LLM that supports chat and function calling. For more details on how to configure models, see the [LLMs guide](/guides/configure-llms).

```python
import controlflow as cf


agent1 = cf.Agent(model="openai/gpt-4o")
agent2 = cf.Agent(model="anthropic/claude-3-5-sonnet-20240620")
```

### LLM rules
<VersionBadge version="0.11.0" />

Each LLM provider may have different requirements for how messages are formatted or presented. For example, OpenAI permits system messages to be interspersed between user messages, but Anthropic requires them to be at the beginning of the conversation. ControlFlow uses provider-specific rules to properly compile messages for each agent's API.

For common providers like OpenAI and Anthropic, LLM rules can be automatically inferred from the agent's model. However, you can use a custom `LLMRules` object to override these rules or provide rules for non-standard providers.

Here is an example of how to tell the agent to use the Anthropic compilation rules with a custom model that can't be automatically inferred:

```python
import controlflow as cf

# note: this is just an example
llm_model = CustomAnthropicModel()

agent = cf.Agent(
model=model,
llm_rules=cf.llm.rules.AnthropicRules(model=model)
)
```

### Interactivity

@@ -196,7 +226,7 @@ temporary positive outcomes, despite the overall bleak and discouraging reality.
</CodeGroup>
When tasks have multiple agents, it's important to understand how they collaborate (and to provide them with clear instructions to guide that behavior). To learn more, see the [collaboration](/patterns/collaboration) doc.
When tasks have multiple agents, it's important to understand how they collaborate (and to provide them with clear instructions to guide that behavior). To learn more, see the [multi-agent collaboration docs](/patterns/running-tasks#multi-agent-collaboration).
#### Assigning completion agents
@@ -221,4 +251,4 @@ task = cf.Task(
# only a1 and a2 can mark the task as successful
completion_agents=[a1, a2],
)
```
```
15 changes: 7 additions & 8 deletions docs/concepts/flows.mdx
Original file line number Diff line number Diff line change
@@ -119,19 +119,18 @@ The following flow properties are inferred from the decorated function:
| ------------- | ------------- |
| `name` | The function's name |
| `description` | The function's docstring |
| `context` | The function's arguments (keyed by argument name) |
| `context` | The function's arguments, if specified as `context_kwargs` (keyed by argument name) |

Additional properties can be set by passing keyword arguments directly to the `@flow` decorator or to the `flow_kwargs` parameter when calling the decorated function.

<Tip>
You may not want the arguments to your flow function to be used as context. In that case, you can set `args_as_context=False` when decorating or calling the function:
To automatically put some of your flow's arguments into the global context that all agents can see, specify `context_kwargs` when decorating your flow:

```python
@cf.flow(args_as_context=False)
def my_flow(secret_var: str):
@cf.flow(context_kwargs=["x"])
def my_flow(x: int, y: int):
# x will be automatically added to a global, agent-visible context
...
```
</Tip>

Additional properties can be set by passing keyword arguments directly to the `@flow` decorator or to the `flow_kwargs` parameter when calling the decorated function.

### The `Flow` object and context manager

89 changes: 71 additions & 18 deletions docs/concepts/tasks.mdx
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ A task in ControlFlow typically consists of:
There are two primary ways to create tasks in ControlFlow: using the `Task` class directly, or using the `@task` decorator.

<Tip>
In practice, you will often use the `cf.run` function to create and run a task in a single step. This is a common operation and accepts all the same arguments as creating a `Task` directly. See [Running Tasks](/concepts/tasks/running-tasks) for more information.
In practice, you will often use the `cf.run` function to create and run a task in a single step. This is a common operation and accepts all the same arguments as creating a `Task` directly. See [Running Tasks](/patterns/running-tasks) for more information.
</Tip>

### Using the `Task` class
@@ -45,7 +45,7 @@ import controlflow as cf
task = cf.Task(
objective="Write a poem about the provided topic",
instructions="Write four lines that rhyme",
context={"topic": "AI"}
context={"topic": "AI"}
)

result = task.run()
@@ -90,11 +90,11 @@ AI, the future, as it softly glows.
The following task properties are inferred directly from the decorated function:

| Task property | Inferred from |
| -------- | ------------------- |
| `name` | The function's name |
| -------- | ------------------- |
| `name` | The function's name |
| `objective` | The function's docstring and return value (if any) |
| `result_type` | The function's return annotation |
| `context` | The function's arguments (keyed by argument name) and return value (keyed as "Additional context") |
| `result_type` | The function's return annotation |
| `context` | The function's arguments (keyed by argument name) and return value (keyed as "Additional context") |

Additional properties can be set by passing keyword arguments directly to the `@task` decorator.

@@ -104,7 +104,7 @@ When creating a task, you can configure various properties to define its behavio

### Objective

The objective of a task is the main goal that the task is working towards. It is used to guide the task's execution and to help agents understand the task's purpose.
The objective of a task is the main goal that the task is working towards. It is used to guide the task's execution and to help agents understand the task's purpose.

The `objective` is the only required task configuration, as it indicates the task's purpose and helps agents understand the task they are working on.

@@ -136,8 +136,8 @@ cf.run("Write a poem... then fail this task.")
```

```text Result
ValueError: Task 04561cda ("Write a poem... then fail this task.")
failed: Task instructed to be marked as failed despite
ValueError: Task 04561cda ("Write a poem... then fail this task.")
failed: Task instructed to be marked as failed despite
no technical error
```
</CodeGroup>
@@ -185,7 +185,7 @@ import controlflow as cf
from pydantic import BaseModel

media = cf.run(
"Star Wars: Return of the Jedi",
"Star Wars: Return of the Jedi",
result_type=["book", "movie", "album"]
)

@@ -197,7 +197,7 @@ movie
```
</CodeGroup>

For more information, see [Result Types](/concepts/tasks/task-results).
For more information, see [Task Results](/patterns/task-results).

### Result validator

@@ -216,13 +216,13 @@ number = cf.run("Choose a number", result_validator=validate_even)
print(number)
```

For more information, see [Result Validators](/concepts/tasks/task-results#result-validators).
For more information, see [Validation](/patterns/task-results#validation).



### Instructions

The instructions of a task are a string that provides detailed instructions for the task. This information is visible to agents during execution, helping them understand the task they are working on.
The instructions of a task are a string that provides detailed instructions for the task. This information is visible to agents during execution, helping them understand the task they are working on.

<Tip>
As a general rule, use the task's `objective` to describe what the task's result should be, and use the `instructions` to provide more detailed instructions on how to achieve the objective.
@@ -235,7 +235,7 @@ As a general rule, use the task's `objective` to describe what the task's result
import controlflow as cf

poem = cf.run(
"Write a poem about AI",
"Write a poem about AI",
instructions="Write only two lines, and end the first line with `not evil`",
)

@@ -264,6 +264,59 @@ task = cf.Task(
)
```

Note that this setting reflects the configuration of the `completion_tools` parameter.

### Completion tools

import { VersionBadge } from '/snippets/version-badge.mdx'

<VersionBadge version="0.10" />

In addition to specifying which agents are automatically given completion tools, you can control which completion tools are generated for a task using the `completion_tools` parameter. This allows you to specify whether you want to provide success and/or failure tools, or even provide custom completion tools.

The `completion_tools` parameter accepts a list of strings, where each string represents a tool to be generated. The available options are:

- `"SUCCEED"`: Generates a tool for marking the task as successful.
- `"FAIL"`: Generates a tool for marking the task as failed.

If `completion_tools` is not specified, both `"SUCCEED"` and `"FAIL"` tools will be generated by default.

You can manually create completion tools and provide them to your agents by calling `task.get_success_tool()` and `task.get_fail_tool()`.

<Warning>
If you exclude `completion_tools`, agents may be unable to complete the task or become stuck in a failure state. Without caps on LLM turns or calls, this could lead to runaway LLM usage. Make sure to manually manage how agents complete tasks if you are using a custom set of completion tools.
</Warning>

Here are some examples:

```python
# Generate both success and failure tools (default behavior, equivalent to `completion_tools=None`)
task = cf.Task(
objective="Write a poem about AI",
completion_tools=["SUCCEED", "FAIL"],
)

# Only generate a success tool
task = cf.Task(
objective="Write a poem about AI",
completion_tools=["SUCCEED"],
)

# Only generate a failure tool
task = cf.Task(
objective="Write a poem about AI",
completion_tools=["FAIL"],
)

# Don't generate any completion tools
task = cf.Task(
objective="Write a poem about AI",
completion_tools=[],
)
```

By controlling which completion tools are generated, you can customize the task completion process to better suit your workflow needs. For example, you might want to prevent agents from marking a task as failed, or you might want to provide your own custom completion tools instead of using the default ones.

### Name

The name of a task is a string that identifies the task within the workflow. It is used primarily for logging and debugging purposes, though it is also shown to agents during execution to help identify the task they are working on.
@@ -279,8 +332,8 @@ The context of a task is a dictionary that provides additional information about
import controlflow as cf

is_spam = cf.run(
"Is this email spam?",
result_type=bool,
"Is this email spam?",
result_type=bool,
context=dict(email='You just won a million dollars!'),
)

@@ -307,7 +360,7 @@ def roll_dice(n_dice: int):

rolls = cf.run(
"Roll 3 dice",
result_type=list[int],
result_type=list[int],
tools=[roll_dice],
)

@@ -386,4 +439,4 @@ An AI's mind begins to sound.
Electric thoughts and data streams,
Crafting worlds and shaping dreams.
```
</CodeGroup>
</CodeGroup>
3 changes: 1 addition & 2 deletions docs/examples/call-routing.mdx
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@ As you run this example, you'll see the conversation unfold in real-time, culmin

```python
import random
from enum import Enum
import controlflow as cf

DEPARTMENTS = [
@@ -81,7 +80,7 @@ def routing_flow():
),
agents=[trainee],
result_type=None,
tools=[main_task.create_success_tool()]
tools=[main_task.get_success_tool()]
)

if main_task.result == target_department:
Loading