Compare commits

...

346 Commits

Author SHA1 Message Date
amoghmc 71b7429a42
Add missing C# and F# kernels (#6283)
Add missing C# and F# kernels.
These are needed to create a default kernel else it will return an empty
kernel.
2025-04-15 20:15:28 +00:00
cheng-tan 88dda88f53
Pin opentelemetry-proto version (#6305)
## Description
This PR pins opentelemetry-proto version to >=1.28.0, which uses
protobuf > 5.0, < 6.0 to generate protobuf files.

## Related issue number
Closes #6304
2025-04-15 09:04:01 -07:00
Yash Malik 7e8472f99b
minor grammatical fix in docs (#6263)
minor grammatical fix in docs

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-15 06:14:44 +00:00
Abhijeetsingh Meena 756aef366d
Add code generation support to `CodeExecutorAgent` (#6098)
## Why are these changes needed?
- To add support for code generation, execution and reflection to
`CodeExecutorAgent`.

## Related issue number
Closes #5824 

## Checks
- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Signed-off-by: Abhijeetsingh Meena <abhijeet040403@gmail.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-14 23:06:40 -07:00
Sungjun.Kim 71a4eaedf9
Bump up json-schema-to-pydantic from v0.2.3 to v0.2.4 (#6300)
---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-14 21:50:49 -07:00
Victor Dibia 95b1ed5d81
Update AutoGen dependency range in AGS (#6298) 2025-04-15 04:26:30 +00:00
Eric Zhu c75515990e
Update website for 0.5.2 (#6299) 2025-04-14 20:51:45 -07:00
Eric Zhu 3500170be1
update version 0.5.2 (#6296)
Update version
2025-04-14 18:03:44 -07:00
larry 3425d7dc2c
Fix typo in multi-agent-debate.ipynb (#6288) 2025-04-13 03:59:37 +00:00
masquerlin eca80ff663
Update discover.md with adding email agent package (#6274)
adding email agent

## Why are these changes needed?

This PR introduces an AI-powered email assistant that can generate
images, attach files, draft reports, and send emails to multiple
recipients or specific users based on their queries. This feature is
highly beneficial for customer management and email marketing, enhancing
automation and improving efficiency.

## Related issue number

Open #6228 
## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.
2025-04-11 09:35:18 -04:00
Ricky Loynd 92df415edf
Expose TCM TypedDict classes for apps to use (#6269)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

An app can pass untyped dicts to set configuration options of various
Task-Centric Memory classes. But tools like pyright can complain about
the loose typing. This PR exposes 4 TypedDict classes that apps can
optionally use.

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-04-10 15:55:21 -07:00
湛露先生 973774b27f
Fix publish_message-method() notes (#6250)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-04-10 18:51:05 +00:00
Shyam Sathish d70cdf8223
Fix ValueError: Dataclass has a union type error (#6266)
Closes #6265

Convert the `Message` and `Resource` dataclasses to Pydantic models in
the `llamaindex-agent` cookbook.

* Replace `dataclass` with `BaseModel` for `Message` and `Resource`
classes.
* Update imports to use `BaseModel` from `pydantic`

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-04-10 11:38:13 -07:00
Macon Pegram 196be34cb6
[Bugfix] Fix for Issue #6241 - ChromaDB removed IncludeEnum (#6260)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

`IncludeEnum` was removed in ChromaDB when it was updated to `1.0.0`.
This caused issues when using `ChromaDBVectorMemory`. This PR fixes
those issues

## Related issue number

Closes #6241

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-04-10 09:41:41 -07:00
Victor Dibia 1226a4f763
Add note on ModelInfo for Gemini Models (#6259)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Add note on how to update modelinfo for new models.

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #6258

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-04-10 08:53:22 -07:00
Xiaoyun Zhang 7abbdc8a6d
.NET update autogen 0.2.2 -> autogen 0.2.3 (#6257)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-04-09 17:42:46 +00:00
Victor Dibia 32d2a18bf1
[Draft] Enable File Upload/Paste as Task in AGS (#6091)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?



https://github.com/user-attachments/assets/e160f16d-f42d-49e2-a6c6-687e4e6786f4



Enable file upload/paste as a task in AGS. Enables tasks like

- Can you research and fact check the ideas in this screenshot?
- Summarize this file

Only text and images supported for now
Underneath, it constructs TextMessage and Multimodal messages as the
task.

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5773 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-04-09 02:44:45 +00:00
Jay Prakash Thakur cc806a57ef
Bugfix/azure ai search embedding (#6248)
## Why are these changes needed?

bug fix : add get_embedding() implementation

## Related issue number

"Closes #6240 " -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [X] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [X] I've made sure all auto checks have passed.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-09 00:19:18 +00:00
Ricky Loynd b3f59057fa
Expose more Task-Centric Memory parameters (#6246)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

- Exposes a few optional memory controller parameters for more detailed
control and evaluation.
- Fixes a couple formatting issues in the documentation.

## Related issue number

None

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.
2025-04-08 15:13:34 -07:00
Artur ac315ef3ce
fix: typo in usage.md (#6245)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.
2025-04-08 15:05:05 -04:00
Xiaoyun Zhang 2230161447
.NET update oai and aoai package version (#6239)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-04-07 14:51:56 -07:00
Michael Scovetta a024790c5b
Fix sha256_hash docstring (#6236)
Fixes the sha256_hash docstring to refer to SHA-256 and not MD5.

## Why are these changes needed?

The docstring refers to (presumably) a previous implementation that was
using MD5.

## Related issue number

N/A

## Checks

- [X] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [N/A] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [N/A] I've made sure all auto checks have passed.
2025-04-07 15:34:32 -04:00
Eric Zhu f564781fef
Update json_schema_to_pydantic version and make relaxed requirement on arry item. (#6209)
Resolves #6152
2025-04-07 18:44:18 +00:00
湛露先生 8fe627e48c
Fix terminations conditions. (#6229)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
2025-04-07 15:24:54 +00:00
Hussein Mozannar 7acfd8a9d8
Docker Code Exec delete temp files (#6211)
This pull request introduces a new feature to the
`DockerCommandLineCodeExecutor` class, which allows temporary files
generated by code execution to be deleted after code execution. The most
important changes include adding a new configuration option, updating
the class to handle this option, and adding tests to verify the new
functionality.

### New Feature: Temporary File Deletion

*
[`python/packages/autogen-ext/src/autogen_ext/code_executors/docker/_docker_code_executor.py`](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R81):
Added `delete_tmp_files` attribute to the
`DockerCommandLineCodeExecutorConfig` class and updated the
`DockerCommandLineCodeExecutor` class to handle this attribute. This
includes initializing the attribute, adding it to the configuration
methods, and implementing the file deletion logic in the
`_execute_code_dont_check_setup` method.
[[1]](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R81)
[[2]](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R128)
[[3]](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R177)
[[4]](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R231)
[[5]](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R318)
[[6]](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R346-R352)
[[7]](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R527)
[[8]](diffhunk://#diff-8ef47c21141ed8b0a757b0e6f9d1491561fc31684756d22ed0253edbfcfcdf91R547)

### Testing

*
[`python/packages/autogen-ext/tests/code_executors/test_docker_commandline_code_executor.py`](diffhunk://#diff-635dbdcdeca161e620283399d5cd43ca756ec0f88d4429f059ee4f6b346874e4R318-R363):
Added a new test `test_delete_tmp_files` to verify the behavior of the
`delete_tmp_files` attribute. This test checks that temporary files are
correctly deleted or retained based on the configuration.<!-- Thank you
for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->
2025-04-06 18:47:35 +00:00
湛露先生 b6705115d1
clean codes notes for autogen-core. (#6218)
Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-05 22:03:07 -07:00
EeS b24df29ad0
Fix/transformer aware any modelfamily (#6213)
This PR improves fallback safety when an invalid `model_family` is
supplied to `get_transformer()`. Previously, if a user passed an
arbitrary or incorrect `family` string in `model_info`, the lookup could
fail without falling back to `ModelFamily.UNKNOWN`.

Now, we explicitly check whether `model_family` is a valid value in
`ModelFamily.ANY`. If not, we fallback to `_find_model_family()` as
intended.


## Related issue number

Related #6011#issuecomment-2779957730

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-05 19:58:16 -07:00
Leonardo Pinheiro faf2a4e6ff
chore: Add powershell path check for code executor (#6212) 2025-04-06 02:41:06 +00:00
Ardent Illumina b1ae4ac79e
added: gemini 2.5 pro preview (#6226) 2025-04-06 00:27:56 +00:00
湛露先生 0a314c17c7
fix autostudio dabase jsons. (#6183)
Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-04-04 15:00:56 -07:00
湛露先生 27e1656e06
Remove redundancy code and improve validation logics in AgentChat (#6190)
Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-04 21:17:43 +00:00
EeS 39321266f9
Improve SocietyOfMindAgent message handling (#6142)
Please refer to #6123  for full context.

That issue outlines several design and behavioral problems with
`SocietyOfMindAgent`.
This DRAFT PR focuses on resolving the most critical and broken
behaviors first.

Here is the error list
🔍 SocietyOfMindAgent: Design Issues and Historical Comparison (v0.2 vs
v0.4+)

###  P1–P4 Regression Issue Table (Updated with Fixes in PR #6142)

| ID | Description | Current v0.4+ Issue | Resolution in PR #6142 | Was
it a problem in v0.2? | Notes |

|-----|-------------|----------------------|--------------------------|----------------------------|-------|
| **P1** | `inner_messages` leaks into outer team termination evaluation
| `Response.inner_messages` is appended to the outer team's
`_message_thread`, affecting termination conditions. Violates
encapsulation. |  `inner_messages` is excluded from `_message_thread`,
avoiding contamination of outer termination logic. |  No | Structural
boundary is now enforced |
| **P2** | Inner team does not execute when outer message history is
empty | In chained executions, if no new outer message exists, no task
is created and the inner team is skipped entirely |  Detects absence of
new outer message and reuses the previous task, passing it via a handoff
message. This ensures the inner team always receives a valid task to
execute |  No | The issue was silent task omission, not summary
failure. Summary succeeds as a downstream effect |
| **P3** | Summary LLM prompt is built from external input only | Prompt
is constructed using external message history, ignoring internal
reasoning |  Prompt construction now uses
`final_response.inner_messages`, restoring internal reasoning as the
source of summarization |  No | Matches v0.2 internal monologue
behavior |
| **P4** | External input is included in summary prompt (possibly
incorrectly) | Outer messages are used in the final LLM summarization
prompt |  Resolved via the same fix as P3; outer messages are no longer
used for summary |  No | Redundant with P3, now fully addressed |


<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number
resolve #6123 
Blocked #6168 (Sometimes SoMA send last whitespace message)
related #6187
<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-04 13:50:50 -07:00
湛露先生 687946258f
Clean chess examples. (#6203)
Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-04 10:57:40 -07:00
EeS f9268204ad
[BUGFIX] Add LLMCallEventMessage to resolve instantiation error in AgentStudio (#6204)
This PR defines the missing `LLMCallEventMessage` class to resolve an
instantiation error that occurs when using custom messages (e.g., via
AgentStudio).

> **Discord Report**  
> சravanaன் — 오후 6:40  
> _“i updated agentchat and agentcore and tried running the config from
agentstudio and it is now not running the agent and is throwing error
`TypeError: Can't instantiate abstract class LLMCallEventMessage with
abstract methods to_model_message, to_model_text, to_text`”_

The issue stems from `LLMCallEventMessage` being an abstract class that
lacks required methods from `BaseChatMessage`.
This PR implements the missing methods.

Since `LLMCallEventMessage` is intended for **logging/UI use only**, and
not to be sent to LLMs, the `to_model_message()` method raises
`NotImplementedError` by design.


## Related issue number

Reported in Discord 
Closes #6206
2025-04-04 10:24:55 -07:00
Eric Zhu b62b12e3e7
Update website verison (#6196) 2025-04-03 15:57:40 -07:00
Eric Zhu 47602eac9e
Update version to 0.5.1 (#6195) 2025-04-03 15:10:41 -07:00
Eric Zhu d4ac2ca6de
Fix streaming + tool bug in Ollama (#6193)
Fix a bug that caused tool calls to be truncated in
OllamaChatCompletionClient when streaming is on.
2025-04-03 14:56:01 -07:00
Eric Zhu 5508cc7a43
Update versions to 0.5.0 (#6184) 2025-04-02 18:15:50 -07:00
Victor Dibia bd572cc112
Ensure message sent to LLMCallEvent for Anthropic is serializable (#6135)
Messages sent as part of `LLMCallEvent` for Anthropic were not fully serializable
The example below shows TextBlock and ToolUseBlocks inside the content of messages - these throw downsteam errors in apps like AGS (or event sinks) that expect serializable dicts inside the LLMCallEvent.
```
[
{'role': 'user', 'content': 'What is the weather in New York?'}, 
{'role': 'assistant', 'content': [TextBlock(citations=None, text='I can help you find the weather in New York. Let me check that for you.', type='text'), ToolUseBlock(id='toolu_016W8g55GejYGBzRRrcsnt7M', input={'city': 'New York'}, name='get_weather', type='tool_use')]}, 
{'role': 'user', 'content': [{'type': 'tool_result', 'tool_use_id': 'toolu_016W8g55GejYGBzRRrcsnt7M', 'content': 'The weather in New York is 73 degrees and Sunny.'}]}
]


```
This PR attempts to first serialize content of anthropic messages before they are passed to `LLMCallEvent`

```
[
{'role': 'user', 'content': 'What is the weather in New York?'}, 
{'role': 'assistant', 'content': [{'citations': None, 'text': 'I can help you find the weather in New York. Let me check that for you.', 'type': 'text'}, {'id': 'toolu_016W8g55GejYGBzRRrcsnt7M', 'input': {'city': 'New York'}, 'name': 'get_weather', 'type': 'tool_use'}]}, 
{'role': 'user', 'content': [{'type': 'tool_result', 'tool_use_id': 'toolu_016W8g55GejYGBzRRrcsnt7M', 'content': 'The weather in New York is 73 degrees and Sunny.'}]}
]

```
2025-04-02 18:01:42 -07:00
Jay Prakash Thakur 0d9b574d09
Add Azure AI Search tool implementation (#5844)
# Azure AI Search Tool Implementation

This PR adds a new tool for Azure AI Search integration to autogen-ext,
enabling agents to search and retrieve information from Azure AI Search
indexes.

## Why Are These Changes Needed?
AutoGen currently lacks native integration with Azure AI Search, which
is a powerful enterprise search service that supports semantic, vector,
and hybrid search capabilities. This integration enables agents to:
1. Retrieve relevant information from large document collections
2. Perform semantic search with AI-powered ranking
3. Execute vector similarity search using embeddings
4. Combine text and vector approaches for optimal results

This tool complements existing retrieval capabilities and provides a
seamless way to integrate with Azure's search infrastructure.

## Features
- **Multiple Search Types**: Support for text, semantic, vector, and
hybrid search
- **Flexible Configuration**: Customizable search parameters and fields
- **Robust Error Handling**: User-friendly error messages with
actionable guidance
- **Performance Optimizations**: Configurable caching and retry
mechanisms
- **Vector Search Support**: Built-in embedding generation with
extensibility

## Usage Example
```python
from autogen_ext.tools.azure import AzureAISearchTool
from azure.core.credentials import AzureKeyCredential
from autogen import AssistantAgent, UserProxyAgent
# Create the search tool
search_tool = AzureAISearchTool.load_component({
   "provider": "autogen_ext.tools.azure.AzureAISearchTool",
   "config": {
       "name": "DocumentSearch",
       "description": "Search for information in the knowledge base",
       "endpoint": "https://your-service.search.windows.net",
       "index_name": "your-index",
       "credential": {"api_key": "your-api-key"},
       "query_type": "semantic",
       "semantic_config_name": "default"
   }
})
# Create an agent with the search tool
assistant = AssistantAgent(
   "assistant",
   llm_config={"tools": [search_tool]}
)
# Create a user proxy agent
user_proxy = UserProxyAgent(
   "user_proxy",
   human_input_mode="TERMINATE",
   max_consecutive_auto_reply=10,
   code_execution_config={"work_dir": "coding"}
)
# Start the conversation
user_proxy.initiate_chat(
   assistant,
   message="What information do we have about quantum computing in our knowledge base?"
)
```

## Testing
- Added unit tests for all search types (text, semantic, vector, hybrid)
- Added tests for error handling and cancellation
- All tests pass locally

## Documentation
- Added comprehensive docstrings with examples
- Included warnings about placeholder embedding implementation
- Added links to Azure AI Search documentation

## Related issue number

Closes #5419 

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-02 23:16:48 +00:00
EeS d7f2b56846
FIX:simple fix on tool calling test for anthropic (#6181)
Just simple change.

```python
messages: List[LLMMessage] = [UserMessage(content="Call the pass tool with input 'task'", source="user")]
```
to
```python
messages: List[LLMMessage] = [UserMessage(content="Call the pass tool with input 'task' and talk result", source="user")]
```

And, now.
Anthropic model could pass that test case
`test_model_client_with_function_calling`.
-> Yup. Before, claude could not pass that test case.

With this change, Claude (Anthropic) models are now able to pass the
test case successfully.

Before this fix, Claude failed to interpret the intent correctly. Now,
it can infer both tool usage and follow-up generation.

This change is backward-compatible with other models (e.g., GPT-4) and
improves cross-model consistency for function-calling tests.
2025-04-02 23:10:11 +00:00
EeS 27da37efc0
[Refactor] model family resolution to support non-prefixed names like Mistral (#6158)
This PR improves how model_family is resolved when selecting a
transformer from the registry.
Previously, model families were inferred using a simple prefix-based
match like:
```
if model.startswith(family): ...
```
This works for cleanly prefixed models (e.g., `gpt-4o`, `claude-3`) but
fails for models like `mistral-large-latest`, `codestral-latest`, etc.,
where prefix-based matching is ambiguous or misleading.

To address this:
	•	model_family can now be passed explicitly (e.g., via ModelInfo)
• _find_model_family() is only used as a fallback when the value is
"unknown"
	•	Transformer lookup is now more robust and predictable
• Example integration in to_oai_type() demonstrates this pattern using
self._model_info["family"]

This change is required for safe support of models like Mistral and
other future models that do not follow standard naming conventions.

Linked to discussion in
[#6151](https://github.com/microsoft/autogen/issues/6151)
Related : #6011

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-02 22:08:17 +00:00
Stuart Leeks 9143e58ef1
Add session_id_param to ACADynamicSessionsCodeExecutor (#6171)
The initializer for ACADynamicSessionsCodeExecutor creates a new GUID to
use as the session ID for dynamic sessions.

In some scenarios it is desirable to be able to re-create the agent
group chat from saved state. In this case, the
ACADynamicSessionsCodeExecutor needs to be associated with a previous
instance (so that any execution state is still valid)

This PR adds a new argument to the initializer to allow a session ID to
be passed in (defaulting to the current behaviour of creating a GUID if
absent).

Closes #6119

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-02 21:39:44 +00:00
EeS 9de16d5f70
Fix/anthropic colud not end with trailing whitespace at assistant content (#6168)
## Why are these changes needed?

This PR fixes a `400 - invalid_request_error` that occurs when using
Anthropic models and the **final message is from the assistant and ends
with trailing whitespace**.

Example error:

```
Error code: 400 - {'error': {'code': 'invalid_request_error', 'message': 'messages: final assistant content cannot end with trailing whitespace', ...}}
```

To unblock ongoing internal usage, this patch introduces an **ad-hoc
fix** that strips trailing whitespace if the model is Anthropic and the
last message is from the assistant.

## Related issue number

Ad-hoc fix for issue discussed here:  
https://github.com/microsoft/autogen/issues/6167

Follow-up structural proposal here:  
https://github.com/microsoft/autogen/issues/6167
https://github.com/microsoft/autogen/issues/6167#issuecomment-2768592840
2025-04-02 00:56:08 +00:00
Eric Zhu aec04e76ec
Stop run when an error occured in a group chat (#6141)
Resolves #5851

* Added GroupChatError event type and terminate a run when an error
occurs in either a participant or the group chat manager
* Raise a RuntimeError from the error message within the group chat run
2025-04-01 20:17:50 +00:00
Eric Zhu 86237c9fdf
Add output_format to AssistantAgent for structured output (#6071)
Resolves #5934

This PR adds ability for `AssistantAgent` to generate a
`StructuredMessage[T]` where `T` is the content type in base model.

How to use?

```python
from typing import Literal

from pydantic import BaseModel

from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.ui import Console

# The response format for the agent as a Pydantic base model.
class AgentResponse(BaseModel):
    thoughts: str
    response: Literal["happy", "sad", "neutral"]


# Create an agent that uses the OpenAI GPT-4o model which supports structured output.
model_client = OpenAIChatCompletionClient(model="gpt-4o")
agent = AssistantAgent(
    "assistant",
    model_client=model_client,
    system_message="Categorize the input as happy, sad, or neutral following the JSON format.",
    # Setting the output format to AgentResponse to force the agent to produce a JSON string as response.
    output_content_type=AgentResponse,
)

result = await Console(agent.run_stream(task="I am happy."))

# Check the last message in the result, validate its type, and print the thoughts and response.
assert isinstance(result.messages[-1], StructuredMessage)
assert isinstance(result.messages[-1].content, AgentResponse)
print("Thought: ", result.messages[-1].content.thoughts)
print("Response: ", result.messages[-1].content.response)
await model_client.close()
```

```
---------- user ----------
I am happy.
---------- assistant ----------
{
  "thoughts": "The user explicitly states they are happy.",
  "response": "happy"
}
Thought:  The user explicitly states they are happy.
Response:  happy
```

---------

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-04-01 20:11:01 +00:00
Federico Villa 9915b65929
Changed Code Executors default directory to temporary directory (#6143)
## Why are these changes needed?

Changed default working directory of code executors, from the current
directory `"."` to Python's
[`tempfile`](https://docs.python.org/3/library/tempfile.html#tempfile.TemporaryDirectory).
These changes simplify file cleanup and prevent the model from accessing
code files or other sensitive data that should not be accessible.
These changes simplify file cleanup and prevent the model from accessing
code files or other sensitive data that should not be accessible.

Changes made:
- The default `work_dir` parameter in code executors is changed to
`None`; when invoking the `start()` method, if not `work_dir` was
specified (`None`) a temporary directory is created.
- The `start()` and `stop()` methods of code executors handle the
creation and cleanup of the working directory, for the default temporary
directory.
- For maintaining backward compatibility:
- A `DeprecationWarning` is emitted when the current dir, `"."`, is used
as `work_dir` as it is in the current code executor implementation. The
deprecation warning is tested in `test_deprecated_warning()`.
- For existing implementation that do not call the `start()` method and
do not specify a `work_dir`, the executors will continue using the
current directory `"."` as the working directory, mantaining backward
compatibility.
- Updated test suites:
- Added tests to confirm that by default code executors use a temporary
directory as their working directory: `test_default_work_dir_is_temp()`;
- Implemented test to ensure that a `DeprecationWarning` is raised when
the current directory is used as the default directory:
`test_deprecated_warning()`;
- Added tests to ensure that errors arise when invalid paths (doesn't
exist or user has not the right permissions) are provided:
`test_error_wrong_path()`.

Feel free to suggest any additions or improvements!

## Related issue number

Close #6041 

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-04-01 10:26:05 -07:00
Eric Zhu 68c1879675
Update mcp version to 1.6.0 to avoid bug in closing client. (#6162)
Upgrade `mcp` package version to >=1.6.0 to avoid bugs causing hanging
when using mcp_server_featch.
2025-04-01 14:54:30 +00:00
effedici c620683ba6
fix: the installation instruction had a missing step (#6166)
## Why are these changes needed?

Following the [guide
instructions](https://microsoft.github.io/autogen/stable//user-guide/autogenstudio-user-guide/installation.html#a-install-from-source-manually)
the user will execute the commands in the wrong directory.

## Related issue number

Closes #6165
2025-04-01 07:44:49 +00:00
湛露先生 20753ad38c
Fix docs typos. (#5975)
Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-31 07:22:38 +00:00
湛露先生 770bf2357a
Fix typos and optimize OrTerminationCondition (#5980)
Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-31 00:14:58 -07:00
EeS 61ba153614
Doc/moudulor transform oai (#6149)
This PR adds a module-level docstring to `_message_transform.py`, as
requested in the review for [PR
#6063](https://github.com/microsoft/autogen/pull/6063).

The documentation includes:
- Background and motivation behind the modular transformer design
- Key concepts such as transformer functions, pipelines, and maps
- Examples of how to define, register, and use transformers
- Design principles to guide future contributions and extensions

By embedding this explanation directly into the module, contributors and
maintainers can more easily understand the structure, purpose, and usage
of the transformer pipeline without needing to refer to external
documents.

## Related issue number

Follow-up to [PR #6063](https://github.com/microsoft/autogen/pull/6063)
2025-03-31 06:39:27 +00:00
EeS fbdd89b46b
[BugFix][Refactor] Modular Transformer Pipeline and Fix Gemini/Anthropic Empty Content Handling (#6063)
## Why are these changes needed?
This change addresses a compatibility issue when using Google Gemini
models with AutoGen. Specifically, Gemini returns a 400 INVALID_ARGUMENT
error when receiving a response with an empty "text" parameter.

The root cause is that Gemini does not accept empty string values (e.g.,
"") as valid inputs in the history of the conversation.

To fix this, if the content field is falsy (e.g., None, "", etc.), it is
explicitly replaced with a single whitespace (" "), which prevents the
Gemini model from rejecting the request.

- **Gemini API compatibility:** Gemini models reject empty assistant
messages (e.g., `""`), causing runtime errors. This PR ensures such
messages are safely replaced with whitespace where appropriate.
- **Avoiding regressions:** Applying the empty content workaround **only
to Gemini**, and **only to valid message types**, avoids breaking OpenAI
or other models.
- **Reducing duplication:** Previously, message transformation logic was
scattered and repeated across different message types and models.
Modularizing this pipeline removes that redundancy.
- **Improved maintainability:** With future model variants likely to
introduce more constraints, this modular structure makes it easier to
adapt transformations without writing ad-hoc code each time.
- **Testing for correctness:** The new structure is verified with tests,
ensuring the bug fix is effective and non-intrusive.

## Summary

This PR introduces a **modular transformer pipeline** for message
conversion and **fixes a Gemini-specific bug** related to empty
assistant message content.

### Key Changes

- **[Refactor]** Extracted message transformation logic into a unified
pipeline to:
  - Reduce code duplication
  - Improve maintainability
  - Simplify debugging and extension for future model-specific logic

- **[BugFix]** Gemini models do not accept empty assistant message
content.
- Introduced `_set_empty_to_whitespace` transformer to replace empty
strings with `" "` only where needed
- Applied it **only** to `"text"` and `"thought"` message types, not to
`"tools"` to avoid serialization errors

- **Improved structure for model-specific handling**
- Transformer functions are now grouped and conditionally applied based
on message type and model family
- This design makes it easier to support future models or combinations
(e.g., Gemini + R1)

- **Test coverage added**
- Added dedicated tests to verify that empty assistant content causes
errors for Gemini
  - Ensured the fix resolves the issue without affecting OpenAI models

---

## Motivation

Originally, Gemini-compatible endpoints would fail when receiving
assistant messages with empty content (`""`).
This issue required special handling without introducing brittle, ad-hoc
patches.

In addressing this, I also saw an opportunity to **modularize** the
message transformation logic across models.
This improves clarity, avoids duplication, and simplifies future
adaptations (e.g., different constraints across model families).

---


## 📘 AutoGen Modular Message Transformer: Design & Usage Guide

This document introduces the **new modular transformer system** used in
AutoGen for converting `LLMMessage` instances to SDK-specific message
formats (e.g., OpenAI-style `ChatCompletionMessageParam`).
The design improves **reusability, extensibility**, and
**maintainability** across different model families.

---

### 🚀 Overview

Instead of scattering model-specific message conversion logic across the
codebase, the new design introduces:

- Modular transformer **functions** for each message type
- Per-model **transformer maps** (e.g., for OpenAI-compatible models)
- Optional **conditional transformers** for multimodal/text hybrid
models
- Clear separation between **message adaptation logic** and
**SDK-specific builder** (e.g., `ChatCompletionUserMessageParam`)

---

### 🧱 1. Define Transform Functions

Each transformer function takes:
- `LLMMessage`: a structured AutoGen message
- `context: dict`: metadata passed through the builder pipeline

And returns:
- A dictionary of keyword arguments for the target message constructor
(e.g., `{"content": ..., "name": ..., "role": ...}`)

```python
def _set_thought_as_content_gemini(message: LLMMessage, context: Dict[str, Any]) -> Dict[str, str | None]:
    assert isinstance(message, AssistantMessage)
    return {"content": message.thought or " "}
```

---

### 🪢 2. Compose Transformer Pipelines

Multiple transformer functions are composed into a pipeline using
`build_transformer_func()`:

```python
base_user_transformer_funcs: List[Callable[[LLMMessage, Dict[str, Any]], Dict[str, Any]]] = [
    _assert_valid_name,
    _set_name,
    _set_role("user"),
]

user_transformer = build_transformer_func(
    funcs=base_user_transformer_funcs,
    message_param_func=ChatCompletionUserMessageParam
)
```

- The `message_param_func` is the actual constructor for the target
message class (usually from the SDK).
- The pipeline is **ordered** — each function adds or overrides keys in
the builder kwargs.

---

### 🗂️ 3. Register Transformer Map

Each model family maintains a `TransformerMap`, which maps `LLMMessage`
types to transformers:

```python
__BASE_TRANSFORMER_MAP: TransformerMap = {
    SystemMessage: system_transformer,
    UserMessage: user_transformer,
    AssistantMessage: assistant_transformer,
}

register_transformer("openai", model_name_or_family, __BASE_TRANSFORMER_MAP)
```

- `"openai"` is currently required (as only OpenAI-compatible format is
supported now).
- Registration ensures AutoGen knows how to transform each message type
for that model.

---

### 🔁 4. Conditional Transformers (Optional)

When message construction depends on runtime conditions (e.g., `"text"`
vs. `"multimodal"`), use:

```python
conditional_transformer = build_conditional_transformer_func(
    funcs_map=user_transformer_funcs_claude,
    message_param_func_map=user_transformer_constructors,
    condition_func=user_condition,
)
```

Where:

- `funcs_map`: maps condition label → list of transformer functions
```python
user_transformer_funcs_claude = {
    "text": text_transformers + [_set_empty_to_whitespace],
    "multimodal": multimodal_transformers + [_set_empty_to_whitespace],
}
```

- `message_param_func_map`: maps condition label → message builder
```python
user_transformer_constructors = {
    "text": ChatCompletionUserMessageParam,
    "multimodal": ChatCompletionUserMessageParam,
}
```

- `condition_func`: determines which transformer to apply at runtime
```python
def user_condition(message: LLMMessage, context: Dict[str, Any]) -> str:
    if isinstance(message.content, str):
        return "text"
    return "multimodal"
```

---

### 🧪 Example Flow

```python
llm_message = AssistantMessage(name="a", thought="let’s go")
model_family = "openai"
model_name = "claude-3-opus"

transformer = get_transformer(model_family, model_name, type(llm_message))
sdk_message = transformer(llm_message, context={})
```

---

### 🎯 Design Benefits

| Feature | Benefit |
|--------|---------|
| 🧱 Function-based modular design | Easy to compose and test |
| 🧩 Per-model registry | Clean separation across model families |
| ⚖️ Conditional support | Allows multimodal / dynamic adaptation |
| 🔄 Reuse-friendly | Shared logic (e.g., `_set_name`) is DRY |
| 📦 SDK-specific | Keeps message adaptation aligned to builder interface
|

---

### 🔮 Future Direction

- Support more SDKs and formats by introducing new message_param_func
- Global registry integration (currently `"openai"`-scoped)
- Class-based transformer variant if complexity grows



---

## Related issue number
Closes #5762

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ v ] I've made sure all auto checks have passed.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-30 21:09:30 -07:00
Eric Zhu 7615c7b83b
Rename to use BaseChatMessage and BaseAgentEvent. Bring back union types. (#6144)
Rename the `ChatMessage` and `AgentEvent` base classes to `BaseChatMessage` and `BaseAgentEvent`. 

Bring back the `ChatMessage` and `AgentEvent` as union of built-in concrete types to avoid breaking existing applications that depends on Pydantic serialization. 

Why?

Many existing code uses containers like this:

```python
class AppMessage(BaseModel):
   name: str
   message: ChatMessage 

# Serialization is this:
m = AppMessage(...)
m.model_dump_json()

# Fields like HandoffMessage.target will be lost because it is now treated as a base class without content or target fields.
```

The assumption on `ChatMessage` or `AgentEvent` to be a union of concrete types could be in many existing code bases. So this PR brings back the union types, while keep method type hints such as those on `on_messages` to use the `BaseChatMessage` and `BaseAgentEvent` base classes for flexibility.
2025-03-30 09:34:40 -07:00
Eric Zhu e686342f53
Fix token limited model context (#6137)
Token limited model context is currently broken because it is importing
from extensions.

This fix removed the imports and updated the model context
implementation to use model client directly.

In the future, the model client's token counting should cache results
from model API to provide accurate counting.
2025-03-28 17:24:41 +00:00
EeS 0cd3ff46fa
FIX: Anthropic and Gemini could take multiple system message (#6118)
Anthropic SDK could not takes multiple system messages.
However some autogen Agent(e.g. SocietyOfMindAgent) makes multiple
system messages.

And... Gemini with OpenaiSDK do not take error. However is not working
mulitple system messages.
(Just last one is working)

So, I simple change of, "merge multiple system message" at these cases.

## Related issue number
Closes #6116
Closes #6117


---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-28 09:05:54 -07:00
Stuart Leeks c24eba6ae1
Add suppress_result_output to ACADynamicSessionsCodeExecutor initializer (#6130)
When using the `ACADynamicSessionsCodeExecutor` it includes the stdout
from the execution but also the `results` property from the call to
dynamic sessions. In some situations, when the executed code results in
a file being saved this is included in the result:

```console
Plot saved as 'results_by_date.png'
{'type': 'image', 'format': 'png', 'base64_data': 'iVBORw0KGgoAAAANSUhEUgAAA90AAAJOCAYAAACqS2TfAAAAOXRFWHRTb2Z0d2FyZQ...
```

In some situations, this additional output is not desirable:
- when displaying the code output to a user - in this case, the stdout
content is dwarfed by the base64 encoded file content
- when an LLM agent is going to evaluate the code output to determine
next steps - in this case, the base64 content will be included in the
message history sent to the LLM increasing the prompt token cost

To handle these cases, this PR adds a new (optional) argument to the
`ACADynamicSessionsCodeExecutor` constructor that would allow
suppressing the result content (but default to False to preserve the
current behaviour in the default case)

(from #6042)
Closes #6042 


Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-28 01:48:18 +00:00
EeS 2754eda611
FEAT: Add missing OpenAI-compatible models (GPT-4.5, Claude models) (#6120)
This PR adds missing model entries for OpenAI-compatible endpoints,
including gpt-4.5-turbo, gpt-4.5-turbo-preview, and claude-3.5-sonnet.
This improves coverage and avoids potential fallback or mismatch issues
when initializing clients.
2025-03-27 18:39:22 -07:00
Griffin Bassman 7487687cdc
[feat] token-limited message context (#6087) 2025-03-27 13:59:27 -07:00
Eric Zhu 29485ef85b
Fix MCP tool bug by dropping unset parameters from input (#6125)
Resolves #6096

Additionally: make sure MCP errors are formatted correctly, added unit
tests for mcp servers and upgrade mcp version.
2025-03-27 13:22:06 -07:00
Jay Prakash Thakur b5ff7ee355
feat(ollama): Add thought field support and fix LLM control parameters (#6126) 2025-03-26 23:14:26 -07:00
Eric Zhu 025490a1bd
Use class hierarchy to organize AgentChat message types and introduce StructuredMessage type (#5998)
This PR refactored `AgentEvent` and `ChatMessage` union types to
abstract base classes. This allows for user-defined message types that
subclass one of the base classes to be used in AgentChat.

To support a unified interface for working with the messages, the base
classes added abstract methods for:
- Convert content to string
- Convert content to a `UserMessage` for model client
- Convert content for rendering in console.
- Dump into a dictionary
- Load and create a new instance from a dictionary

This way, all agents such as `AssistantAgent` and `SocietyOfMindAgent`
can utilize the unified interface to work with any built-in and
user-defined message type.

This PR also introduces a new message type, `StructuredMessage` for
AgentChat (Resolves #5131), which is a generic type that requires a
user-specified content type.

You can create a `StructuredMessage` as follow:

```python

class MessageType(BaseModel):
  data: str
  references: List[str]

message = StructuredMessage[MessageType](content=MessageType(data="data", references=["a", "b"]), source="user")

# message.content is of type `MessageType`. 
```

This PR addresses the receving side of this message type. To produce
this message type from `AssistantAgent`, the work continue in #5934.

Added unit tests to verify this message type works with agents and
teams.
2025-03-26 16:19:52 -07:00
Jack Gerrits 8a5ee3de6a
Add autogen user agent to azure openai requests (#6124) 2025-03-26 16:01:42 -07:00
Liu Jia ce92926e78
add read timeout for create_mcp_server_session (#6080)
Closes #6031 

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-26 17:51:09 +00:00
y26s4824k264 0bec835d59
Emit <think> and </think> around reasoning chunks from model_extras in choices.detla
So the behavior of hosted R1 model is the same as locally hosted R1 model.
Addresses: #5989
---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-25 16:17:53 -07:00
Kurok1 2e2a314f7e
Take the output of the tool and use that to create the HandoffMessage (#6073)
Take the output of the tool and use that to create the HandoffMessage.
[discussion is
here](https://github.com/microsoft/autogen/discussions/6067#discussion-8117177)

Supports agents to carry specific instructions when performing handoff
operations

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-25 21:38:07 +00:00
Victor Dibia 9a0588347a
add utf encoding in websurfer read file (#6094)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->



<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Add utf encoding to file reading. 
Without this, a default system encoding will be used. On Windows
machines this can default to any local encoding causing errors.

```python
with open(
            os.path.join(os.path.abspath(os.path.dirname(__file__)), "page_script.js"), "rt", encoding="utf-8"
        ) as fh:
```

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #6093


## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-25 09:01:27 -07:00
Jay Prakash Thakur 7047fb8b8d
Add support for thought field in AzureAIChatCompletionClient (#6062)
added support for the thought process in tool calls for
`OpenAIChatCompletionClient`, allowing additional text produced by a
model alongside tool calls to be preserved in the thought field of
`CreateResult`. This PR extends the same functionality to
`AzureAIChatCompletionClient` for consistency across model clients.

#5650
Co-authored-by: Jay Prakash Thakur <jathakur@microsoft.com>
2025-03-24 17:33:10 -07:00
tongyu 47ffaccba1
AssistantAgent.metadata for user/application identity information associated with the agent. #6048 (#6057)
This PR introduces a metadata field in AssistantAgentConfig, allowing
applications to assign and track identity information for agents.
The metadata field is a Dict[str, str] and is included in the
configuration for proper serialization.


---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-23 14:49:57 -07:00
jspv fc2c9978fd
Add model_context property to AssistantAgent (#6072)
AssistantAgent initiation allows one to pass in a model_context, but
there isn't a "public: way to get the existing model_context created by
default.
2025-03-22 20:21:29 -07:00
Abhijeetsingh Meena e28738ac6f
Add async support for `selector_func` and `candidate_func` in `SelectorGroupChat` (#6068) 2025-03-22 11:32:57 -07:00
EeS bca4d7e82f
FIX: Anthropic multimodal(Image) message for Anthropic >= 0.48 aware (#6054)
## Why are these changes needed?
This PR fixes a `TypeError: Cannot instantiate typing.Union` that occurs
when using the `MultimodalWebSurfer_agent` with Anthropic models. The
error was caused by the incorrect usage of `typing.Union` as a class
constructor instead of a type hint within the `_anthropic_client.py`
file. The code was attempting to instantiate `typing.Union`, which is
not allowed. The fix correctly uses `typing.Union` within type hints,
and uses the correct `Base64ImageSourceParam` type. It also updates the
`pyproject.toml` dependency.

## Related issue number
Closes #6035 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [v] I've made sure all auto checks have passed.

---------

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-22 00:46:55 -07:00
Victor Dibia a2add02b12
[Draft] Add Tracing docs to agentchat (#5995)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->


## Why are these changes needed?

- Adds tracing docs page for AgentChat with Jaeger example 
- [x] Runtime tracing: Example code where tracing is done with the
SingleThreaded Runtime, logging all events
- [x] Custom event tracing: Example code logging messages returned from
`team.run_stream()`
- [ ] LLM span tracing .. depends on
https://github.com/microsoft/autogen/issues/5895
 - [ ] [TBD] Distributed tracing 

See
[tracing.ipynb](bdb6ac5315/python/packages/autogen-core/docs/src/user-guide/agentchat-user-guide/tracing.ipynb)
here

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

#5992

## Open Questions

@ekzu 
- What is the recommended way to directly log custom events like
LLMCallEvents and ToolCallEvents? LogEventhandlers in user code that
become traced spans?
- Currenltly tool calls and their args are already logged (not sure
where this is done), but LLM call events are not. Should we include
samples on this?

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-22 00:09:19 -07:00
cheng-tan 6f784ac186
[Accessibility] Fix: screen reader does not announce theme change and nested nav label (#6061)
## Why are these changes needed?
fix the accessibility issue that screen reader doesn't announce the
theme when it changes

## Related issue number
#5631 (13) (31) (59)

---------

Co-authored-by: peterychang <49209570+peterychang@users.noreply.github.com>
2025-03-21 18:36:56 -04:00
Eric Zhu 26364e3dfb
doc: Improve documentation around model client and tool and how it works under the hood (#6050)
Address some confusion such as #6036

---------

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-21 15:01:47 -07:00
湛露先生 97ccc582fc
Fix some code for clean autogenstudio (#5981)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-21 14:35:56 -07:00
afourney eaef7bab7c
Allow Docker-out-of-docker in AGBench (#6047)
This PR allows docker-out-of-docker scenarios to be run in agbench
(e.g., agent teams that rely on the DockerCommandLineExecutor)

This is becoming increasingly important for benchmarking and testing,
since the behaviors of running local executors can diverge in important
ways.
2025-03-21 12:55:00 -07:00
cheng-tan ff847cccad
[Accessibility] fix screen reader is not announcing 'Copied' information (#6059)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?
<!-- Please give a short summary of the change and the problem this
solves. -->
If user tab to a code block copy button then hit enter, screen reader
doesn't announce "Copied". This PR fixed this bug.


## Related issue number
#5631 (8)
<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-21 13:17:29 -04:00
Stuart Leeks 9a536e5d2b
Update migration guide type name (#5978)
Update AzureContainerCodeExecutor to ACADynamicSessionsCodeExecutor to
match the type name in the target docs
2025-03-21 02:52:25 +00:00
Luke Singham 3705ecb9d7
Improve grammar of README.md (#5999)
Minor improvements to the grammar of the README. 

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-21 02:46:22 +00:00
WuYunlong 334209f825
Correct README command examples for chess game sample. (#6008)
Fix outdated script references from chess_game.py to main.py
2025-03-21 02:30:30 +00:00
peterychang 8f58e4704f
Add alt text for clickable cards on website (#6043)
## Why are these changes needed?

Fixes (53) on screen reader issues. A special thanks to @sjay8 for
starting the work on this task

## Related issue number

https://github.com/microsoft/autogen/issues/5631
2025-03-21 00:29:24 +00:00
peterychang a21a60b4f3
add alt text to images (#6045)
Adds alt text to images. fixes screen reader issue (41)

## Related issue number

https://github.com/microsoft/autogen/issues/5631
2025-03-20 17:23:35 -07:00
gagb 878aa4c3fc
Add linter to AGBench (#6022)
This pull request introduces a new linting feature to the benchmark
configuration in the `agbench` package. The main changes include adding
a new command to the CLI, implementing the linter functionality, and
integrating it with the existing codebase.

### New Linting Feature:

*
[`python/packages/agbench/src/agbench/cli.py`](diffhunk://#diff-0eafed70ad5e99e6f7319927bf92ee3ce4787d156dd2775b10a61baad7ec1799R10):
Added `lint_cli` import and integrated the new "lint" command into the
`main` function.
[[1]](diffhunk://#diff-0eafed70ad5e99e6f7319927bf92ee3ce4787d156dd2775b10a61baad7ec1799R10)
[[2]](diffhunk://#diff-0eafed70ad5e99e6f7319927bf92ee3ce4787d156dd2775b10a61baad7ec1799R37-R41)

### Linter Implementation:

*
[`python/packages/agbench/src/agbench/linter/__init__.py`](diffhunk://#diff-45842e728e3daad063b3cf84d5857a4fdfe14e6d977fb2054f284eb9f5bb5272R1-R4):
Added necessary imports to initialize the linter module.
*
[`python/packages/agbench/src/agbench/linter/_base.py`](diffhunk://#diff-f7ea2f6706232406b6c727fda6d71f09c568b4573f070af79bb7f3da3514e364R1-R81):
Defined core classes such as `Document`, `Code`, `CodeExample`,
`CodedDocument`, and the `BaseQualitativeCoder` protocol.
*
[`python/packages/agbench/src/agbench/linter/cli.py`](diffhunk://#diff-e6ad1e14dc0df2c10fe62fede5a06d83865ad1961f99ec2d78f9052feb4d663bR1-R86):
Implemented the `lint_cli` function, which includes loading log files,
coding them, and printing the results.
*
[`python/packages/agbench/src/agbench/linter/coders/oai_coder.py`](diffhunk://#diff-5059129410822c8a214f797a6167cbfcfbe31bd6a3b1efcb65a2dd703ef9b331R1-R212):
Implemented the `OAIQualitativeCoder` class to interact with OpenAI for
coding documents and caching results.

Example usage:

<img width="997" alt="image"
src="https://github.com/user-attachments/assets/6718688e-9917-4a43-a2f1-1105b030528d"
/>


<img width="999" alt="image"
src="https://github.com/user-attachments/assets/7fcb9c43-70f2-4fe7-ae29-5ad6a4ef2a16"
/>

> If you are in VSCode Terminal, you can click on the links in the
terminal output to jump to the exact error.

---------

Co-authored-by: afourney <adamfo@microsoft.com>
2025-03-20 19:05:42 +00:00
Hussein Mozannar fef953e062
Fix bytes in markdown converter playwright (#6044)
Fix error:

TypeError: Input stream must be opened in bytes mode, not in text mode.

Markdown converter takes binary stream
2025-03-20 11:53:53 -07:00
Eric Zhu 46add11ec7
Move start() and stop() as interface methods for CodeExecutor (#6040)
Resolves #6015
2025-03-20 10:00:52 -07:00
peterychang 989d99dabe
Announce current page on sidebar links, version (#5986)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Fixes Screen Reader issue (58)

## Related issue number

https://github.com/microsoft/autogen/issues/5631

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-03-20 15:49:11 +00:00
afourney ecdb74b1ef
Limit what files and folders FileSurfer can access. (#6024)
Optionally limit what files and folders FileSurfer can access
(constraining it to a subtree of the FS).

This is not a replacement for Docker sandboxing, but can be used in
conjunction with sandboxing to help prevent FileSurfer from accessing
sensitive files.
2025-03-20 08:35:09 -07:00
Federico Villa 262c74fd41
Properly close model clients in documentation and samples (#5898)
Closes #5873
---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-20 07:50:14 +00:00
EdwinInnovation 3498c3ccda
Fix issue #5946: changed code for ACASessionsExecutor _ensure_access_token to be https:/ /dynamicsessions.io/.default (#6001)
## Why are these changes needed?

when I want to create a ACASessionsExecutor instance and execute some
code, the default library imported does not work. It always returns:
"ClientAuthenticationError: Authentication failed: AADSTS70011: The
provided request must include a 'scope' input parameter. The provided
value for the input parameter 'scope' is not valid. The scope
https://dynamicsessions.io/ is not valid. Trace ID:
d75efa58-8be7-44ef-8839-aacfdc850600 Correlation ID:
a8e4d859-92da-4fbe-a8e0-05116323ab55 Timestamp: 2025-03-14 14:15:09Z"

After changing the scope in _ensure_access_token to be
"https://dynamicsessions.io/.default" rather than
""https://dynamicsessions.io/" and it worked.

## Related issue number

 issue #5946

## Checks

- [Y ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ Y] I've made sure all auto checks have passed.

Co-authored-by: edwinwu <edwin@Edwin-MBA.local>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-20 07:26:14 +00:00
Eric Zhu 9103359ef4
add cancellation support to docker executor (#6027)
Resolves #6013
2025-03-19 21:29:01 -07:00
Eric Zhu 855bcd711c
Add API doc for save_state and load_state for SingleThreadedAgentRuntime (#5984)
Resolves #4108
2025-03-19 21:07:30 +00:00
湛露先生 8f42e5a27f
redundancy package delete. (#5976)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

Signed-off-by: zhanluxianshen <zhanluxianshen@163.com>
Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-03-19 20:46:51 +00:00
Eric Zhu 69292e6ff4
Update mimum openai version to 1.66.5 as import path changed (#5996)
Resolves #5994

Open AI moved `openai.types.beta.vector_store` to
`openai.types.vector_store`.
https://github.com/openai/openai-python/compare/v1.65.5...v1.66.0

Also fixed unit tests and use parameterized fixture to run all
scenarios.
2025-03-19 05:20:04 +00:00
Zachary Huang d83927e22a
fix AssistantAgent polymorphism bug (#5967)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Resolve #5953 

## Related issue number
#5953 

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

I have run all [common
tasks](https://github.com/microsoft/autogen/blob/main/python/README.md#common-tasks),
got below errors which I think it is due to no OpenAI API Key is in my
environment variables. Can we ignore them or do I need to buy one?
```
=================================================== short test summary info =================================================== 
ERROR tests/test_db_manager.py::TestDatabaseOperations::test_basic_entity_creation - openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_...
ERROR tests/test_db_manager.py::TestDatabaseOperations::test_upsert_operations - openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_...
ERROR tests/test_db_manager.py::TestDatabaseOperations::test_delete_operations - openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_...
ERROR tests/test_team_manager.py::TestTeamManager::test_load_from_file - openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_...
ERROR tests/test_team_manager.py::TestTeamManager::test_load_from_directory - openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_...
ERROR tests/test_team_manager.py::TestTeamManager::test_create_team - openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_...
ERROR tests/test_team_manager.py::TestTeamManager::test_run_stream - openai.OpenAIError: The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_...
=========================================== 3 passed, 5 warnings, 7 errors in 9.07s ===========================================
```

Co-authored-by: Leonardo Pinheiro <leosantospinheiro@gmail.com>
2025-03-19 14:38:36 +10:00
Jacob Alber a2ab0e36d6
ci: Remove --locked from uv sync in Integration test project (#5993)
For some reason --locked is causing the CI to fall over in the codesign
pipeline.

Unclear why it is not happening on the GitHub Actions side - though it
may be an artifact of the way we have the uv cache set up (and the uv
install version does not match between the two). Getting to a building
state, then will investigate further.
2025-03-18 16:34:44 -04:00
Eric Zhu a8cef327f1
Support json schema for response format type in OpenAIChatCompletionClient (#5988)
Resolves #5982

This PR adds support for `json_schema` as a `response_format` type in
`OpenAIChatCompletionClient`. This is necessary because it allows the
client to be serialized along with the schema. If user use
`response_format=SomeBaseModel`, the client cannot be serialized.

Usage:

```python
# Structured output response, with a pre-defined JSON schema.

OpenAIChatCompletionClient(...,
response_format = {
    "type": "json_schema",
    "json_schema": {
        "name": "name of the schema, must be an identifier.",
        "description": "description for the model.",
        # You can convert a Pydantic (v2) model to JSON schema
        # using the `model_json_schema()` method.
        "schema": "<the JSON schema itself>",
        # Whether to enable strict schema adherence when
        # generating the output. If set to true, the model will
        # always follow the exact schema defined in the
        # `schema` field. Only a subset of JSON Schema is
        # supported when `strict` is `true`.
        # To learn more, read
        # https://platform.openai.com/docs/guides/structured-outputs.
        "strict": False,  # or True
    },
},
)
````
2025-03-18 03:14:42 +00:00
Federico Villa 09d8d344a2
Filter invalid parameters in Ollama client requests (#5983)
Remove unrecognized parameters in Ollama API calls.
---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-17 21:09:26 +00:00
Abhijeetsingh Meena c4e07e86d8
Implement 'candidate_func' parameter to filter down the pool of candidates for selection (#5954)
## Summary of Changes
- Added 'candidate_func' to 'SelectorGroupChat' to narrow-down the pool
of candidate speakers.
- Introduced a test in tests/test_group_chat_endpoint.py to validate its
functionality.
- Updated the selector group chat user guide with an example
demonstrating 'candidate_func'.

## Why are these changes needed?
- These changes adds a new parameter `candidate_func` to
`SelectorGroupChat` that helps user narrow-down the set of agents for
speaker selection, allowing users to automatically select next speaker
from a smaller pool of agents.

## Related issue number
Closes #5828

## Checks
- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Signed-off-by: Abhijeetsingh Meena <abhijeet040403@gmail.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-17 21:03:25 +00:00
Victor Dibia 8f8ee0478a
AGS - Test Model Component in UI, Compare Sessions (#5963)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

- Adds ability to test model clients in UI after configrations, before
they are used in agents or teams
- Adds UI side by side comparison of sessions
<img width="1878" alt="image"
src="https://github.com/user-attachments/assets/f792d8d6-3f5d-4d8c-a365-5a9e9c00f49e"
/>
<img width="1877" alt="image"
src="https://github.com/user-attachments/assets/5a115a5a-95e1-4956-a733-5f0065711fe3"
/>


<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #4273 
Closes #5728

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-17 11:00:46 -07:00
ZakWork 685142cf51
Fix R1 reasoning parser for openai client (#5961)
R1 reasoning tokens from hosted R1 model were not parsed correctly for the openai client

Resolves #5941

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-17 10:09:41 -07:00
afourney e5ab7d55cf
Some pandas series were not being handled correctly (#5972) 2025-03-17 07:16:18 +00:00
afourney 22b68b96b6
Added a flag to agbench to enable Azure identity. (#5977) 2025-03-17 00:10:44 -07:00
Eric Zhu 483532180a
Improvements to agbench (#5776)
1. Add host network support in Docker and remove unused requirements
from argument check.
2. Use Pandas to simplify summary statistic calculations. 
3. Add running time to summary statistics

```
Using tabulation method defined in '/home/ekzhu/autogen/python/packages/agbench/benchmarks/HumanEval/Scripts/custom_tabulate.py'

    Task Id       Trial 0 Success      Trial 0 Time
--  ------------  -----------------  --------------
 0  HumanEval_0   True                            3
 1  HumanEval_1   False                          15
 2  HumanEval_2   True                            2
 3  HumanEval_3   True                           11
 4  HumanEval_4   True                            4
 5  HumanEval_5   True                            2
 6  HumanEval_6   False                          18
 7  HumanEval_7   True                            2
 8  HumanEval_8   True                            2
 9  HumanEval_9   True                           12
10  HumanEval_10  False                          11
11  HumanEval_11  True                            2
12  HumanEval_12  True                            3
13  HumanEval_13  True                            1
14  HumanEval_14  True                            4
15  HumanEval_15  True                            1
16  HumanEval_16  True                            2
17  HumanEval_17  False                          76
18  HumanEval_18  True                            4
19  HumanEval_19  True                            3
20  HumanEval_20  True                            5
21  HumanEval_21  True                            3
22  HumanEval_22  True                            1
23  HumanEval_23  True                            2
24  HumanEval_24                                nan

Summary Statistics

           Successes    Failures    Missing    Total    Average Success Rate    Average Time    Total Time
-------  -----------  ----------  ---------  -------  ----------------------  --------------  ------------
Trial 0           20           4          1       25                     0.8           7.875           189

CAUTION: 'autogenbench tabulate' is in early preview and is not thoroughly tested.
Please do not cite values from these calculations in academic work without first inspecting and verifying the results in the run logs yourself.

```

Now the default tabulate output looks like this

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-03-16 09:13:12 -07:00
Eric Zhu aba41d74d3
feat: add structured output to model clients (#5936) 2025-03-15 07:58:13 -07:00
Eric Zhu 9bde5ef911
Improve docs for model clients (#5952)
Address questions related to logging of model client calls and reduce
redundant docs.
2025-03-15 02:28:15 +00:00
Victor Dibia fe1feb3906
Enable Auth in AGS (#5928)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?


https://github.com/user-attachments/assets/b649053b-c377-40c7-aa51-ee64af766fc2

<img width="100%" alt="image"
src="https://github.com/user-attachments/assets/03ba1df5-c9a2-4734-b6a2-0eb97ec0b0e0"
/>


## Authentication

This PR implements an experimental authentication feature to enable
personalized experiences (multiple users). Currently, only GitHub
authentication is supported. You can extend the base authentication
class to add support for other authentication methods.

By default authenticatio is disabled and only enabled when you pass in
the `--auth-config` argument when running the application.

### Enable GitHub Authentication

To enable GitHub authentication, create a `auth.yaml` file in your app
directory:

```yaml
type: github
jwt_secret: "your-secret-key"
token_expiry_minutes: 60
github:
  client_id: "your-github-client-id"
  client_secret: "your-github-client-secret"
  callback_url: "http://localhost:8081/api/auth/callback"
  scopes: ["user:email"]
```

Please see the documentation on [GitHub
OAuth](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authenticating-to-the-rest-api-with-an-oauth-app)
for more details on obtaining the `client_id` and `client_secret`.

To pass in this configuration you can use the `--auth-config` argument
when running the application:

```bash
autogenstudio ui --auth-config /path/to/auth.yaml
```

Or set the environment variable:

```bash
export AUTOGENSTUDIO_AUTH_CONFIG="/path/to/auth.yaml"
```

```{note}
- Authentication is currently experimental and may change in future releases
- User data is stored in your configured database
- When enabled, all API endpoints require authentication except for the authentication endpoints
- WebSocket connections require the token to be passed as a query parameter (`?token=your-jwt-token`)

```

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #4350  

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2025-03-14 15:02:05 -07:00
Eric Zhu 5f9e37dc27
Upgrade llama cpp to 0.3.8 to fix windows related error (#5948)
use the latest version of llama-cpp-python to ensure `uv sync
--all-extras` don't fail on windows.

reference:
https://github.com/microsoft/autogen/pull/5942#issuecomment-2724478534
2025-03-14 12:20:42 -07:00
Nissa Seru 0276aac8fb
Fix `poe check` on Windows (#5942)
`poe check` fails on main on Windows due to a combination line ending
mismatches, Unix-specific commands, and Windows-specific `asyncio`
behavior. This PR attempts to fix this (so that `poe check` on a
freshly-pulled `main` passes on Windows 11.)
2025-03-14 11:44:38 -07:00
Victor Dibia b8b7a2db3a
Ensure SecretStr is cast to str on load for model clients (#5947)
Currently we have SecretStr type for model clients to promote security
best practices.

- when we dump_component, keys are serialized  as SecreteStr ..
- when we load_component ... SecreteStr type is passed to the client in
the api_key field. This i causes the type problems as the clients expect
a string type.

This PR updates the from_config method for model clients to ensure we
get the value from SecretStr.

Closes #5944
2025-03-14 10:15:21 -07:00
Victor Dibia 296de5253a
Update AgentChat Docs for RAGAgent / Teachability (#5935)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?
<img width="1151" alt="image"
src="https://github.com/user-attachments/assets/98bc91ee-749c-4831-b36f-10322979883b"
/>
 
- Update migration guide to cover teachability/rag agents (mention how
similar functionality can be accomplished with AssistantAgent + Memory)
- Update memory docs to explicitly add a text chunking example and a rag
agent

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5772 
Closes #4742

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-13 21:57:47 -07:00
Eric Zhu a4b6372813
Use SecretStr type for api key (#5939)
To prevent accidental export of API keys
2025-03-13 21:29:19 -07:00
afourney 84c622a4cc
Fixes an error that can occur when listing the contents of a directory. (#5938)
Fixes issues like the following trace:

```
packages/autogen_ext/agents/file_surfer/_markdown_file_browser.py", line 39, in __init__
    self.set_path(self._base_path)
  File "/home/hmozannar/webby/.venv/lib/python3.12/site-packages/autogen_ext/agents/file_surfer/_markdown_file_browser.py", line 67, in set_path
    self._open_path(path)
  File "/home/hmozannar/webby/.venv/lib/python3.12/site-packages/autogen_ext/agents/file_surfer/_markdown_file_browser.py", line 210, in _open_path
    io.StringIO(self._fetch_local_dir(path)), file_extension=".txt"
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/hmozannar/webby/.venv/lib/python3.12/site-packages/autogen_ext/agents/file_surfer/_markdown_file_browser.py", line 248, in _fetch_local_dir
    mtime = datetime.datetime.fromtimestamp(os.path.getmtime(full_path)).strftime("%Y-%m-%d %H:%M")
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen genericpath>", line 67, in getmtime
PermissionError: [Errno 13] Permission denied: '/home/hmozannar/webby/autogen-studio/frontend/readme.txt'
```
2025-03-13 20:40:30 -07:00
Napat Gun R. fc6fb4ea15
fix: revert to python:3.10-slim base image for AutoGen Studio (#5932)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

This reverts the base image in AutoGen Studio Dockerfile to `FROM
python:3.10-slim`. This fixes the Docker image build failure due to
conflicting UID with Dev Container's `vscode` user.

## Related issue number

Fixes #5929

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-13 16:08:18 -07:00
dependabot[bot] 3b1ed78c64
Bump @babel/helpers from 7.26.9 to 7.26.10 in /python/packages/autogen-studio/frontend (#5905)
Bumps
[@babel/helpers](https://github.com/babel/babel/tree/HEAD/packages/babel-helpers)
from 7.26.9 to 7.26.10.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/babel/babel/releases"><code>@​babel/helpers</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v7.26.10 (2025-03-11)</h2>
<p>Thanks <a
href="https://github.com/jordan-choi"><code>@​jordan-choi</code></a> and
<a
href="https://github.com/mmmsssttt404"><code>@​mmmsssttt404</code></a>
for your first PRs!</p>
<p>This release includes a fix for <a
href="https://github.com/babel/babel/security/advisories/GHSA-968p-4wvh-cqc8">https://github.com/babel/babel/security/advisories/GHSA-968p-4wvh-cqc8</a>,
a security vulnerability which affects the <code>.replace</code> method
of transpiled regular expressions that use named capturing groups.</p>
<h4>👓 Spec Compliance</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17159">#17159</a>
Disallow decorator in array pattern (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-parser</code>, <code>babel-template</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17164">#17164</a>
Fix: always initialize ExportDeclaration attributes (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17142">#17142</a>
fix: &quot;Map maximum size exceeded&quot; in deepClone (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-parser</code>,
<code>babel-plugin-transform-typescript</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17154">#17154</a>
Update typescript parser tests (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-traverse</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17151">#17151</a>
fix: Should not evaluate vars in child scope (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17153">#17153</a>
fix: Correctly generate <code>abstract override</code> (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17107">#17107</a> Fix
source type detection when parsing TypeScript (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-helpers</code>, <code>babel-runtime</code>,
<code>babel-runtime-corejs2</code>, <code>babel-runtime-corejs3</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17173">#17173</a> Fix
processing of replacement pattern with named capture groups (<a
href="https://github.com/%5Bmmmsssttt404%5D(https://github.com/mmmsssttt404)"><code>@​mmmsssttt404</code></a>)</li>
</ul>
</li>
</ul>
<h4>💅 Polish</h4>
<ul>
<li><code>babel-standalone</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17158">#17158</a>
Avoid warnings when re-bundling <code>@​babel/standalone</code> with
webpack (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
</ul>
<h4>🏠 Internal</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17160">#17160</a>
Left-value parsing cleanup (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 6</h4>
<ul>
<li>Babel Bot (<a
href="https://github.com/babel-bot"><code>@​babel-bot</code></a>)</li>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
<li>Nicolò Ribaudo (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
<li>Yunyoung Jordan Choi (<a
href="https://github.com/jordan-choi"><code>@​jordan-choi</code></a>)</li>
<li><a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a></li>
<li><a
href="https://github.com/mmmsssttt404"><code>@​mmmsssttt404</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/babel/babel/blob/main/CHANGELOG.md"><code>@​babel/helpers</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>v7.26.10 (2025-03-11)</h2>
<h4>👓 Spec Compliance</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17159">#17159</a>
Disallow decorator in array pattern (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-parser</code>, <code>babel-template</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17164">#17164</a>
Fix: always initialize ExportDeclaration attributes (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17142">#17142</a>
fix: &quot;Map maximum size exceeded&quot; in deepClone (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-parser</code>,
<code>babel-plugin-transform-typescript</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17154">#17154</a>
Update typescript parser tests (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-traverse</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17151">#17151</a>
fix: Should not evaluate vars in child scope (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17153">#17153</a>
fix: Correctly generate <code>abstract override</code> (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17107">#17107</a> Fix
source type detection when parsing TypeScript (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-helpers</code>, <code>babel-runtime</code>,
<code>babel-runtime-corejs2</code>, <code>babel-runtime-corejs3</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17173">#17173</a> Fix
processing of replacement pattern with named capture groups (<a
href="https://github.com/%5Bmmmsssttt404%5D(https://github.com/mmmsssttt404)"><code>@​mmmsssttt404</code></a>)</li>
</ul>
</li>
</ul>
<h4>💅 Polish</h4>
<ul>
<li><code>babel-standalone</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17158">#17158</a>
Avoid warnings when re-bundling <code>@​babel/standalone</code> with
webpack (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
</ul>
<h4>🏠 Internal</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17160">#17160</a>
Left-value parsing cleanup (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e1ce99df42"><code>e1ce99d</code></a>
v7.26.10</li>
<li><a
href="d5952e80c0"><code>d5952e8</code></a>
Fix processing of replacement pattern with named capture groups (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-helpers/issues/17173">#17173</a>)</li>
<li>See full diff in <a
href="https://github.com/babel/babel/commits/v7.26.10/packages/babel-helpers">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@babel/helpers&package-manager=npm_and_yarn&previous-version=7.26.9&new-version=7.26.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/microsoft/autogen/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-13 22:16:39 +00:00
dependabot[bot] 6bf22ea1df
Bump @babel/runtime from 7.26.9 to 7.26.10 in /python/packages/autogen-studio/frontend (#5904)
Bumps
[@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime)
from 7.26.9 to 7.26.10.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/babel/babel/releases"><code>@​babel/runtime</code>'s
releases</a>.</em></p>
<blockquote>
<h2>v7.26.10 (2025-03-11)</h2>
<p>Thanks <a
href="https://github.com/jordan-choi"><code>@​jordan-choi</code></a> and
<a
href="https://github.com/mmmsssttt404"><code>@​mmmsssttt404</code></a>
for your first PRs!</p>
<p>This release includes a fix for <a
href="https://github.com/babel/babel/security/advisories/GHSA-968p-4wvh-cqc8">https://github.com/babel/babel/security/advisories/GHSA-968p-4wvh-cqc8</a>,
a security vulnerability which affects the <code>.replace</code> method
of transpiled regular expressions that use named capturing groups.</p>
<h4>👓 Spec Compliance</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17159">#17159</a>
Disallow decorator in array pattern (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-parser</code>, <code>babel-template</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17164">#17164</a>
Fix: always initialize ExportDeclaration attributes (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17142">#17142</a>
fix: &quot;Map maximum size exceeded&quot; in deepClone (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-parser</code>,
<code>babel-plugin-transform-typescript</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17154">#17154</a>
Update typescript parser tests (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-traverse</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17151">#17151</a>
fix: Should not evaluate vars in child scope (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17153">#17153</a>
fix: Correctly generate <code>abstract override</code> (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17107">#17107</a> Fix
source type detection when parsing TypeScript (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-helpers</code>, <code>babel-runtime</code>,
<code>babel-runtime-corejs2</code>, <code>babel-runtime-corejs3</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17173">#17173</a> Fix
processing of replacement pattern with named capture groups (<a
href="https://github.com/%5Bmmmsssttt404%5D(https://github.com/mmmsssttt404)"><code>@​mmmsssttt404</code></a>)</li>
</ul>
</li>
</ul>
<h4>💅 Polish</h4>
<ul>
<li><code>babel-standalone</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17158">#17158</a>
Avoid warnings when re-bundling <code>@​babel/standalone</code> with
webpack (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
</ul>
<h4>🏠 Internal</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17160">#17160</a>
Left-value parsing cleanup (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 6</h4>
<ul>
<li>Babel Bot (<a
href="https://github.com/babel-bot"><code>@​babel-bot</code></a>)</li>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
<li>Nicolò Ribaudo (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
<li>Yunyoung Jordan Choi (<a
href="https://github.com/jordan-choi"><code>@​jordan-choi</code></a>)</li>
<li><a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a></li>
<li><a
href="https://github.com/mmmsssttt404"><code>@​mmmsssttt404</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/babel/babel/blob/main/CHANGELOG.md"><code>@​babel/runtime</code>'s
changelog</a>.</em></p>
<blockquote>
<h2>v7.26.10 (2025-03-11)</h2>
<h4>👓 Spec Compliance</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17159">#17159</a>
Disallow decorator in array pattern (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>🐛 Bug Fix</h4>
<ul>
<li><code>babel-parser</code>, <code>babel-template</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17164">#17164</a>
Fix: always initialize ExportDeclaration attributes (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17142">#17142</a>
fix: &quot;Map maximum size exceeded&quot; in deepClone (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-parser</code>,
<code>babel-plugin-transform-typescript</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17154">#17154</a>
Update typescript parser tests (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-traverse</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17151">#17151</a>
fix: Should not evaluate vars in child scope (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17153">#17153</a>
fix: Correctly generate <code>abstract override</code> (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17107">#17107</a> Fix
source type detection when parsing TypeScript (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-helpers</code>, <code>babel-runtime</code>,
<code>babel-runtime-corejs2</code>, <code>babel-runtime-corejs3</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17173">#17173</a> Fix
processing of replacement pattern with named capture groups (<a
href="https://github.com/%5Bmmmsssttt404%5D(https://github.com/mmmsssttt404)"><code>@​mmmsssttt404</code></a>)</li>
</ul>
</li>
</ul>
<h4>💅 Polish</h4>
<ul>
<li><code>babel-standalone</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17158">#17158</a>
Avoid warnings when re-bundling <code>@​babel/standalone</code> with
webpack (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
</ul>
<h4>🏠 Internal</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17160">#17160</a>
Left-value parsing cleanup (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e1ce99df42"><code>e1ce99d</code></a>
v7.26.10</li>
<li><a
href="d5952e80c0"><code>d5952e8</code></a>
Fix processing of replacement pattern with named capture groups (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-runtime/issues/17173">#17173</a>)</li>
<li>See full diff in <a
href="https://github.com/babel/babel/commits/v7.26.10/packages/babel-runtime">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@babel/runtime&package-manager=npm_and_yarn&previous-version=7.26.9&new-version=7.26.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/microsoft/autogen/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-13 22:10:10 +00:00
Victor Dibia 87707bca37
Improve AgentChat Teams Doc (#5930)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

![image](https://github.com/user-attachments/assets/73735a47-f3a6-44f6-8e9d-3a5632c8a80f)


## Why are these changes needed?

The [agentchat teams
docs](https://microsoft.github.io/autogen/dev/user-guide/agentchat-user-guide/tutorial/teams.html)
page did not list out the teams currently supported. This is confusing
for readers/uisers as they have to search around to discover that
selector groupchat, swarm and magentic one are available.

This PR adds a list of supported teams to the top of the teams page and
links to the relevant tutorials.

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-13 21:58:16 +00:00
Yusuf Kaka f1e615321e
Update memory.ipynb - fixed typo chroma_user_memory (#5901)
Fixed a typo, chroma_user_memory instead of user_memory

## Why are these changes needed?

There's a confusing typo in the documentation.

## Related issue number

None

## Checks

- [x ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x ] I've made sure all auto checks have passed.

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-13 21:49:18 +00:00
Eric Zhu 3a1108a575
fix: make sure system message is present in reflection call (#5926)
Resolves #5919
2025-03-13 21:29:46 +00:00
Jacob Alber 41e7e85c40
fix: Improve PublishMessageAsync resilience (#5923)
During the recent fix to SendMessageAsync's recurrence, we added code to ensure blocking on Publish. This adds additional resilience to the Publish delivery, ensuring that every subscribed agent receives the message, regardless of errors in the middle.
2025-03-13 16:53:21 -04:00
Jacob Alber 52346fdb78
ci: Add missing Code Coverage assemblies to M.AG.* tests (#5925)
* Also adds --locked to the `uv sync` call in the Integration Tests project; this will hopefully reduce how much the uv.lock file is mangled during .NET development
2025-03-13 15:56:41 -04:00
Nissa Seru 6ae098fe49
bugfix: Workaround for pydantic/#7713 (#5893)
Use of `SKChatCompletionAdapter` reliably fails with "'MockValSer'
object cannot be converted to 'SchemaSerializer'"; can repro with this
example:
https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/components/model-clients.html#semantic-kernel-adapter

This appears to be related to
https://github.com/pydantic/pydantic/issues/7713 - commit uses
workaround from
https://github.com/pydantic/pydantic/issues/7713#issuecomment-2604574418

## Why are these changes needed?

This unblocks use of the Semantic Kernel integration by addressing the
above-referenced error, enabling the integration to perform as expected.

## Related issue number

N/A, see https://github.com/pydantic/pydantic/issues/7713 for context,
though.

## Checks

- [X] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
 - None needed, internal only change.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- None added; this works on my machine, but I'm not clear on the root
cause of the issue and have no strong opinion on whether this is the
ideal way to fix it long term - simply leaning towards PR`ing a tenative
fix instead of raising an issue.
- [ ] I've made sure all auto checks have passed.
 - I am not familiar with these, but assume they will be run during CI.

---------

Co-authored-by: Leonardo Pinheiro <leosantospinheiro@gmail.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-13 18:23:01 +00:00
Jacob Alber cf1365763c
feat: Implement AgentChat.NET Termination Conditions (#5839)
Closes #5801
2025-03-13 12:41:13 -04:00
afourney aefa66a3ce
Update MarkItDown. (#5920)
Update FileSurfer and WebSurfer to use the latest MarkItDown package.
2025-03-12 21:17:25 -07:00
Eric Zhu 4d8b97eed1
Fix logging error with ollama client (#5917)
Resolves #5910

Co-authored-by: peterychang <49209570+peterychang@users.noreply.github.com>
2025-03-12 16:59:43 -04:00
Griffin Bassman 8199a2c0a1
feat: [dotnet] open control channel for grpc save/load (#5489)
Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-03-12 15:18:32 -04:00
Jacob Alber 0a988b6393
fix: Recurrent SendMessageAsync deadlock in message handler (#5916)
In the .NET InProcessRuntime we tried to minimize the amount of tasks
created. Unfortunately, this results in a deadlock when a send message
handler is attempting to SendMessage during the handling of the incoming
message.

The fix is to create a new task for delivering the message in the
message processing loop, which creates a new logical stack to run the
delivery, freeing the loop to process the next delivery request.

* Also fixes passing exceptions and cancellations back to the waiting
task.
* Also fixes a build slowdown on Windows due to uv and llama-cpp

Closes #5915
2025-03-12 14:58:07 -04:00
Eric Zhu 712aba6b4e
update ref for v0.4.9 website (#5914)
Needed to fix the homepage display.
2025-03-12 09:00:48 -07:00
peterychang 90332e371b
Revert Allow Voice Access to find clickable cards commit (#5911)
Reverts https://github.com/microsoft/autogen/pull/5857 due to weird
interaction with non-clickable cards
2025-03-12 08:52:13 -07:00
Eric Zhu 2573739111
update website for v0.4.9 (#5906) 2025-03-12 00:05:57 -07:00
Eric Zhu bb8439c7bd
update version to v0.4.9 (#5903) 2025-03-11 19:35:22 -07:00
Eric Zhu 58a5583549
feat: Pause and Resume for AgentChat Teams and Agents (#5887)
1. Add `on_pause` and `on_resume` API to `ChatAgent` to support pausing
behavior when running `on_message` concurrently.
2. Add `GroupChatPause` and `GroupChatResume` RPC events and handle them
in `ChatAgentContainer`.
3. Add `pause` and `resume` API to `BaseGroupChat` to allow for this
behavior accessible from the public API.
4. Improve `SequentialRoutedAgent` class to customize which message
types are sequentially handled, making it possible to have concurrent
handling for some messages (e.g., `GroupChatPause`).
5. Added unit tests. 

See `test_group_chat_pause_resume.py` for how to use this feature. 

What is the difference between pause/resume vs. termination and restart?
- Pause and resume issue direct RPC calls to the participanting agents
of a team while they are running, allowing putting the on-going
generation or actions on hold. This is useful when an agent's turn takes
a long time and multiple steps to complete, and user/application wants
to re-evaluate whether it is worth continue the step or cancel. This
also allows user/application to pause individual agents and resuming
them independently from the team API.
- Termination and restart requires the whole team to comes to a
full-stop, and termination conditions are checked in between agents'
turns. So termination can only happen when no agent is working on its
turn. It is possible that a termination condition has reached well
before the team is terminated, if the agent is taking a long time to
generate a response.

Resolves: #5881
2025-03-11 17:12:34 -07:00
Eitan Yarmush 8fb9ca3a3e
Allow for tracing via context provider (#5889)
These changes allow for 2 important use-cases:
1. Add a span for tool calls which will enable tracing of all tool calls
in agent_chat
2. Allow runtimes to pick up global `tracer_providers` if they are
available. This is very helpful because it allows for nested teams/agent
to all use the same tracer.
---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-11 16:33:39 -07:00
Eitan Yarmush 817f728d04
add LLMStreamStartEvent and LLMStreamEndEvent (#5890)
These changes are needed because there is currently no way to get
logging information about Streaming LLM requests/responses.

I decided to put the StreamStart event AFTER the first chunk so there
aren't false positives about connections/auth.

Closes #5730
---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-11 15:02:46 -07:00
Victor Dibia 2cc8c73d3b
Fix termination UI in AGS (#5888)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Fix termination UI in AGS, ensure it can be edited correctly

<img width="1269" alt="image"
src="https://github.com/user-attachments/assets/eaa7a92f-a1ea-4ab4-a679-2894ac441311"
/>
<img width="1273" alt="image"
src="https://github.com/user-attachments/assets/6db81068-932f-4d4e-9512-279770c02bf2"
/>
<img width="1270" alt="image"
src="https://github.com/user-attachments/assets/5ca9df7d-b968-46c9-9d62-becd78809273"
/>


<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #5872
## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-11 11:46:25 -07:00
Jacob Alber b4c1e5841f
feat: Save/Load for AgentChat.NET (#5841)
Partially addresses #5800, others pending the Agents PR #5837 and GroupChats PR #5838 coming in to have the classes to attach save/load logic to.
2025-03-11 12:35:03 -04:00
PythicCoder 6a3acc4548
Feature add Add LlamaCppChatCompletionClient and llama-cpp (#5326)
This pull request introduces the integration of the `llama-cpp` library
into the `autogen-ext` package, with significant changes to the project
dependencies and the implementation of a new chat completion client. The
most important changes include updating the project dependencies, adding
a new module for the `LlamaCppChatCompletionClient`, and implementing
the client with various functionalities.

### Project Dependencies:

*
[`python/packages/autogen-ext/pyproject.toml`](diffhunk://#diff-095119d4420ff09059557bd25681211d1772c2be0fbe0ff2d551a3726eff1b4bR34-R38):
Added `llama-cpp-python` as a new dependency under the `llama-cpp`
section.

### New Module:

*
[`python/packages/autogen-ext/src/autogen_ext/models/llama_cpp/__init__.py`](diffhunk://#diff-42ae3ba17d51ca917634c4ea3c5969cf930297c288a783f8d9c126f2accef71dR1-R8):
Introduced the `LlamaCppChatCompletionClient` class and handled import
errors with a descriptive message for missing dependencies.

### Implementation of `LlamaCppChatCompletionClient`:

*
`python/packages/autogen-ext/src/autogen_ext/models/llama_cpp/_llama_cpp_completion_client.py`:
- Added the `LlamaCppChatCompletionClient` class with methods to
initialize the client, create chat completions, detect and execute
tools, and handle streaming responses.
- Included detailed logging for debugging purposes and implemented
methods to count tokens, track usage, and provide model information.…d
chat capabilities

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [X ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [X ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ X] I've made sure all auto checks have passed.

---------

Co-authored-by: aribornstein <x@x.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-03-10 16:53:53 -07:00
Leonardo Pinheiro a1858efac9
feat: update local code executor to support powershell (#5884)
To support powershell on the local code executor.
Closes #5518
2025-03-10 14:00:14 -07:00
Hussein Mozannar 7d17b22925
Add an optional base path to FileSurfer (#5886)
This pull request introduces a new feature to the `FileSurfer` agent and
`MarkdownFileBrowser` by adding support for specifying a base path for
file browsing.

*
`python/packages/autogen-ext/src/autogen_ext/agents/file_surfer/_file_surfer.py`:
* Added `base_path` parameter to `FileSurfer` class and its
initialization method, with a default value of the current working
directory (`os.getcwd()`).
[[1]](diffhunk://#diff-084847b5e64c659c9aff0bd2d05bbcd0fff2c819a4b91bbe65fa0566054c0972R58)
[[2]](diffhunk://#diff-084847b5e64c659c9aff0bd2d05bbcd0fff2c819a4b91bbe65fa0566054c0972R80-R85)
* Updated `MarkdownFileBrowser` initialization within `FileSurfer` to
use the `base_path` parameter.

*
`python/packages/autogen-ext/src/autogen_ext/agents/file_surfer/_markdown_file_browser.py`:
* Added `base_path` parameter to `MarkdownFileBrowser` class and its
initialization method, with a default value of the current working
directory (`os.getcwd()`).
* Updated `MarkdownFileBrowser` to use the `base_path` for setting the
initial path and returning the current page path.
2025-03-09 20:33:18 -07:00
Eric Zhu 99eee0cd27
fix: save_state should not require the team to be stopped. (#5885)
Modify `BaseGroupChat.save_state` to not require the team to be stopped
first. The `save_state` method is read-only. While it may retrieve an
inconsistent state when the team is running, we made a notice to it's
API doc.

Resolves: #5880
2025-03-09 20:09:32 -07:00
Eric Zhu e32f419387
Fix span structure for tracing (#5853)
Resolves #5697
2025-03-08 22:28:11 -08:00
dependabot[bot] dce31cf0d9
Bump axios from 1.7.9 to 1.8.2 in /python/packages/autogen-studio/frontend (#5874)
Bumps [axios](https://github.com/axios/axios) from 1.7.9 to 1.8.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/releases">axios's
releases</a>.</em></p>
<blockquote>
<h2>Release v1.8.2</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>http-adapter:</strong> add allowAbsoluteUrls to path
building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)
(<a
href="fb8eec214c">fb8eec2</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/lexcorp16"
title="+1/-1 ([#6810](https://github.com/axios/axios/issues/6810)
)">Fasoro-Joseph Alexander</a></li>
</ul>
<h2>Release v1.8.1</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>utils:</strong> move <code>generateString</code> to platform
utils to avoid importing crypto module into client builds; (<a
href="https://redirect.github.com/axios/axios/issues/6789">#6789</a>)
(<a
href="36a5a620be">36a5a62</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+51/-47
([#6789](https://github.com/axios/axios/issues/6789) )">Dmitriy
Mozgovoy</a></li>
</ul>
<h2>Release v1.8.0</h2>
<h2>Release notes:</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>examples:</strong> application crashed when navigating
examples in browser (<a
href="https://redirect.github.com/axios/axios/issues/5938">#5938</a>)
(<a
href="1260ded634">1260ded</a>)</li>
<li>missing word in SUPPORT_QUESTION.yml (<a
href="https://redirect.github.com/axios/axios/issues/6757">#6757</a>)
(<a
href="1f890b13f2">1f890b1</a>)</li>
<li><strong>utils:</strong> replace getRandomValues with crypto module
(<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)
(<a
href="23a25af068">23a25af</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)
(<a
href="32c7bcc0f2">32c7bcc</a>)</li>
</ul>
<h3>Reverts</h3>
<ul>
<li>Revert &quot;chore: expose fromDataToStream to be consumable (<a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a>)&quot;
(<a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a>)
(<a
href="1317261125">1317261</a>),
closes <a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a> <a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a></li>
</ul>
<h3>BREAKING CHANGES</h3>
<ul>
<li>
<p>code relying on the above will now combine the URLs instead of prefer
request URL</p>
</li>
<li>
<p>feat: add config option for allowing absolute URLs</p>
</li>
<li>
<p>fix: add default value for allowAbsoluteUrls in buildFullPath</p>
</li>
<li>
<p>fix: typo in flow control when setting allowAbsoluteUrls</p>
</li>
</ul>
<h3>Contributors to this release</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/axios/axios/blob/v1.x/CHANGELOG.md">axios's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/axios/axios/compare/v1.8.1...v1.8.2">1.8.2</a>
(2025-03-07)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>http-adapter:</strong> add allowAbsoluteUrls to path
building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)
(<a
href="fb8eec214c">fb8eec2</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a href="https://github.com/lexcorp16"
title="+1/-1 ([#6810](https://github.com/axios/axios/issues/6810)
)">Fasoro-Joseph Alexander</a></li>
</ul>
<h2><a
href="https://github.com/axios/axios/compare/v1.8.0...v1.8.1">1.8.1</a>
(2025-02-26)</h2>
<h3>Bug Fixes</h3>
<ul>
<li><strong>utils:</strong> move <code>generateString</code> to platform
utils to avoid importing crypto module into client builds; (<a
href="https://redirect.github.com/axios/axios/issues/6789">#6789</a>)
(<a
href="36a5a620be">36a5a62</a>)</li>
</ul>
<h3>Contributors to this release</h3>
<ul>
<li><!-- raw HTML omitted --> <a
href="https://github.com/DigitalBrainJS" title="+51/-47
([#6789](https://github.com/axios/axios/issues/6789) )">Dmitriy
Mozgovoy</a></li>
</ul>
<h1><a
href="https://github.com/axios/axios/compare/v1.7.9...v1.8.0">1.8.0</a>
(2025-02-25)</h1>
<h3>Bug Fixes</h3>
<ul>
<li><strong>examples:</strong> application crashed when navigating
examples in browser (<a
href="https://redirect.github.com/axios/axios/issues/5938">#5938</a>)
(<a
href="1260ded634">1260ded</a>)</li>
<li>missing word in SUPPORT_QUESTION.yml (<a
href="https://redirect.github.com/axios/axios/issues/6757">#6757</a>)
(<a
href="1f890b13f2">1f890b1</a>)</li>
<li><strong>utils:</strong> replace getRandomValues with crypto module
(<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)
(<a
href="23a25af068">23a25af</a>)</li>
</ul>
<h3>Features</h3>
<ul>
<li>Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)
(<a
href="32c7bcc0f2">32c7bcc</a>)</li>
</ul>
<h3>Reverts</h3>
<ul>
<li>Revert &quot;chore: expose fromDataToStream to be consumable (<a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a>)&quot;
(<a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a>)
(<a
href="1317261125">1317261</a>),
closes <a
href="https://redirect.github.com/axios/axios/issues/6731">#6731</a> <a
href="https://redirect.github.com/axios/axios/issues/6732">#6732</a></li>
</ul>
<h3>BREAKING CHANGES</h3>
<ul>
<li>
<p>code relying on the above will now combine the URLs instead of prefer
request URL</p>
</li>
<li>
<p>feat: add config option for allowing absolute URLs</p>
</li>
<li>
<p>fix: add default value for allowAbsoluteUrls in buildFullPath</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a9f7689b0c"><code>a9f7689</code></a>
chore(release): v1.8.2 (<a
href="https://redirect.github.com/axios/axios/issues/6812">#6812</a>)</li>
<li><a
href="fb8eec214c"><code>fb8eec2</code></a>
fix(http-adapter): add allowAbsoluteUrls to path building (<a
href="https://redirect.github.com/axios/axios/issues/6810">#6810</a>)</li>
<li><a
href="9812045755"><code>9812045</code></a>
chore(sponsor): update sponsor block (<a
href="https://redirect.github.com/axios/axios/issues/6804">#6804</a>)</li>
<li><a
href="72acf75937"><code>72acf75</code></a>
chore(sponsor): update sponsor block (<a
href="https://redirect.github.com/axios/axios/issues/6794">#6794</a>)</li>
<li><a
href="2e64afdff5"><code>2e64afd</code></a>
chore(release): v1.8.1 (<a
href="https://redirect.github.com/axios/axios/issues/6800">#6800</a>)</li>
<li><a
href="36a5a620be"><code>36a5a62</code></a>
fix(utils): move <code>generateString</code> to platform utils to avoid
importing crypto...</li>
<li><a
href="cceb7b1e15"><code>cceb7b1</code></a>
chore(release): v1.8.0 (<a
href="https://redirect.github.com/axios/axios/issues/6795">#6795</a>)</li>
<li><a
href="23a25af068"><code>23a25af</code></a>
fix(utils): replace getRandomValues with crypto module (<a
href="https://redirect.github.com/axios/axios/issues/6788">#6788</a>)</li>
<li><a
href="32c7bcc0f2"><code>32c7bcc</code></a>
feat: Add config for ignoring absolute URLs (<a
href="https://redirect.github.com/axios/axios/issues/5902">#5902</a>)
(<a
href="https://redirect.github.com/axios/axios/issues/6192">#6192</a>)</li>
<li><a
href="4a3e26cf65"><code>4a3e26c</code></a>
chore(config): adjust rollup config to preserve license header to
minified Ja...</li>
<li>Additional commits viewable in <a
href="https://github.com/axios/axios/compare/v1.7.9...v1.8.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=axios&package-manager=npm_and_yarn&previous-version=1.7.9&new-version=1.8.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/microsoft/autogen/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-08 19:56:16 -08:00
DavidYu00 b69751d88f
Add author name before their message in Chainlit team sample (#5878)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->
This PR makes it clear which agent is speaking per message in the
Chainlit team sample. Previously, messages would be exchanged without
showing who is communicating.

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #5609 

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-08 19:45:49 -08:00
Victor Dibia 134a8c71ef
Add anthropic docs (#5882)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Add anthropic docs

- Add api docs 
- Add sample code + usage in agent chat user guide

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5856 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-08 19:35:28 -08:00
Eric Zhu 704dab1018
Update README to clarify Web Browsing Agent Team usage, and use animated Chromium browser (#5861)
Because it is more fun to see it
2025-03-07 16:47:00 -08:00
Eric Zhu 740afe5b61
Add ToolCallEvent and log it from all builtin tools (#5859)
Resolves #5745

Also made sure to log LLMCallEvent from all builtin model clients, and
added unit test for coverage.

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-07 16:04:45 -08:00
gagb 4ba65601ca
Add new sample: Gitty (#5842) 2025-03-07 23:24:07 +00:00
afourney 8f737de0e1
Add client close (#5871)
Fixes #4821 by adding a `close()` method to all clients.

Additionally:
* The m1 CLI is updated to close the client before exiting.
* The playwrightcontroller is updated to suppress some other unrelated
chatty warnings (e.g,, produced by markitdown when encountering
conversions that require external utilities)
2025-03-07 14:10:06 -08:00
peterychang dd82883a90
Allow Voice Access to find clickable cards (#5857)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Fixes accessibility issue (34)

## Related issue number

#5634 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-03-07 13:35:15 -05:00
peterychang 97dbc5cd16
word wrap prev/next links on autodocs (#5867)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Long module names get cut off in autodocs. Fixes (3). I would love to
break the words on dots and underscores, but it doesn't look like theres
a CSS option for that

before:

![image](https://github.com/user-attachments/assets/c2e425db-a197-4174-9af8-1f7a805df307)

after:

![image](https://github.com/user-attachments/assets/dcfc261a-61ca-4072-a28f-3b51e428ef7f)


## Related issue number

#5634 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-07 13:22:34 -05:00
afourney 5685bd1888
Update markitdown requirements to >= 0.0.1, while still in the 0.0.x range (#5864) 2025-03-06 21:33:09 -08:00
Eric Zhu ea89a84c30
fix: remove max_tokens from az ai client create call when stream=True (#5860) 2025-03-06 17:18:37 -08:00
Jacob Alber 05b14f197a
feat: Enable Reset in AgentChat.NET (#5855)
Factors out RunContext management into separate classes:
* Defines a LifecycleObject abstraction to manage initialization /
deinitialization
* Defines RunContextStack to enable a stack of init/deinit layers
* Defines a RunManager to own ensuring proper semantics for performing a
"single execution at a time" call while enabling a polymorphic base.

Implements Reset

Closes #5799
Unblocks #5800 (needs RunContext refactor too)
2025-03-06 16:32:29 -08:00
Eric Zhu 907dad46b2
update ollama usage docs (#5854)
Update the outdated ollama usage doc.
2025-03-06 12:53:38 -08:00
peterychang 21770766bf
copy tooltip on focus. Upgrade PDT version (#5848)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

(Partially?) fixes accessibility issue (19). Question out to
accessibility team whether its enough.

Migrating to 16.0 for accessibility fixes. Not moving to 16.1 yet
because of a weird change to the 'Show Source' link's appearance

## Related issue number

#5630 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-03-06 19:47:36 +00:00
Victor Dibia 648f734c75
Fix component.label error in AGS frontend (#5845)
Fix issue here in this discussion -
https://github.com/microsoft/autogen/discussions/4208#discussioncomment-12394408

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Fix bug in AGS UI where frontend crashes because the default team config
is null

- update /teams endpoint to always return a default team if none is
found for the user
- update UI to check for team before rendering 
- also update run_id type to be autoincrement int (similar to team id)
instead of uuid. This helps side step the migration failed errors
related to UUID type when using an sqlite backend

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-03-06 10:52:42 -08:00
Eric Zhu 7e5c1154cf
Support for external agent runtime in AgentChat (#5843)
Resolves #4075

1. Introduce custom runtime parameter for all AgentChat teams
(RoundRobinGroupChat, SelectorGroupChat, etc.). This is done by making
sure each team's topics are isolated from other teams, and decoupling
state from agent identities. Also, I removed the closure agent from the
BaseGroupChat and use the group chat manager agent to relay messages to
the output message queue.
2. Added unit tests to test scenarios with custom runtimes by using
pytest fixture
3. Refactored existing unit tests to use ReplayChatCompletionClient with
a few improvements to the client.
4. Fix a one-liner bug in AssistantAgent that caused deserialized agent
to have handoffs.

How to use it? 

```python
import asyncio
from autogen_core import SingleThreadedAgentRuntime
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.conditions import TextMentionTermination
from autogen_ext.models.replay import ReplayChatCompletionClient

async def main() -> None:
    # Create a runtime
    runtime = SingleThreadedAgentRuntime()
    runtime.start()

    # Create a model client.
    model_client = ReplayChatCompletionClient(
        ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
    )

    # Create agents
    agent1 = AssistantAgent("assistant1", model_client=model_client, system_message="You are a helpful assistant.")
    agent2 = AssistantAgent("assistant2", model_client=model_client, system_message="You are a helpful assistant.")

    # Create a termination condition
    termination_condition = TextMentionTermination("10", sources=["assistant1", "assistant2"])

    # Create a team
    team = RoundRobinGroupChat([agent1, agent2], runtime=runtime, termination_condition=termination_condition)

    # Run the team
    stream = team.run_stream(task="Count to 10.")
    async for message in stream:
        print(message)
    
    # Save the state.
    state = await team.save_state()

    # Load the state to an existing team.
    await team.load_state(state)

    # Run the team again
    model_client.reset()
    stream = team.run_stream(task="Count to 10.")
    async for message in stream:
        print(message)

    # Create a new team, with the same agent names.
    agent3 = AssistantAgent("assistant1", model_client=model_client, system_message="You are a helpful assistant.")
    agent4 = AssistantAgent("assistant2", model_client=model_client, system_message="You are a helpful assistant.")
    new_team = RoundRobinGroupChat([agent3, agent4], runtime=runtime, termination_condition=termination_condition)

    # Load the state to the new team.
    await new_team.load_state(state)

    # Run the new team
    model_client.reset()
    new_stream = new_team.run_stream(task="Count to 10.")
    async for message in new_stream:
        print(message)
    
    # Stop the runtime
    await runtime.stop()

asyncio.run(main())
```

TODOs as future PRs:
1. Documentation.
2. How to handle errors in custom runtime when the agent has exception?

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-03-06 10:32:52 -08:00
Eric Zhu 30b1b8f90c
Fix warning in selector gorup chat guide (#5849)
Fix a warning that has been resolved in the latest release.
2025-03-06 10:24:18 -08:00
Taswar Bhatti 7d17ac8d5b
Update quickstart.ipynb (#5815)
Added notice for user who are not using Jypter Notebook for the example,
to wrap with asyncio
2025-03-06 14:45:27 +00:00
Leonardo Pinheiro 9d235d2585
fix: add plugin to kernel (#5830)
Line that adds the plugin to the kernel was accidentally removed, which
caused SK to be unable to invoke tools.
2025-03-05 04:37:43 +00:00
Eric Zhu 54c309007a
fix: warn when using reflection on tool use with Claude models (#5829)
Resolves #5731
2025-03-05 04:30:19 +00:00
peterychang 92d857f6b4
Keyboard copy event and search bar cancellation (#5820)
## Why are these changes needed?

Keyboard focus location was being lost after a copy event. Header anchor
was also not selectable while hidden

Fixes (2), (4), (11), (35)

## Related issue number

#5630 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-04 18:56:53 +00:00
Ricky Loynd 97536af7a3
Task-Centric Memory (#5227)
_(EXPERIMENTAL, RESEARCH IN PROGRESS)_

In 2023 AutoGen introduced [Teachable
Agents](https://microsoft.github.io/autogen/0.2/blog/2023/10/26/TeachableAgent/)
that users could teach new facts, preferences and skills. But teachable
agents were limited in several ways: They could only be
`ConversableAgent` subclasses, they couldn't learn a new skill unless
the user stated (in a single turn) both the task and how to solve it,
and they couldn't learn on their own. **Task-Centric Memory** overcomes
these limitations, allowing users to teach arbitrary agents (or teams)
more flexibly and reliably, and enabling agents to learn from their own
trial-and-error experiences.

This PR is large and complex. All of the files are new, and most of the
added components depend on the others to run at all. But the review
process can be accelerated if approached in the following order.
1. Start with the [Task-Centric Memory
README](https://github.com/microsoft/autogen/tree/agentic_memory/python/packages/autogen-ext/src/autogen_ext/task_centric_memory).
1. Install the memory extension locally, since it won't be in pypi until
it's merged. In the `agentic_memory` branch, and the `python/packages`
directory:
        - `pip install -e autogen-agentchat`
        - `pip install -e autogen-ext[openai]`
        - `pip install -e autogen-ext[task-centric-memory]`
2. Run the Quickstart sample code, then immediately open the
`./pagelogs/quick/0 Call Tree.html` file in a browser to view the work
in progress.
    3. Click through the web page links to see the details.
2. Continue through the rest of the main README to get a high-level
overview of the architecture.
3. Read through the [code samples
README](https://github.com/microsoft/autogen/tree/agentic_memory/python/samples/task_centric_memory),
running each of the 4 code samples while viewing their page logs.
4. Skim through the 4 code samples, along with their corresponding yaml
config files:
    1. `chat_with_teachable_agent.py`
    2. `eval_retrieval.py`
    3. `eval_teachability.py`
    4. `eval_learning_from_demonstration.py`
    5. `eval_self_teaching.py`
6. Read `task_centric_memory_controller.py`, referring back to the
previously generated page logs as needed. This is the most important and
complex file in the PR.
7. Read the remaining core files.
    1. `_task_centric_memory_bank.py`
    2. `_string_similarity_map.py`
    3. `_prompter.py`
8. Read the supporting files in the utils dir.
    1. `teachability.py`
    2. `apprentice.py`
    3. `grader.py`
    4. `page_logger.py`
    5. `_functions.py`
2025-03-04 09:56:49 -08:00
Eric Zhu 39bfa35e28
docs: Add note recommending PythonCodeExecutionTool as an alternative to CodeExecutorAgent (#5809)
Resolves #5782

---------

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-04 17:48:13 +00:00
peterychang 3855989543
Fix high contrast mode focus (#5796)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Adds sidebar and breadcrumb selection and focus indicators to high
contrast modes.
Fixes (46), (55), (56)

## Related issue number

 #5633 

This change has no affect on normal color modes, but adds selection and
focus indicators to high contrast modes. I'm not sure how to get rid of
the double bars on nested links, but thats a minor issue

before:

![image](https://github.com/user-attachments/assets/62e7ce65-c3f0-4160-8260-b4153a4a2835)

after:

![image](https://github.com/user-attachments/assets/581ed2a2-5f7c-43c8-a675-2f6c57c6a251)
2025-03-04 17:41:25 +00:00
peterychang a701e3b4fa
highlight focused code output boxes in jupyter notebook pages (#5819)
## Why are these changes needed?

Current webpage theme does not highlight code output boxes. Issues (5)
and (29)

## Related issue number

#5630 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-04 09:29:08 -08:00
Eric Zhu ed08676bd7
doc: update termination tutorial to include FunctionCallTermination condition and fix formatting (#5813) 2025-03-03 23:22:19 -08:00
Eric Zhu 83fb29edd4
Update website for v0.4.8 (#5812) 2025-03-03 22:50:56 -08:00
Eric Zhu e7b47700da
doc: update guide for termination condition and tool usage (#5807)
Resolves #5786

Also updated the termination tutorial to include an example of a custom
termination conditon.

Also added to guide about FunctionTool and MCP tools.
2025-03-03 22:26:27 -08:00
Eric Zhu 4858676bdd
Add examples for custom model context in AssistantAgent and ChatCompletionContext (#5810)
Resolves #5777
2025-03-03 22:19:59 -08:00
Eric Zhu cc1b0cdd51
feat: Add FunctionCallTermination condition (#5808)
Add function call termination condition.

Useful as an alternative to TextMentionTermination for models with tool
call capability.
2025-03-04 03:26:47 +00:00
Paul Barbaste da10765474
Update magentic-one.md (#5779)
## Why are these changes needed?

The current installation command fails in certain shells (e.g., `zsh`,
`fish`) because brackets (`[]`) are interpreted as special characters.
Adding quotes ensures compatibility across different environments,
including Linux, macOS, and Windows.

## Related issue number

No related issue, but this fixes an installation issue encountered by
multiple users.

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-04 00:48:08 +00:00
LuSrackhall 897efcca99
Update installation.md (#5784)
## Why are these changes needed?

* `python3` to `python`: Windows uses `python` for Python 3 by default,
not `python3`.
* `bin` to `scripts`: Windows virtual environments use `Scripts` instead
of `bin`.

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-04 00:41:52 +00:00
Muhammad Junaid 0b9a622b56
Fix: Auto-Convert Pydantic and Dataclass Arguments in AutoGen Tool Calls (#5737)
AutoGen was passing raw dictionaries to functions instead of
constructing Pydantic model or dataclass instances. If a tool function’s
parameter was a Pydantic BaseModel or a dataclass, the function would
receive a dict and likely throw an error or behave incorrectly (since it
expected an object of that type).

This PR addresses problem in AutoGen where tool functions expecting
structured inputs (Pydantic models or dataclasses) were receiving raw
dictionaries. It ensures that structured inputs are automatically
validated and instantiated before function calls. Complete details are
in Issue #5736

[Reproducible Example Code - Failing
Case](https://colab.research.google.com/drive/1hgoP-cGdSZ1-OqQLpwYmlmcExgftDqlO?usp=sharing)
 
<!-- Please give a short summary of the change and the problem this
solves. -->
## Changes Made:
- Inspect function signatures for Pydantic BaseModel and dataclass
annotations.
- Convert input dictionaries into properly instantiated objects using
BaseModel.model_validate() for Pydantic models or standard instantiation
for dataclasses.
  - Raise descriptive errors when validation or instantiation fails.
  - Unit tests have been added to cover all scenarios

Now structured inputs are automatically validated and instantiated
before function calls.

- **Updated Conversion Logic:**  
In the `run()` method, we now inspect the function’s signature and
convert input dictionaries to structured objects. For parameters
annotated with a Pydantic model, we use `model_validate()` to create an
instance; for those annotated with a dataclass, we instantiate the
object using the dataclass constructor. For example:

  ```python
  # Get the function signature.
  sig = inspect.signature(self._func)
  raw_kwargs = args.model_dump()
  kwargs = {}

  # Iterate over the parameters expected by the function.
  for name, param in sig.parameters.items():
      if name in raw_kwargs:
          expected_type = param.annotation
          value = raw_kwargs[name]
# If expected type is a subclass of BaseModel, perform conversion.
if inspect.isclass(expected_type) and issubclass(expected_type,
BaseModel):
              try:
                  kwargs[name] = expected_type.model_validate(value)
              except ValidationError as e:
                  raise ValueError(
f"Error validating parameter '{name}' for function
'{self._func.__name__}': {e}"
                  ) from e
          # If it's a dataclass, instantiate it.
          elif is_dataclass(expected_type):
              try:
cls = expected_type if isinstance(expected_type, type) else
type(expected_type)
                  kwargs[name] = cls(**value)
              except Exception as e:
                  raise ValueError(
f"Error instantiating dataclass parameter '{name}' for function
'{self._func.__name__}': {e}"
                  ) from e
          else:
              kwargs[name] = value
  ```

- **Error Handling Improvements:**  
Conversion steps are wrapped in try/except blocks to raise descriptive
errors when instantiation fails, aiding in debugging invalid inputs.

- **Testing:**  
Unit tests have been added to simulate tool calls (e.g., an `add` tool)
to ensure that with input like:
  ```json
  {"input": {"x": 2, "y": 3}}
  ```
The tool function receives an instance of the expected type and returns
the correct result.


## Related issue number
Closes #5736
 
## Checks
- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.
2025-03-03 16:35:27 -08:00
laurentran 3d5e4c8d7b
Update with correct message types (#5789)
Correcting an error: If CodeReviewResult is not approved, the coder
agents sends a CodeReviewTask back to the reviewer agent, not a
CodeWritingTask.

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-03 23:46:53 +00:00
Victor Dibia 1b51e69602
add api docstring to with_requirements (#5746)
Starting out this draft PR to add documentation for the
`with_requirements` decorator in the `autogen-core` package.

---------

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-03-03 23:35:10 +00:00
Eitan Yarmush 9d4236b1ce
TextMessageTerminationCondition for agentchat (#5742)
Closes #5732 
---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-03 23:29:25 +00:00
Leonardo Pinheiro 906b09e451
fix: Update SKChatCompletionAdapter message conversion (#5749)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

The PR introduces two changes.

The first change is adding a name attribute to
`FunctionExecutionResult`. The motivation is that semantic kernel
requires it for their function result interface and it seemed like a
easy modification as `FunctionExecutionResult` is always created in the
context of a `FunctionCall` which will contain the name. I'm unsure if
there was a motivation to keep it out but this change makes it easier to
trace which tool the result refers to and also increases api
compatibility with SK.

The second change is an update to how messages are mapped from autogen
to semantic kernel, which includes an update/fix in the processing of
function results.

## Related issue number

<!-- For example: "Closes #1234" -->

Related to #5675 but wont fix the underlying issue of anthropic
requiring tools during AssistantAgent reflection.

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Leonardo Pinheiro <lpinheiro@microsoft.com>
2025-03-03 23:05:54 +00:00
YASAI03 7e01350d46
fix(studio): Fixed an issue where the app would crash if a team was not set when opening a playground page. (#5794)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

(I'm not familiar with English, so I use Goggle translation a lot. So
please forgive me if I say something rude.)
I started autogen-studio and opened the page in the browser, nothing was
rendered.
I checked using the Developer tool, the following error appeared:
```
TypeError: Cannot read properties of null (reading 'label')
at editor.tsx:114:42
```
I check the implementation, it looks like `team.component` is `null`,
which seems to be caused during initialization process when the team is
not registered.
[source](78ff883d24/python/packages/autogen-studio/frontend/src/components/views/playground/manager.tsx (L199))

So I fixed the issue where the gallery wasn't being retrieved which was
causing the issue.

### Reproduce bug

1. clone this repository
2. open devcontainer(`python/packages/autogen-studio`)
3. Running the application
```sh
cd frontend
yarn build
cd -
OPENAI_API_KEY="" autogenstudio ui --port 8081
```
4. Open `localhost:8081` in browser.

## Related issue number

<!-- For example: "Closes #1234" -->

Probably not found. (sorry if I had to raise an issue before PR)

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [-] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-03-03 14:25:40 -08:00
Peter Jausovec a785cd90f9
add stream_options to openai model (#5788)
stream_options are not part of the model classes, so they won't get
serialized when calling dump_component. Adding this to the model allows
us to store the stream options when the component is serialized.
---------

Signed-off-by: Peter Jausovec <peter.jausovec@solo.io>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-03 21:58:05 +00:00
Victor Dibia 679a9357f8
Fix AGS Cascading Delete Issue (#5804)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

> Hey Victor, this is maybe a bug, but when a session is delete, runs
and messages for that session are not deleted, any reason why to keep
them?

@husseinmozannar 

The main fix is to add a pragma that ensures SQL lite enforces foreign
key constraints.
Also needed to update error messages for autoupgrade of databases. Also
adds a test for cascade deletes and for parts of teammanager

With this fix,

- Messages get deleted when the run is deleted 
- Runs get deleted when sessiosn are deleted 
- Sessions get deleted when a team is deleted 

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-03 21:46:57 +00:00
peterychang 8c9961ecba
add options to ollama client (#5805)
Necessary to configure ollama client

## Related issue number

#5597 

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-03 13:24:14 -08:00
Victor Dibia dd1ade816e
Add Git LFS Note to AGS Readme (#5798)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->



## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

- AGS contains image files which are required for local build /dev
- These files are stored using git lfs which needs to be run before the
files are downloaded
- This PR adds a reminder to the AGS readme to run `git lfs checkout`
after installing git lfs to download the image files

## Related issue number

<!-- For example: "Closes #1234" -->

Close #3418

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-03 12:39:25 -08:00
Jay Prakash Thakur 78ff883d24
docs: add note about markdown code block requirement in CodeExecutorA… (#5785)
## Why are these changes needed?

The CodeExecutorAgent documentation needs to be updated to explicitly
mention that it only processes code properly formatted in markdown code
blocks with triple backticks. This change adds a clear note with
examples to help users understand the required format for code
execution.

## Related issue number

Closes #5771


Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-03-02 17:00:08 -08:00
Victor Dibia b8b13935c9
Make FileSurfer and CodeExecAgent Declarative (#5765)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Make FileSurfer and CodeExecAgent Declarative.
These agent presents are used as part of magentic one and having them
declarative is a precursor to their use in AGS.

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #5607

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-01 15:46:30 +00:00
Victor Dibia 78ef148c88
Add ChromaDBVectorMemory in Extensions (#5308)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->
Shows an example of how to use the `Memory` interface to implement a
just-in-time vector memory based on chromadb.

```python
import os
from pathlib import Path

from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.ui import Console
from autogen_core.memory import MemoryContent, MemoryMimeType
from autogen_ext.memory.chromadb import ChromaDBVectorMemory, PersistentChromaDBVectorMemoryConfig
from autogen_ext.models.openai import OpenAIChatCompletionClient

# Initialize ChromaDB memory with custom config
chroma_user_memory = ChromaDBVectorMemory(
    config=PersistentChromaDBVectorMemoryConfig(
        collection_name="preferences",
        persistence_path=os.path.join(str(Path.home()), ".chromadb_autogen"),
        k=2,  # Return top  k results
        score_threshold=0.4,  # Minimum similarity score
    )
)
# a HttpChromaDBVectorMemoryConfig is also supported for connecting to a remote ChromaDB server

# Add user preferences to memory
await chroma_user_memory.add(
    MemoryContent(
        content="The weather should be in metric units",
        mime_type=MemoryMimeType.TEXT,
        metadata={"category": "preferences", "type": "units"},
    )
)

await chroma_user_memory.add(
    MemoryContent(
        content="Meal recipe must be vegan",
        mime_type=MemoryMimeType.TEXT,
        metadata={"category": "preferences", "type": "dietary"},
    )
)


# Create assistant agent with ChromaDB memory
assistant_agent = AssistantAgent(
    name="assistant_agent",
    model_client=OpenAIChatCompletionClient(
        model="gpt-4o",
    ),
    tools=[get_weather],
    memory=[user_memory],
)

stream = assistant_agent.run_stream(task="What is the weather in New York?")
await Console(stream)

await user_memory.close()
```

```txt
 ---------- user ----------
What is the weather in New York?
---------- assistant_agent ----------
[MemoryContent(content='The weather should be in metric units', mime_type='MemoryMimeType.TEXT', metadata={'category': 'preferences', 'mime_type': 'MemoryMimeType.TEXT', 'type': 'units', 'score': 0.4342913043162201, 'id': '8a8d683c-5866-41e1-ac17-08c4fda6da86'}), MemoryContent(content='The weather should be in metric units', mime_type='MemoryMimeType.TEXT', metadata={'category': 'preferences', 'mime_type': 'MemoryMimeType.TEXT', 'type': 'units', 'score': 0.4342913043162201, 'id': 'f27af42c-cb63-46f0-b26b-ffcc09955ca1'})]
---------- assistant_agent ----------
[FunctionCall(id='call_a8U3YEj2dxA065vyzdfXDtNf', arguments='{"city":"New York","units":"metric"}', name='get_weather')]
---------- assistant_agent ----------
[FunctionExecutionResult(content='The weather in New York is 23 °C and Sunny.', call_id='call_a8U3YEj2dxA065vyzdfXDtNf', is_error=False)]
---------- assistant_agent ----------
The weather in New York is 23 °C and Sunny.
```

Note that MemoryContent object in the MemoryQuery events have useful
metadata like the score and id retrieved memories.

## Related issue number

<!-- For example: "Closes #1234" -->


## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-03-01 07:41:01 -08:00
Peter Jausovec 7bbf8e075d
fix incorrect field name from config to component (#5761)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

The Team DB class doesn't have the "config" field anymore. It has
"component"

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-02-28 19:23:59 -08:00
Victor Dibia 6625f89c28
Add support for default model client, in AGS updates to settings UI (#5763)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Add support for default model client, in AGS updates to settings UI. 
A default model client will be used for subsequent background tasks
(e.g, automatically naming sessions to meaningful names).

<img width="1441" alt="image"
src="https://github.com/user-attachments/assets/31675ef4-8f80-4a8c-9762-3d6bcbc6d33d"
/>


<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5685

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-28 16:37:51 -08:00
Stuart Leeks 07a455f239
Fix typo (#5754)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->
Typo in example text

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [X] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [X] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [X] I've made sure all auto checks have passed.
2025-02-28 10:33:19 -05:00
Victor Dibia dd0781a76b
Add Serialization Instruction for MemoryContent (#5727)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

- Running a team generates a MemoryQueryEvent has a MemoryContent field
and is part of the model context
- Saving team state (`team.save_state()`) includes serializing model
context
- MemoryContent has a mime_type field, which was not being properly
serialized.
"Object of type MemoryMimeType is not JSON serializable"

This PR? -> add explicit serialization instruction for the mimetype
field.

```python
import asyncio
import logging
import json
import yaml, aiofiles
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.conditions import MaxMessageTermination
from autogen_core.memory import ListMemory, MemoryContent, MemoryMimeType
from autogen_agentchat.ui import Console

logger = logging.getLogger(__name__)

state_path = "team_state.json"

model_client =  OpenAIChatCompletionClient(model="gpt-4o-mini")

max_msg_termination = MaxMessageTermination(max_messages=3)
# Initialize user memory
user_memory = ListMemory()

# Add user preferences to memory
await user_memory.add(MemoryContent(content="The weather should be in metric units", mime_type=MemoryMimeType.TEXT))

# Create the team.
agent = AssistantAgent(
    name="assistant",
    model_client=model_client,
    system_message="You are a helpful assistant.",
    memory = [user_memory],
)
yoda = AssistantAgent(
    name="yoda",
    model_client=model_client,
    system_message="Repeat the same message in the tone of Yoda.",
)

team = RoundRobinGroupChat(
    [agent, yoda],
    termination_condition=max_msg_termination
)

await Console(team.run_stream(task="Hi, How are you ?"))
 
# Save team state to file.
state = await team.save_state()
with open(state_path, "w") as f:
    json.dump(state, f)
# Load team state from file.
with open("team_state.json", "r") as f:
    team_state = json.load(f)
    
await team.load_state(state) 
await Console( team.run_stream(task="What was the last thing that was said in this conversation "))
```

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5688
## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-26 18:40:00 +00:00
Jack Gerrits 6b68719939
Allow background exceptions to be fatal (#5716)
Closes #4904 

Does not change default behavior in core.

In agentchat, this change will mean that exceptions that used to be
ignored and result in bugs like the group chat stopping are now reported
out to the user application.

---------

Co-authored-by: Ben Constable <benconstable@microsoft.com>
Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-02-26 18:34:53 +00:00
peterychang dc55ec964b
Fix visual accessibility issues 6 and 20 (#5725)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Fixes visual accessibility issues `(6) Luminosity contrast ratio of
focus indicator on 'Venv' control is less than 3:1.` and `(20) "Only
color is used to indicate the focus indicator on the 'Venv', and 'conda'
Tab controls."`

## Related issue number

#5633 

before:
<img width="162" alt="image"
src="https://github.com/user-attachments/assets/ac317e82-c82e-4d3b-910b-e9eb5d087340"
/>

![image](https://github.com/user-attachments/assets/2971043a-8b5b-4521-8135-c411c0ecab1f)

after:
<img width="160" alt="image"
src="https://github.com/user-attachments/assets/8053ae77-4d62-491b-9d78-657646ed71a6"
/>

![image](https://github.com/user-attachments/assets/5c3ac2c3-4813-461b-8958-4665860574a0)
2025-02-26 11:59:07 -05:00
rylativity 5615f40a30
5663 ollama client host (#5674)
@ekzhu should likely be assigned as reviewer

## Why are these changes needed?

These changes address the bug reported in #5663. Prevents TypeError from
being thrown at inference time by ollama AsyncClient when `host` (and
other) kwargs are passed to autogen OllamaChatCompletionClient
constructor.

It also adds ollama as a named optional extra so that the ollama
requirements can be installed alongside autogen-ext (e.g. `pip install
autogen-ext[ollama]`

@ekzhu, I will need some help or guidance to ensure that the associated
test (which requires ollama and tiktoken as dependencies of the
OllamaChatCompletionClient) can run successfully in autogen's test
execution environment.

I have also left the "I've made sure all auto checks have passed" check
below unchecked as this PR is coming from my fork. (UPDATE: auto checks
appear to have passed after opening PR, so I have checked box below)

## Related issue number

Intended to close #5663 

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Co-authored-by: Ryan Stewart <ryanstewart@Ryans-MacBook-Pro.local>
Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
Co-authored-by: peterychang <49209570+peterychang@users.noreply.github.com>
2025-02-26 11:02:48 -05:00
Victor Dibia 05fc763b8a
add anthropic native support (#5695)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

Claude 3.7 just came out. Its a pretty capable model and it would be
great to support it in Autogen.
This will could augment the already excellent support we have for
Anthropic via the SKAdapters in the following ways

- Based on the ChatCompletion API similar to the ollama and openai
client
- Configurable/serializable (can be dumped) .. this means it can be used
easily in AGS.

## What is Supported 

(video below shows the client being used in autogen studio)

https://github.com/user-attachments/assets/8fb7c17c-9f9c-4525-aa9c-f256aad0f40b



- streaming 
- tool callign / function calling 
- drop in integration with assistant agent. 
- multimodal support

```python

from dotenv import load_dotenv
import os 

load_dotenv()

from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_ext.models.anthropic import AnthropicChatCompletionClient 
model_client =   AnthropicChatCompletionClient(
        model="claude-3-7-sonnet-20250219" 
    )

async def get_weather(city: str) -> str:
    """Get the weather for a given city."""
    return f"The weather in {city} is 73 degrees and Sunny."

 
agent = AssistantAgent(
    name="weather_agent",
    model_client=model_client,
    tools=[get_weather],
    system_message="You are a helpful assistant.", 
    # model_client_stream=True,   
)

# Run the agent and stream the messages to the console.
async def main() -> None:
    await Console(agent.run_stream(task="What is the weather in New York?"))
await main()
```

result 

```
messages = [
    UserMessage(content="Write a very short story about a dragon.", source="user"),
]

# Create a stream.
stream = model_client.create_stream(messages=messages)

# Iterate over the stream and print the responses.
print("Streamed responses:")
async for response in stream:  # type: ignore
    if isinstance(response, str):
        # A partial response is a string.
        print(response, flush=True, end="")
    else:
        # The last response is a CreateResult object with the complete message.
        print("\n\n------------\n")
        print("The complete response:", flush=True)
        print(response.content, flush=True)
        print("\n\n------------\n")
        print("The token usage was:", flush=True)
        print(response.usage, flush=True)
```

 

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" --> 

Closes #5205 
Closes #5708

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed. 



cc @rohanthacker
2025-02-26 07:27:41 +00:00
Victor Dibia 1f30622adc
update human in the loop docs for agentchat (#5720)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

update human in the loop docs for agentchat  
..

> Outputs in docs are outdated as summary is not printed out by default
when using Console
[#5590](https://github.com/microsoft/autogen/issues/5590)

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #5590

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-25 23:15:33 -08:00
gagb 173e649aa6
Update README.md for improved clarity and formatting (#5714)
This pull request includes updates to the `README.md` file for the
`autogen-studio` package to improve clarity and accuracy. The most
important changes include a minor rewrite of the project structure
section and updates to the installation instructions (better tabbing).
2025-02-25 19:28:05 -08:00
cedricmendelin b37c192424
Dotnet: Add modelServiceId support to SemanticKernelAgent (#5422)
The `SemanticKernelAgent` class has been updated to include an optional
`modelServiceId` parameter, allowing the specification of a service ID
for the model.

## Why are these changes needed?

Currently, `SemanticKernelAgent` uses the parameterless method for
resolving `IChatCompletionSerivce`. This will fail, when multiple models
are registered in the Kernel.

To support different models registered in the Kernel, I adopted the
resolving of the `IChatCompletionSerivce` within the
`SemanticKernelAgent` with an optional parameter. When it is not set, I
resolve the default instance, otherwise, I use the optional parameter as
a servide id for resolving the `IChatCompletionSerivce` service.

## Related issue number



## Checks

- [x] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
Co-authored-by: Xiaoyun Zhang <bigmiao.zhang@gmail.com>
2025-02-25 20:39:45 +00:00
Jack Gerrits 1380412582
Specify specific UV version should be used (#5711)
Closes #5710
2025-02-25 19:47:20 +00:00
peterychang 73f26792ab
Fix accessibility issue 14 for visual accessibility (#5709)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Fixes `(14) Ensures the contrast between foreground and background
colors meets WCAG 2 AA minimum contrast ratio thresholds`

Note: the color values don't output at the exact values on the
stylesheet. For example, the value `#1774E5` evaluates to `#2274E0` by
the Accessibility Insights app.

## Related issue number

https://github.com/microsoft/autogen/issues/5633

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-25 19:19:14 +00:00
Leonardo Pinheiro a02d08a8ef
Refactor AssistantAgent on_message_stream (#5642)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

I'm unsure if everyone will agree, but I started to look into adding new
logic and found that refactoring into smaller functions would make it
more maintainable.

There is no change in functionality, only a breakdown into smaller
methods to make it more modular and improve readability. There is a lot
of logic in the method and this refactor breaks it down into context
management, llm call and result processing.

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Leonardo Pinheiro <lpinheiro@microsoft.com>
2025-02-25 19:11:35 +00:00
pengjunfeng11 a06b6c8b0b
REF: replaced variable name in TextMentionTermination (#5698)
## Why are these changes needed?

For the sake of subsequent people reading the metacode and following
programming specifications, variable names are updated in combination
with usage scenarios. Mainly contains the variable "_self_text" in
TextMentionTermination
2025-02-25 16:00:41 +00:00
Victor Dibia fbe94dd7ed
Add Token Streaming in AGS , Support Env variables (#5659)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

This PR has 3 main improvements. 

- Token streaming 
- Adds support for environment variables in the app settings 
- Updates AGS to persist Gallery entry in db.

## Adds Token Streaming in AGS.  

Agentchat now supports streaming of tokens via
`ModelClientStreamingChunkEvent `. This PR is to track progress on
supporting that in the AutoGen Studio UI.

If `model_client_stream` is enabled in an assitant agent, then token
will be streamed in UI.

```python
streaming_assistant = AssistantAgent(
    name="assistant",
    model_client=model_client,
    system_message="You are a helpful assistant.",
    model_client_stream=True,  # Enable streaming tokens.
)

```

https://github.com/user-attachments/assets/74d43d78-6359-40c3-a78e-c84dcb5e02a1


## Env Variables 
Also adds support for env variables in AGS Settings

You can set env variables that are loaded just before a team is run.
Handy to set variable to be used by tools etc.

<img width="1291" alt="image"
src="https://github.com/user-attachments/assets/437b9d90-ccee-42f7-be5d-94ab191afd67"
/>


> Note: the set variables are available to the server process.

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #5627  
Closes #5662 
Closes #5619 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-25 15:21:08 +00:00
Jack Gerrits ca86906b62
Change base image to one with arm64 support (#5681) 2025-02-25 12:27:02 +00:00
Hussein Mozannar 4dac9c819e
Add metadata field to basemessage (#5372)
Add metadata field to BaseMessage.

Why?
- additional metadata field can track 1) timestamp if needed, 2) flags
about the message. For instance, a use case is a metadata field
{"internal":"yes"} that would hide messages from being displayed in an
application or studio.

As long as an extra field is added to basemessage that is not consumed
by existing agents, I am happy.



Notes:
- We can also only add it to BaseChatMessage, that would be fine
- I don't care what the extra field is called as long as there is an
extra field somewhere
- I don't have preference for the type, a str could work, but a dict
would be more useful.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-25 06:54:49 +00:00
Eric Zhu c302b5408a
doc: Update SelectorGroupChat doc on how to use O3-mini model. (#5657)
Resolves #5408

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-02-25 06:44:23 +00:00
Eric Zhu a14aeab6e4
doc & sample: Update documentation for human-in-the-loop and UserProxyAgent; Add UserProxyAgent to ChainLit sample; (#5656)
Resolves #5610

And address various questions regarding to how to use user proxy agent
and human-in-the-loop.
2025-02-25 01:41:15 +00:00
Jack Gerrits a54a85e2f8
Update issue templates (#5686) 2025-02-25 01:15:50 +00:00
Eric Zhu 6bc896f6e2
update versions to 0.4.8 (#5689) 2025-02-24 23:46:37 +00:00
Ryan Sweet 78adf32f7d
pack agenthost as tool (#5647)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

convenience - allows to just run "agenthost"

```
dotnet pack --no-build --configuration Release --output './output/release' -bl\n
dotnet tool install --add-source ./output/release Microsoft.AutoGen.AgentHost
agenthost 
```

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

closes #5646 

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-24 14:23:45 -08:00
gagb 159e4f114d
Improve readme inconsistency (#5691)
### Before

<img width="823" alt="image"
src="https://github.com/user-attachments/assets/d5ba1671-9433-4fa4-9884-c0de6fafb82e"
/>



### After
<img width="803" alt="image"
src="https://github.com/user-attachments/assets/07fdd32a-d2ad-450d-8b7f-b21f10f14c85"
/>
2025-02-24 12:12:53 -08:00
Shubham Shukla caa363b517
Replace the undefined tools variable with tool_schema parameter in ToolUseAgent class (#5684)
Replace the undefined `tools` variable with `tool_schema` parameter

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?
This change keeps the documentation up to date :
https://microsoft.github.io/autogen/stable//user-guide/core-user-guide/components/tools.html

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-24 17:41:45 +00:00
Jack Gerrits 181925c95d
[dotnet] Add mixin for easier state save/load apis (#5438)
Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-02-24 16:24:30 +00:00
Ryan Sweet 213da855ec
remove dep on aspire - add google.protobuf (#5645)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

removes unneeded deps

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5644

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-24 16:02:49 +00:00
Eric Zhu 0360ab9715
doc: Enrich AssistantAgent API documentation with usage examples. (#5653)
Resolves #5562
2025-02-24 10:57:34 -05:00
Eric Zhu 08c82e4c6f
docs: Add logging instructions for AgentChat and enhance core logging guide (#5655)
Resolves #5640
2025-02-24 14:39:38 +00:00
Christoph Schittko 64807d24f5
DOCS: Fixed small errors in the text and made code format more consistent (#5664)
## Why are these changes needed?

Fix minor issues in docs:
- probably editing left over
- typo
- code formatting inconsistency

## Related issue number

N/A

## Checks

- [ X] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ X] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ X] I've made sure all auto checks have passed.

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-02-24 14:28:17 +00:00
Eric Zhu 9fd8eefc55
fix: Structured output with tool calls for OpenAIChatCompletionClient (#5671)
Resolves: #5568

Also, refactored some unit tests.

Integration tests against OpenAI endpoint passed:
https://github.com/microsoft/autogen/actions/runs/13484492096

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-02-24 14:18:46 +00:00
Ryan Sweet 745c9d2bc5
completes the table on the readme with the .NET links to docs and packages. (#5673)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

completes the table on the readme with the .NET links to docs and
packages.

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-02-24 14:09:12 +00:00
linznin 2570cc9cf3
Fix: Add support for custom headers in HTTP tool requests (#5660)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

The HttpTool in AutoGen accepts a headers parameter, but it is not being
used in the actual request. This fix ensures that the headers provided
by users are correctly included in HTTP requests. This resolves issues
where authentication or other custom headers are required but currently
ignored.

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #5638

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-02-24 13:52:58 +00:00
Christoph Schittko 87495c67c3
DOCS: Minor updates to handoffs.ipynb (#5665)
Updates:
- added missing backtick for formatting class name
- typo in user response example

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-24 06:40:50 +00:00
philippHorn 95585b4408
fix: Crash in argument parsing when using Openrouter (#5667)
## Why are these changes needed?
See issue for a bug description.
The problem was that a lot of openrouter models return `""` as
`tool_call.arguments`, which caused `json.loads` to fail
## Related issue number
https://github.com/microsoft/autogen/issues/5666
---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-23 22:35:13 -08:00
Victor Dibia 170b8cc893
Make ChatCompletionCache support component config (#5658)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

This PR makes makes ChatCompletionCache   support component config

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed? 

Ensures we have a path to serializing ChatCompletionCache , similar to
the ChatCompletion client that it wraps.

This PR does the following

- Makes CacheStore serializable first (part of this includes converting
from Protocol to base class). Makes it's derivatives serializable as
well (diskcache, redis)
- Makes ChatCompletionCache serializable 
- Adds some tests

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5141

## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed. 


cc @nour-bouzid
2025-02-23 19:49:22 -08:00
Eric Zhu a226966dbe
fix: Remove R1 model family from is_openai function (#5652) 2025-02-21 16:22:14 -07:00
Eric Zhu 7784f44ea6
feat: Add thought process handling in tool calls and expose ThoughtEvent through stream in AgentChat (#5500)
Resolves #5192

Test

```python
import asyncio
import os
from random import randint
from typing import List
from autogen_core.tools import BaseTool, FunctionTool
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.ui import Console

async def get_current_time(city: str) -> str:
    return f"The current time in {city} is {randint(0, 23)}:{randint(0, 59)}."

tools: List[BaseTool] = [
    FunctionTool(
        get_current_time,
        name="get_current_time",
        description="Get current time for a city.",
    ),
]

model_client = OpenAIChatCompletionClient(
    model="anthropic/claude-3.5-haiku-20241022",
    base_url="https://openrouter.ai/api/v1",
    api_key=os.environ["OPENROUTER_API_KEY"],
    model_info={
        "family": "claude-3.5-haiku",
        "function_calling": True,
        "vision": False,
        "json_output": False,
    }
)

agent = AssistantAgent(
    name="Agent",
    model_client=model_client,
    tools=tools,
    system_message= "You are an assistant with some tools that can be used to answer some questions",
)

async def main() -> None:
    await Console(agent.run_stream(task="What is current time of Paris and Toronto?"))

asyncio.run(main())
```

```
---------- user ----------
What is current time of Paris and Toronto?
---------- Agent ----------
I'll help you find the current time for Paris and Toronto by using the get_current_time function for each city.
---------- Agent ----------
[FunctionCall(id='toolu_01NwP3fNAwcYKn1x656Dq9xW', arguments='{"city": "Paris"}', name='get_current_time'), FunctionCall(id='toolu_018d4cWSy3TxXhjgmLYFrfRt', arguments='{"city": "Toronto"}', name='get_current_time')]
---------- Agent ----------
[FunctionExecutionResult(content='The current time in Paris is 1:10.', call_id='toolu_01NwP3fNAwcYKn1x656Dq9xW', is_error=False), FunctionExecutionResult(content='The current time in Toronto is 7:28.', call_id='toolu_018d4cWSy3TxXhjgmLYFrfRt', is_error=False)]
---------- Agent ----------
The current time in Paris is 1:10.
The current time in Toronto is 7:28.
```

---------

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-02-21 13:58:32 -08:00
Victor Dibia 45c6d133c2
Update AGS, Remove Numpy Dep (#5648)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

Update AGS, Remove Numpy Dep

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5639

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-21 15:33:15 -05:00
Ryan Sweet 3a239c5336
message registry buffer size limit #5582 (#5603) 2025-02-21 09:23:21 -08:00
Victor Dibia 2f43005624
Improve Gallery Editor UX in AGS (#5613)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed? 

Fixes the problem where Gallery items could only be modified via JSON 

This PR does the following

- Refactor TeamBuilder to have modular component editor UI primarily
focused on editing each component type.
- Refactor the Gallery UX 
   - improve layout to use tabs for each component type 
- enable editing of each component item by reusing the component editor
- Enable switching between form editing and UI editing for coponent
editor view

This way, gallery items can be readily modified and then reused in the
component library in team builder.
It also implements an upate to the Gallery data structure to make it
more intuitive - it has a components field that has teams, agents,
models ...

<img width="1598" alt="image"
src="https://github.com/user-attachments/assets/3c3a228a-0bd2-4fc1-85ec-c9685c80bf72"
/>
<img width="1614" alt="image"
src="https://github.com/user-attachments/assets/5b6ed840-9c48-47bc-8c17-2aa50c7dcb99"
/>


<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5465 
Closes #5047
 
cc @nour-bouzid @balakreshnan @EItanya @joslat @IustinT @leonG7
## Checks

- [ ] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-20 21:51:05 -08:00
Wei Jen Lu 34d30b56f5
Fix typo in doc (#5628)
Fix typo in doc

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
<https://microsoft.github.io/autogen/>. See
<https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-20 14:07:44 -05:00
Ryan Sweet 7e1f7a762a
more dotnet doc improvements (#5559)
cleaning up the dotnet docs site, improving formatting, making the
landing page look more like the python
## Why are these changes needed?

---------

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-02-19 17:24:26 +00:00
Ryan Sweet fa40568210
minor updates to the .NET docs (#5552)
## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number
2025-02-19 16:45:27 +00:00
OndeVai df829a133f
Fixing grammar issues (#5537)
Fixing grammar issues

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-19 15:38:58 +00:00
gagb fa3396e9c3
Initialize BaseGroupChat before reset (#5608)
Fixes #5366 

Solution: Instead of raising an error called `_init()`

---------

Co-authored-by: Jack Gerrits <jackgerrits@users.noreply.github.com>
2025-02-19 15:03:54 +00:00
Li Jiang a0e3a1208c
Improve the model mismatch warning msg (#5586) 2025-02-19 01:17:41 +00:00
Eric Zhu 083129045c
feat: enhance issue templates with detailed guidance (#5594) 2025-02-19 01:07:24 +00:00
peterychang 2842c76aeb
Ollama client docs (#5605)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Adds ollama client documentation to the docs page

## Related issue number

https://github.com/microsoft/autogen/issues/5604

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-18 16:25:51 -05:00
peterychang 4959b24777
Fix ollama docstring (#5600)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Initial commit's docstrings were incorrect, which would be confusing for
a user

## Related issue number

https://github.com/microsoft/autogen/issues/5595
2025-02-18 13:38:35 -05:00
peterychang 8294c4c65e
Ollama client (#5553)
## Why are these changes needed?

Adds a client for ollama models

## Related issue number

https://github.com/microsoft/autogen/issues/5595

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-18 11:39:34 -05:00
Victor Dibia e02db84586
Improves editing UI for tools in AGS (#5539)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->
<img width="1560" alt="image"
src="https://github.com/user-attachments/assets/da3d781f-2572-4bd7-802d-1d3900f6c6d9"
/>

## Why are these changes needed?

Improves  editing UI for tools in AGS
- add remove tools 
- add/remove imports 
- show source code section of FunctionTool in  in code editor

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-18 01:24:43 +00:00
Ryan Sweet 9a10427a7d
bugfix exception issue 5580 (#5581)
## Why are these changes needed?

fixing intermittent bug #5580 

was using the wrong scheduler. 

## Related issue number

closes #5580
2025-02-17 15:46:22 -08:00
Reece Adamson 17888819c2
doc: fix typo (recpients -> recipients) (#5570)
## Why are these changes needed?

Just fixing a very minor typo I noticed while reading the docs.

`recpients` -> `recipients`
2025-02-17 16:17:29 +00:00
Ryan Sweet 48242f5255
adding initial docker support for agenthost (#5479)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-17 16:07:19 +00:00
Ryan Sweet 2a90731c44
improving doc comments (#5550)
adding some missing doc comments
2025-02-17 16:01:48 +00:00
Eric Zhu c76a68c780
Update website version (#5561) 2025-02-15 01:30:32 -08:00
Eric Zhu b04775f3dc
Update python version to v0.4.7 (#5558) 2025-02-14 20:08:38 -08:00
Eric Zhu 54681b2aec
fix: Add warning and doc for Windows event loop policy to avoid subprocess issues in web surfer and local executor (#5557) 2025-02-14 18:59:52 -08:00
Eric Zhu 80891b4841
doc & fix: Enhance AgentInstantiationContext with detailed documentation and examples for agent instantiation; Fix a but that caused value error when the expected class is not provided in register_factory (#5555)
Resolves #5519

Also spotted and fixed a bug that caused value error from `register_factory`, when the `expected_class` was not provided.
2025-02-14 18:19:32 -08:00
Eric Zhu 69c0b2b5ef
fix: Add model info validation and improve error messaging (#5556)
Introduce validation for the ModelInfo dictionary to ensure required
fields are present.

Resolves #5501
2025-02-14 18:09:33 -08:00
Jacob Alber 36da8f2af7
ci: Enable NuGet packaging of Core.Grpc and RuntimeGateway.Grpc (#5554) 2025-02-14 14:58:17 -08:00
Eric Zhu a1234bc658
doc: improve tool guide in Core API doc (#5546)
- Add a section on how to use model client with tools
- Replace the obsecure pattern of using ToolAgent with a simpler
implementation of calling tool within the agent itself.
2025-02-14 14:14:51 -08:00
Ryan Sweet acd7e86430
add a buffer to message delivery so that clients wh subscribe within a window can receive (#5543)
sometimes a client will subscribe but the message it was hoping for is
already published and delivered to one of its peers but it missed it.
this adds a five second (default) buffer and will deliver buffered
messages to new subscribers. messages are removed from the buffer after
5 seconds

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-02-14 07:42:18 -08:00
Jacob Alber 8029572f3f
fix: Unhandled Messages should not error when no deserializer is found (#5549)
Right now if a remote agent sends a message that local agents do not
listen to (and thus will never configure a deserializer for), or if the
first agent in the iteration is one such, the runtime will throw an
unnecessary exception an come down, even though the deserialized message
will never actually be needed before a deserializer is registered.

The fix will downgrade that to a warning.

* Also updates the HelloAgent sample to be more amenable to being used
with gRPC directly, without configuring environment variables.
2025-02-14 10:27:29 -05:00
Eric Zhu e7a3c78594
fix: Address tool call execution scenario when model produces empty tool call ids (#5509)
Resolves #5508
2025-02-13 23:11:44 -08:00
Ryan Sweet ff7f863e73
Improve e2e integration tests and isolate tests from other things; includes patch to Serializer (#5497)
* integration tests used to use the samples - now they are separate
* patch dictionary problem in serializer
* add Message Registry with dead letter queue that gets checked on new
subs.
2025-02-13 16:43:57 -08:00
gagb 3abc022ca9
fix: update help text for model configuration argument (#5533)
This pull request includes a small change to the
`python/packages/magentic-one-cli/src/magentic_one_cli/_m1.py` file. The
change modifies the help message for the `--config` argument to remove
the part about leaving it empty to print a sample configuration. This is
already handled by `--sample-config`.

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-13 16:07:32 -08:00
Eric Zhu 0355b228ce
fix: update 0.2 deployment workflow to use tag input instead of branch (#5536) 2025-02-13 14:18:49 -08:00
Victor Dibia e6423bb862
Make CodeExecutor Serializable/Declarative (#5527)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Make
[PythonCodeExecutionTool](https://github.com/microsoft/autogen/blob/main/python/packages/autogen-ext/src/autogen_ext/tools/code_execution/_code_execution.py)
declarative so it can be used in tools like AGS

Summary of changes

- Make CodeExecutor declarative (convert from Protocol to ABC, inherit
from ComponentBase)
- Make LocalCommandLineCodeExecutor, JupyterCodeExecutor and
DockerCommandLineCodeExecutor declarative , best effort. Not all fields
are serialized, warnings are shown where appropriate.
- Make PythonCodeExecutionTool declarative.

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

Closes #5526 
<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-13 13:50:11 -08:00
Jacob Alber 4e3b88784a
docs: Add Link (and redirect) to .NET docs (#5534)
Pulls the .NET Docs a bit more into the documentation website proper:

* Add a link from the 0.4-series Python docs to 
* Adds a transient redirect from /dotnet/ to /dotnet/dev/ to forward to
the dev docs until we do a non "-dev" release
2025-02-13 12:06:15 -08:00
Eric Zhu ec314c586c
feat: Add strict mode support to BaseTool, ToolSchema and FunctionTool (#5507)
Resolves #4447

For `openai` client's structured output support is through its beta
client, which requires the function JSON schema to be strict when in
structured output mode.

Reference:
https://platform.openai.com/docs/guides/function-calling#strict-mode
2025-02-13 19:44:55 +00:00
Ryan Sweet 970420885b
initial doc for xlang (#5476)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

adds some docs for xlang and .NET
2025-02-13 17:49:54 +00:00
Yosua Wijaya 20245b1c7e
Update custom-agents.ipynb (#5531)
Update AutoGen Studio link to stable page url
2025-02-13 16:55:56 +00:00
Ryan Sweet eb80286adf
remove noisy logging (#5446)
the uv sync logging in the test build was really noisy - no longer
needed
## Why are these changes needed?


## Related issue number


## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-13 00:57:03 +00:00
Jacob Alber 62954ea1cb
fix: Race condition between GrpcWorkerConnection open and agent type registration (#5521)
This finishes the fix for the race condition between opening a
GrpcWorkerConnection and registering agent types on that worker. Now,
instead of failing to register, we return from the call (with the
expectation that we will finish registration as we set up the
connection)

Part 1: #5494 
Part 2: #5514

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-02-12 19:51:49 -05:00
Xiaoyun Zhang 7f0acd78a8
.NET update global.json to use 9.0.100 (#5517)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-13 00:02:37 +00:00
Jacob Alber d9432510e4
fix: Switch HelloAgent to use agent_events.proto from the Agents project (#5512)
* There was an inconsistentcy between the package names that prevented
xlang from working even though the actual types were 1:1 compatible
* Also moves the HelloAgent aspire project into the Hello solution
folder
2025-02-12 18:37:42 -05:00
Wei Jen Lu 4765bca736
Fix class name style in document (#5516)
Fixed a wrong class name style in the document and removed trailing whitespace.

Co-authored-by: Wei Jen Lu <weijenlu@microsoft.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-12 14:57:02 -08:00
Victor Dibia 559aea9f5b
Update Model Client Docs to Mention API Key from Environment Variables (#5515)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

Adds the following blurb to the model clients docs

## API Keys From Environment Variables

In the examples above, we show that you can provide the API key through
the `api_key` argument. Importantly, the OpenAI and Azure OpenAI clients
use the [openai
package](3f8d8205ae/src/openai/__init__.py (L260)),
which will automatically read an api key from the environment variable
if one is not provided.

- For OpenAI, you can set the `OPENAI_API_KEY` environment variable.  
- For Azure OpenAI, you can set the `AZURE_OPENAI_API_KEY` environment
variable.

This is a good practice to explore, as it avoids including sensitive api
keys in your code.



## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-12 13:59:12 -08:00
Jacob Alber 676b611064
fix: Make race condition between channel open and RPC less likely to occur (#5514)
Right now we rely on opening the channel to associate a ClientId with an
entry on the gateway side. This causes a race when the channel is being
opened in the background while an RPC (e.g. MyAgent.register()) is
invoked.

If the RPC is processed first, the gateway rejects it due to "invalid"
clientId.

This fix makes this condition less likely to trigger, but there is still
a piece of the puzzle that needs to be solved on the Gateway side.
2025-02-12 16:40:52 -05:00
Victor Dibia f49f159a43
Support Component Validation API in AGS (#5503)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

It is useful to rapidly validate any changes to a team structure as
teams are built either via drag and drop or by modifying the underlying
spec

You can now “validate” your team. The key ideas are as follows
- Each team is based on some Component Config specification which is a
pedantic model underneath.
- Validation is 3 pronged based on a ValidatorService class 
    - Data model validation (validate component schema)
    - Instantiation validation (validate component can be instantiated)
- Provider validation, component_type validation (validate that provider
exists and can be imported)
- UX: each time a component is **loaded or saved**, it is automatically
validated and any errors shown (via a server endpoint). This way, the
developer immediately knows if updates to the configuration is wrong or
has errors.

> Note: this is different from actually running the component against a
task. Currently you can run the entire team. In a separate PR we will
implement ability to run/test other components.

<img width="1360" alt="image"
src="https://github.com/user-attachments/assets/d61095b7-0b07-463a-b4b2-5c50ded750f6"
/>

<img width="1368" alt="image"
src="https://github.com/user-attachments/assets/09a1677e-76e8-44a4-9749-15c27457efbb"
/>

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

Closes #4616 

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-12 17:29:43 +00:00
Jacob Alber 07fdc4e2da
fix: gRPC Agent Runtime Serialization Registration (#5513)
We were registering the serializers when we already had a concrete type
on the way into Publish or Send on the .NET side. However, in a xLang
scenario, messages could originate from e.g. Python before being
sent/published from .NET, resulting in no serializer being found.

This change adds a second-change registration and lookup when the agent
is instantiated based on the IHandle<T> implementations.
2025-02-12 12:12:07 -05:00
Eric Zhu 492b106b19
doc: API doc example for langchain database tool kit (#5498) 2025-02-11 20:15:07 -08:00
Eric Zhu cbc5d0241b
doc: Update AgentChat quickstart guide to enhance clarity and installation instructions (#5499)
Fix the installation instruction and add comments to the code.
2025-02-12 02:50:08 +00:00
Jack Gerrits e27f74ee8d
Reduce number of doc jobs for old releases (#5375)
We don't provide links to the dev releases on the site anymore, so let's
save some CI time and clutter

---------

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-11 22:52:12 +00:00
Jack Gerrits dc877d5737
Impl remove and get subscription APIs for python xlang (#5365)
Closes #5297

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
Co-authored-by: Jacob Alber <jaalber@microsoft.com>
Co-authored-by: Jacob Alber <jacob.alber@microsoft.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-11 14:42:09 -08:00
Jacob Alber 392aa14491
fix: Add deferral to RegisterAgentType and (Add/Remove)Subscription (#5494)
Unlike with the InProcessRuntime, there is a two-phase initialization,
first when AgentsApp is built (when initial agents are registered) and
when it StartAsync()s and connects to the Gateway. Unfortunately, it is
possible to attempt to send direct RPC calls to the Gateway before the
message channel is opened; in this case, the Gateway has no connected
client corresponding to the RPC's clientId, and falls over.

The fix is to defer registering agents and subscriptions with the
gateway until after the connection is established after .StartAsync() is
called.
2025-02-11 16:03:02 -05:00
Andrej Kyselica 540c4fb345
feat: DockerCommandLineCodeExecutor support for additional volume mounts, exposed host ports (#5383)
Add the following additional configuration options to
DockerCommandLineCodeExectutor:

- **extra_volumes** (Optional[Dict[str, Dict[str, str]]], optional): A
dictionary of extra volumes (beyond the work_dir) to mount to the
container. Defaults to None.
- **extra_hosts** (Optional[Dict[str, str]], optional): A dictionary of
host mappings to add to the container. (See Docker docs on extra_hosts)
Defaults to None.
- **init_command** (Optional[str], optional): A shell command to run
before each shell operation execution. Defaults to None. 

## Why are these changes needed?

See linked issue below.

In summary: Enable the agents to:
- work with a richer set of sys admin tools on top of code execution
- add support for a 'project' directory the agents can interact on
that's accessible by bash tools and custom scripts

## Related issue number

Closes #5363

## Checks

- [x] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.
2025-02-11 10:17:34 -08:00
Eric Zhu a9db38461f
doc: Update API doc for MCP tool to include installation instructions (#5482) 2025-02-10 23:55:13 -08:00
Eric Zhu f9d4a844df
Update website version v0.4.6 (#5481) 2025-02-10 16:49:00 -08:00
Victor Dibia cd085e6b89
Improve custom agentchat agent docs with model clients (gemini example) and serialization (#5468)
This PR improves documentation on custom agents 

- Shows example on how to create a custom agent that directly uses a
model client. In this case an example of a GeminiAssistantAgent that
directly uses the Gemini SDK model client.
- Shows that that CustomAgent can be easily added to any agentchat team 
- Shows how the same CustomAgent can be made declarative by inheriting
the Component interface and implementing the required methods.

Closes #5450
2025-02-10 16:29:43 -08:00
Jack Gerrits 2612796681
Implement control channel in python host servicer (#5427)
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-10 23:05:19 +00:00
Xiaoyun Zhang 9ceb5c05a7
[.NET] save chatHistory in another list to avoid duplicate messages (#5478)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->
Fix #4731 

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-10 21:13:55 +00:00
Eric Zhu 6db946bc89
doc: enhance extensions user guide with component examples (#5480) 2025-02-10 12:43:53 -08:00
Eitan Yarmush 8a9f452136
Adding declarative HTTP tools to autogen ext (#5181)
## Why are these changes needed?
These changes are needed because currently there's no generic way to add
`tools` to autogen studio workflows using the existing DSL and schema
other than inline python.

This API will be quite verbose, and lacks a discovery mechanism, but it
unlocks a lot of programmatic use-cases.

## Related issue number
https://github.com/microsoft/autogen/issues/5170

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-10 20:27:27 +00:00
Eric Zhu 9e15e9529c
doc: improve agent tutorial to include multi-modal input. (#5471)
Have seen discussion on Discord regarding confusion about multi-modal
support in v0.4. This change adds a small note on how to use multi-modal
messages with agents.
2025-02-10 11:29:25 -08:00
Eric Zhu 378b5ac09a
Update version to 0.4.6 (#5477) 2025-02-10 11:22:23 -08:00
Leonardo Pinheiro 50d7587a46
fix: Update SK kernel from tool to use method. (#5469)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->
The current implementation tries to recreate the metadata but it does it
in an incomplete way. This PR uses SK built-in kernel from function
decorator to infer the callable from the `run_json` and makes better use
of the pydantic schemas for the input and output to infer the schema of
the kernel function.

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #5458 

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Leonardo Pinheiro <lpinheiro@microsoft.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-10 16:34:54 +10:00
wistuba 7a772a2fcd
feat: add indictor for tool failure to FunctionExecutionResult (#5428)
Some LLMs recieve an explicit signal about tool use failures. 

Closes #5273

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-09 21:57:50 -08:00
Eric Zhu b8c5e499b3
doc: improve m1 docs, remove duplicates (#5460)
Resolves #5358

---------

Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-02-10 05:40:02 +00:00
Victor Dibia 340a8e8587
Add notes on api key and modifying specifications in AGS (#5466)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

Add clear notes on how to specify api key and modifying specifications
in AGS.
Add diagrams explaining how to switch between visual builder and JSON
mode

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->


![teambuilder](https://github.com/user-attachments/assets/9eede334-7f60-4c87-bec6-cf41839ba231)


## Related issue number

<!-- For example: "Closes #1234" -->

@nour-bouzid 

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-09 14:46:07 -08:00
Eric Zhu 9a028acf9f
feat: enhance Gemini model support in OpenAI client and tests (#5461) 2025-02-09 10:12:59 -08:00
Richárd Gyikó 5308b76d5f
Add MCP adapters to autogen-ext (#5251)
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-09 05:20:00 +00:00
Victor Dibia 7fc7f383f0
Enable LLM Call Observability in AGS (#5457)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

It is often helpful to inspect the raw request and response to/from an
LLM as agents act.
This PR, does the following:

- Updates TeamManager to yield LLMCallEvents from core library
- Run in an async background task to listen for LLMCallEvent JIT style
when a team is run
   - Add events to   an async queue and 
- yield those events in addition to whatever actual agentchat
team.run_stream yields.
- Update the AGS UI to show those LLMCallEvents in the messages section
as a team runs
   - Add settings panel to show/hide llm call events in messages. 
- Minor updates to default team

<img width="1539" alt="image"
src="https://github.com/user-attachments/assets/bfbb19fe-3560-4faa-b600-7dd244e0e974"
/>
<img width="1554" alt="image"
src="https://github.com/user-attachments/assets/775624f5-ba83-46e8-81ff-512bfeed6bab"
/>
<img width="1538" alt="image"
src="https://github.com/user-attachments/assets/3becbf85-b75a-4506-adb7-e5575ebbaec4"
/>


## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5440 

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-09 04:50:12 +00:00
Leonardo Pinheiro b868e32b05
fix: update SK adapter stream tool call processing. (#5449)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

The current stream processing of SK model adapter returns on the first
function call chunk but this behavior is incorrect end ends up returning
with an incomplete function call. The observed behavior is that the
function name and arguments are split into different chunks and this
update correctly processes the chunks in this way.

## Related issue number

<!-- For example: "Closes #1234" -->

Fixes the reply in #5420 

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Leonardo Pinheiro <lpinheiro@microsoft.com>
2025-02-09 14:39:19 +10:00
Eric Zhu b5eaab8501
fix & doc: update selector prompt documentation and remove validation checks (#5456) 2025-02-08 18:08:14 -08:00
Eric Zhu 15891e8cef
docs: enhance human-in-the-loop tutorial with FastAPI websocket example (#5455)
Added a websocket example and link to the sample directory.
2025-02-08 15:53:02 -08:00
Eric Zhu 426b898485
fix: improve speaker selection in SelectorGroupChat for weaker models (#5454)
Don't throw an exception when model makes a mistake. Use retries, and if
not succeeding after a fixed attempts, fall back to the previous sepaker
if available, or the first participant.

Resolves #5453
2025-02-08 23:13:46 +00:00
afourney 0b659de36d
Mitigates #5401 by optionally prepending names to messages. (#5448)
Mitigates #5401 by optionally prepending names to messages.

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-08 07:04:24 +00:00
Leonardo Pinheiro be085567ea
fix: remove sk tool adapter plugin name (#5444)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

Semantic kernel prepends the plugin name to the tool name when passing
the tools to model clients and this is causing a mismatch between tool
names in SK and the AssistantAgent. Since plugin names are optional, we
have opted to remove it.

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5420 

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Leonardo Pinheiro <lpinheiro@microsoft.com>
2025-02-08 04:54:05 +00:00
Ryan Sweet 51b601b6d8
re-add hello app host (#5445) 2025-02-07 22:59:38 -05:00
Ryan Sweet edbd20167b
bring back grpc service (#5377)
Restoring the grpc + Orleans server into the project

## Why are these changes needed?

This is the distributed agent runtime for .NET that can manage routing
messages amongst a fleet of grpc agent runtimes.

## Related issue number

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

---------

Co-authored-by: Jack Gerrits <jack@jackgerrits.com>
Co-authored-by: Jacob Alber <jaalber@microsoft.com>
2025-02-07 19:28:55 -05:00
Victor Dibia 9494ac97a0
AGS Improvements (Add Test Button in Team Builder View + Others) (#5416)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

- Add ability to test teams in Team Builder view 
- Update Gallery (add deep research default team, fix bug with gallery
serialization)
- UI fixes 
   -  improve drag drop component experience 
- improve new session experience (single click rather than 3 clicks to
create a session)
   - fix bug with stop reason not being shown in some cases

<img width="1738" alt="Image"
src="https://github.com/user-attachments/assets/4b895df2-3bad-474e-bec6-4fbcbf1c4346"
/>

<img width="1761" alt="Image"
src="https://github.com/user-attachments/assets/65f52eb9-e926-4168-88fb-d2496c159474"
/>

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

Closes #5392

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-07 23:37:44 +00:00
Rohan Thacker 73a7ba5764
Added the Claude family of models to ModelFamily (#5443)
Added the Claude family of models to the `ModelFamily` class. 

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-07 23:27:14 +00:00
Jacob Alber 9f1c4c924f
.NET AgentChat Part 1: Abstractions, Base Classes, RoundRobin (#5434)
Stands up an initial implementation of the AgentChat project, including abstractions, base classes, and the `RoundRobinGroupChat` implementation.
2025-02-07 17:57:08 -05:00
Eric Zhu 0008c9cb44
fix: do not count agent event in MaxMessageTermination condition (#5436)
Resolves #5425
2025-02-07 20:52:08 +00:00
abhijeethaval 707c3cf655
Update teams.ipynb : In the sample code the termination condition is set to the text "APPROVE" but the documentation mentions "TERMINATE" (#5426)
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-07 20:41:01 +00:00
Eric Zhu abdc0da4f1
Add sample chat application with FastAPI (#5433)
Introduce a sample chat application using AgentChat and FastAPI,
demonstrating single-agent and team chat functionalities, along with
state persistence and conversation history management.

Resolves #5423

---------

Co-authored-by: Victor Dibia <victor.dibia@gmail.com>
Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-02-07 20:17:56 +00:00
afourney f20ba9127d
M1 docker (#5437)
Presently MagenticOne and the m1 CLI use the LocalCommandLineExecutor
(presumably copied from the agbench code, which already runs in Docker).

This pr defaults m1 to Docker, and adds a code_executor parameter to
MagenticOne, which defaults to local for now to maintain backward
compatibility -- but this behavior is immediately deprecated.
2025-02-07 20:08:28 +00:00
Wei Jen Lu 5fcb3b8061
Fix typo in Swarm doc (#5435)
Fix typo in Swarm doc
2025-02-07 11:58:56 -08:00
so2liu 07c5dc7514
fix: streaming token mode cannot work in function calls and will infi… (#5396)
Fix: Prevent empty messages accumulation in streaming mode

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-07 10:42:27 -08:00
Eric Zhu 901ab1276d
feat: enhance AzureAIChatCompletionClient validation and add unit tests (#5417)
Resolves #5414
2025-02-07 18:32:14 +00:00
afourney af5dcc7fdf
Significant updates to agbench. (#5313)
- Updated HumanEval template to use AgentChat
- Update templates to use config.yaml for model and other configuration
- Read environment from ENV.yaml (ENV.json still supported but
deprecated)
- Temporarily removed WebArena and AssistantBench. Neither had viable
Templates after `autogen_magentic_one` was removed. Templates need to be
update to AgentChat (in a future PR, but this PR is getting big enough
already)
2025-02-07 18:01:44 +00:00
Jack Gerrits f7f5507c70
Split out GRPC tests (#5431) 2025-02-07 16:57:30 +00:00
Jack Gerrits 362d6a4e6b
Use a root json element instead of dict (#5430) 2025-02-07 11:52:37 -05:00
afourney 4c1c12d350
Flush console output after every message. (#5415) 2025-02-06 22:20:06 -08:00
afourney 3c30d8961e
Prompting changes to better support smaller models. (#5386)
A series of changes to the
`python/packages/autogen-ext/src/autogen_ext/agents/web_surfer/_multimodal_web_surfer.py`
file have been made to better support smaller models.

This includes changes to the prompts, state descriptions, and ordering
of messages.

Regression tasks with OpenAI models shows no change in GAIA scores,
while scores for Llama are significantly improved.
2025-02-06 17:47:55 -08:00
Eric Zhu 3b2bf82d15
feat: add integration workflow for testing multiple packages (#5412) 2025-02-06 16:59:31 -08:00
afourney 59e392cd0f
Get SelectorGroupChat working for Llama models. (#5409)
Get's SelectorGroupChat working for llama by:

1. Using a UserMessage rather than a SystemMessage
2. Normalizing how roles are presented (one agent per line)
3. Normalizing how the transcript is constructed (a blank line between
every message)
2025-02-06 16:03:17 -08:00
Griffin Bassman c8e4ad8242
feat: save/load test for dotnet agents (#5284) 2025-02-06 17:09:26 -05:00
Jack Gerrits 25f26a338b
Updates to proto for state apis (#5407) 2025-02-06 16:54:21 -05:00
Griffin Bassman da6f918708
feat: add dotnet code coverage (#5403) 2025-02-06 14:30:15 -05:00
Jack Gerrits ca428914f5
Refactor grpc channel connection in servicer (#5402) 2025-02-06 13:53:24 -05:00
afourney cf798aef3f
Various web surfer fixes. (#5393)
This PR fixes:

A prompting bug when no control had focus.
Awkward prompt phrasing.
Renamed page_down to scroll_down to better match other prompting and
agent descriptions.
2025-02-05 22:17:18 -08:00
afourney ac74305913
Ensure decriptions appear each on one line. Fix web_surfer's desc (#5390)
Some agent descriptions were split over multiple lines in the M1
orchestrator. This PR ensures that each description appears on one, and
only one, line. This makes it easier for smaller models to understand.
2025-02-05 20:17:24 -08:00
afourney d86540e9cd
Fix summarize_page in a text-only context, and for unknown models. (#5388)
WebSurfer's summarize_page was failing when the model was text-only, or
unknown.
2025-02-06 00:57:46 +00:00
Wei Jen Lu 7947464e4a
Fixed example code in doc:Custom Agents (#5381)
The Tuple class is never used in CountDownAgent class.

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [x] I've made sure all auto checks have passed.

Co-authored-by: Victor Dibia <victordibia@microsoft.com>
2025-02-06 00:52:32 +00:00
Eitan Yarmush 172a16a615
Memory component base (#5380)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Currently the way to accomplish RAG behavior with agent chat,
specifically assistant agents is with the memory interface, however
there is no way to configure it via the declarative API.

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Co-authored-by: Victor Dibia <chuvidi2003@gmail.com>
2025-02-05 16:07:27 -08:00
gagb be3c60baab
docs: add blog link to README for updates and resources (#5368)
#5080 

<img width="900" alt="image"
src="https://github.com/user-attachments/assets/bf8c32e5-8d66-43b7-a68a-2a3f9eb5c522"
/>
2025-02-05 18:35:52 +00:00
Griffin Bassman 442df18397
feat: dotnet runtime tests (#5342) 2025-02-05 13:02:43 -05:00
Jack Gerrits 08f9830bf7
Dotnet Grpc worker implementation (#5245)
Co-authored-by: Jacob Alber <jaalber@microsoft.com>
Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-02-05 08:34:02 -08:00
Wei Jen Lu 9030f75b4d
Fix typo (#5361)
Just fix typo

<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-05 09:57:39 -05:00
Leonardo Pinheiro 5c969d3f10
fix: add state management for oai assistant (#5352)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

To allow serialization of OAI Assistant Agent.

## Related issue number

<!-- For example: "Closes #1234" -->

Closes #5130 

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-04 21:56:30 +00:00
Eric Zhu 68cc2e1019
docs(python): add instructions for syncing dependencies and checking samples (#5362)
Address some common questions.
2025-02-04 19:35:51 +00:00
Jack Gerrits 40d74a32a1
Use proto descriptor for typename (#5346)
Closes #5302
2025-02-04 19:18:16 +00:00
Victor Dibia 6454e3fece
fix permission issue in ags windows (#5360)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Fix permission issue in ags windows (env files now stored in a user
directory)

<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->
Closes #5355
## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-04 10:23:46 -08:00
afourney cf6fa77273
Add text-only model support to M1 (#5344)
Modify M1 agents to support text-only settings.
This allows M1 to be used with models like o3-mini and Llama3.1+
2025-02-04 08:25:48 -08:00
afourney 517e3f000e
Assistant agent drop images when not provided with a vision-capable model. (#5351)
Allow AssistantAgent to drop images when not equipped with a multi-modal model.

Adds a corresponding utility function, which can be used in autogen-ext and teams, to accomplish the same.
2025-02-04 14:55:04 +00:00
Juan 5df5bde127
docs(core_distributed-group-chat): fix the typos in the docs in the README.md (#5347)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Wrong file names in the README.md

## Related issue number



## Checks

- [x] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

Co-authored-by: Mohammad Mazraeh <Mazraeh.Mohammad@Gmail.com>
2025-02-04 07:13:03 +00:00
Victor Dibia b89ca2a5ae
Fix warnings in AGS (#5320)
This PR does the following: 

- Fix warning messages in AGS on launch.
- Improve Cli message to include app URL on startup from command line
- Minor improvements default gallery generator. (add more default tools)
- Improve new session behaviour.



## Related issue number

Closes #5097

## Checks
2025-02-04 06:32:34 +00:00
Victor Dibia fbda70320d
Ensure ModelInfo field is serialized for OpenAIChatCompletionClient (#5315)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

Fix bug where the `model_info` field is not serialized for the
`OpenAIChatCompletionClient` class. This was because the `_raw_config`
field was based on a version of the args that had been sanitized
(model_info removed). We need the full model info field for non-openai
models

```python
from autogen_ext.agents.web_surfer import MultimodalWebSurfer
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_core.models import ModelInfo
mistral_vllm_model = OpenAIChatCompletionClient(
    model="TheBloke/Mistral-7B-Instruct-v0.2-GGUF",
    base_url="http://localhost:1234/v1",
    api_key="empty",
    model_info=ModelInfo(vision=False, function_calling=True, json_output=False, family="unkown"),
)
(mistral_vllm_model.dump_component().model_dump_json())
```

Before
```
{
  "provider": "autogen_ext.models.openai.OpenAIChatCompletionClient",
  "component_type": "model",
  "version": 1,
  "component_version": 1,
  "description": "Chat completion client for OpenAI hosted models.",
  "label": "OpenAIChatCompletionClient",
  "config": {
    "model": "TheBloke/Mistral-7B-Instruct-v0.2-GGUF",
    "api_key": "empty",
    "base_url": "http://localhost:1234/v1"
  }
}

```

After
```
{
  "provider": "autogen_ext.models.openai.OpenAIChatCompletionClient",
  "component_type": "model",
  "version": 1,
  "component_version": 1,
  "description": "Chat completion client for OpenAI hosted models.",
  "label": "OpenAIChatCompletionClient",
  "config": {
    "model": "TheBloke/Mistral-7B-Instruct-v0.2-GGUF",
    "api_key": "empty",
    "model_info": {
      "vision": false,
      "function_calling": true,
      "json_output": false,
      "family": "unkown"
    },
    "base_url": "http://localhost:1234/v1"
  }
}


```
<!-- Please give a short summary of the change and the problem this
solves. -->

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [ ] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.
2025-02-04 05:51:38 +00:00
afourney e8f49ef386
Fix reading string args from m1 cli (#5343)
After #5431 some command-line arguments became string rather than lists.
This PR fixes the issue by checking the type.
2025-02-03 13:27:37 -08:00
afourney cd88757cac
Allow m1 cli to read a configuration from a yaml file. (#5341)
Allow m1 cli to read a configuration from a yaml file.
2025-02-03 20:11:42 +00:00
razvanvalca 3d00457993
Adding o3 family: o3-mini (#5325)
## Why are these changes needed?
This pull request introduces the 'o3' model family and adds support for
the 'o3-mini' model.

---------

Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-03 18:57:21 +00:00
Mohammad Mazraeh 06c706633d
fix: warn on empty chunks, don't error out (#5332)
<!-- Thank you for your contribution! Please review
https://microsoft.github.io/autogen/docs/Contribute before opening a
pull request. -->

<!-- Please add a reviewer to the assignee section when you create a PR.
If you don't have the access to it, we will shortly find a reviewer and
assign them to your PR. -->

## Why are these changes needed?

<!-- Please give a short summary of the change and the problem this
solves. -->

We are seeing this issue more often now, probably related to the load on
the API servers. Hence this PR:
1. Demotes the the `max_consecutive_empty_chunk_tolerance` parameter
from function to inline threshold
2. Change exception to a one time warning

## Related issue number

<!-- For example: "Closes #1234" -->

## Checks

- [x] I've included any doc changes needed for
https://microsoft.github.io/autogen/. See
https://microsoft.github.io/autogen/docs/Contribute#documentation to
build and test documentation locally.
- [x] I've added tests (if relevant) corresponding to the changes
introduced in this PR.
- [ ] I've made sure all auto checks have passed.

---------

Signed-off-by: Mohammad Mazraeh <mazraeh.mohammad@gmail.com>
Co-authored-by: Eric Zhu <ekzhu@users.noreply.github.com>
2025-02-03 18:45:29 +00:00
Eric Zhu 569bc19769
feat: add gemini model families, enhance group chat selection for Gemini model and add tests (#5334)
Resolves #5322
2025-02-03 18:32:35 +00:00
Griffin Bassman 9af6883fbe
fix: dotnet test CI and standardize test categories (#5286)
Co-authored-by: Ryan Sweet <rysweet@microsoft.com>
2025-02-03 11:49:08 -05:00
afourney 877796ded1
WebSurfer: print viewport text (#5329)
This PR adds a method that approximately extracts the text visible in
the viewport of the web browser (as opposed to always printing the first
50 lines, or relying entirely on OCR).
2025-02-03 11:42:18 -05:00
Eric Zhu 227b875f28
Update Python website to v0.4.5 (#5316) 2025-01-31 20:01:51 -08:00
870 changed files with 71923 additions and 16625 deletions

View File

@ -1,5 +1,5 @@
# Note: You can use any Debian/Ubuntu based image you want.
FROM mcr.microsoft.com/devcontainers/universal:2
FROM mcr.microsoft.com/devcontainers/base:ubuntu
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \

View File

@ -20,7 +20,10 @@
},
"ghcr.io/elanhasson/devcontainer-features/dotnet-aspire-daily:1": {},
"ghcr.io/devcontainers/features/azure-cli:1": {},
"ghcr.io/azure/azure-dev/azd:0": {}
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/dotnet:2": {},
"ghcr.io/azure/azure-dev/azd:0": {},
"ghcr.io/devcontainers/features/python:1": {}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

171
.github/ISSUE_TEMPLATE/1-bug_report.yml vendored Normal file
View File

@ -0,0 +1,171 @@
name: 🐛 Bug Report
description: Report a bug
type: "bug"
labels:
- needs-triage
body:
- type: markdown
attributes:
value: |
## Please Read the following before submitting an issue.
### Have you read the docs?
- [Python AgentChat User Guide and Tutorial](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/index.html)
- [Python Core API User Guide](https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/index.html)
- [Python API Doc](https://microsoft.github.io/autogen/stable/reference/index.html)
- [.NET Doc](https://microsoft.github.io/autogen/dotnet/)
### Have you searched for related issues?
- Some other users might have the same issue as yours.
### Are you familiar with GitHub Markdown Syntax?
Please use [GitHub Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax)
syntax to format your input.
Pay attention to code blocks. Use "```" blocks for code and output.
For examples:
````
```python
# your Python code here.
```
````
````
```bash
# your bash shell command here.
```
````
If your output contains "```", use "````" (four "`") to escape them.
You can use the "Preview" switcher to check your formatted output.
- type: textarea
attributes:
label: What happened?
description: Please provide as much information as possible, this helps us address the issue. Use Markdown to format your text.
value: |
**Describe the bug**
A clear and concise description of what the bug is.
If it is a question or suggestion, please use [Discussions](https://github.com/microsoft/autogen/discussions)
instead.
**To Reproduce**
Steps to reproduce the behavior. Please include code and outputs such as stacktrace.
- If your input is just "I tried X, and it didn't work" or
"X is not working", your issue will be ignored.
- If your input is not well formatted, it will hurt readability and
may be ignored as well.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
validations:
required: true
- type: dropdown
attributes:
label: Which packages was the bug in?
multiple: true
options:
- Python Core (autogen-core)
- Python AgentChat (autogen-agentchat>=0.4.0)
- Python Extensions (autogen-ext)
- .NET Core (Microsoft.AutoGen.Core)
- AutoGen Studio (autogensudio)
- AutoGen Bench (agbench)
- Magentic One CLI (magentic-one-cli)
- V0.2 (autogen-agetnchat==0.2.*)
validations:
required: true
- type: dropdown
attributes:
label: AutoGen library version.
description: What is the version of the library was used.
multiple: false
options:
- "Python dev (main branch)"
- "Python 0.5.2"
- "Python 0.5.1"
- "Python 0.4.9"
- "Python 0.4.8"
- "Python 0.4.7"
- "Python 0.4.6"
- "Python 0.4.5"
- "Python 0.4.4"
- "Python 0.4.3"
- "Python 0.4.2"
- "Python 0.4.1"
- "Python 0.4.0"
- ".NET dev (main branch)"
- "Studio 0.4.1"
- "Studio 0.4.0"
- "Other (please specify)"
validations:
required: True
- type: input
attributes:
label: Other library version.
description: "Please specify if selected 'Other' above"
- type: input
attributes:
label: Model used
description: If a model was used, please name here. Use full model name with version number.
placeholder: "e.g., gpt-4o-2024-11-20"
- type: dropdown
attributes:
label: Model provider
description: The provider or hosting service that runs the model.
options:
- "Anthropic"
- "AWS Bedrock"
- "Azure OpenAI"
- "Azure AI Foundary (Azure AI Studio)"
- "DeepSeek (Hosted)"
- "GitHub Models"
- "Google Gemini"
- "Google Vertex AI"
- "HuggingFace Models (Hosted)"
- "HuggingFace Transformers (Local)"
- "LlamaCpp"
- "Mistral AI"
- "Ollama"
- "OpenAI"
- "OpenRouter"
- "Together AI"
- "vLLM"
- "Other (please specify below)"
- type: input
attributes:
label: Other model provider
description: "Other provider if not found above."
- type: dropdown
attributes:
label: Python version
options:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- Other (please note we only support Python 3.10+)
- type: dropdown
attributes:
label: .NET version
options:
- ".NET 9"
- ".NET 8"
- type: dropdown
attributes:
label: Operating system
options:
- Windows
- MacOS
- Ubuntu
- Fedora
- CentOS
- Other

47
.github/ISSUE_TEMPLATE/2-doc_issue.yml vendored Normal file
View File

@ -0,0 +1,47 @@
name: 📘 Doc Issue
description: Report an issue in the documentation, including missing or incorrect information.
type: "bug"
labels:
- needs-triage
- documentation
body:
- type: markdown
attributes:
value: |
## Please Read the following before submitting an issue.
### Have you read the docs?
- [Python AgentChat User Guide and Tutorial](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/index.html)
- [Python Core API User Guide](https://microsoft.github.io/autogen/stable/user-guide/core-user-guide/index.html)
- [Python API Doc](https://microsoft.github.io/autogen/stable/reference/index.html)
- [.NET Doc](https://microsoft.github.io/autogen/dotnet/)
### Have you searched for related issues?
- Some other users might have the same issue as yours.
- type: textarea
attributes:
label: What is the doc issue?
description: Please provide as much information as possible, this helps us address the issue. Use Markdown to format your text.
value: |
**Describe the issue**
A clear and concise description of what the issue is. What is missing or incorrect?
**What do you want to see in the doc?**
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
Add any other context about the problem here.
validations:
required: true
- type: input
id: doc-link
attributes:
label: Link to the doc page, if applicable
description: Please provide a link to the doc page that has the issue.
placeholder: https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/index.html
validations:
required: true

View File

@ -0,0 +1,20 @@
name: 🔒 Maintainer Only
description: Only use this template if you are a maintainer.
body:
- type: checkboxes
attributes:
label: Confirmation
description: Please only use this template if you are a maintainer. Thanks for helping us keep the issue tracker organized!
options:
- label: I confirm that I am a maintainer and so can use this template. If I am not, I understand this issue will be closed and I will be asked to use a different template.
required: true
- type: textarea
id: body
attributes:
label: Issue body
description: "How do you trigger this bug? Please walk us through it step by step."
validations:
required: true

View File

@ -1,55 +0,0 @@
name: Bug Report
description: Report a bug
type: "bug"
body:
- type: textarea
attributes:
label: What happened?
description: Please provide as much information as possible, this helps us address the issue.
validations:
required: true
- type: textarea
attributes:
label: What did you expect to happen?
validations:
required: true
- type: textarea
attributes:
label: How can we reproduce it (as minimally and precisely as possible)?
description: Please provide steps to reproduce. Provide code that can be run if possible.
validations:
required: true
- type: input
attributes:
label: AutoGen version
description: What version or commit of the library was used
validations:
required: true
- type: dropdown
attributes:
label: Which package was this bug in
options:
- Core
- AgentChat
- Extensions
- AutoGen Studio
- Magentic One
- AutoGen Bench
- Other
validations:
required: true
- type: input
attributes:
label: Model used
description: If a model was used, please describe it here, indicating whether it is a local model or a cloud-hosted model
placeholder: gpt-4, mistral-7B etc
- type: input
attributes:
label: Python version
- type: input
attributes:
label: Operating system
- type: textarea
attributes:
label: Any additional info you think would be helpful for fixing this bug

View File

@ -1,5 +1,8 @@
blank_issues_enabled: true
blank_issues_enabled: false
contact_links:
- name: Questions or general help 💬
- name: 💬 Questions or general help
url: https://github.com/microsoft/autogen/discussions
about: Please ask and answer questions here.
- name: 💡 Suggest a new feature
url: https://github.com/microsoft/autogen/discussions/categories/feature-suggestions
about: Please suggest new features here and once the feature is accepted a maintainer will create an issue.

View File

@ -1,18 +0,0 @@
name: Feature Request
description: Request a new feature or enhancement
type: "feature"
body:
- type: textarea
attributes:
label: What feature would you like to be added?
description: Please describe the desired feature. Be descriptive, provide examples and if possible, provide a proposed solution.
validations:
required: true
- type: textarea
attributes:
label: Why is this needed?
description: Why is it important that this feature is implemented? What problem or need does it solve?
validations:
required: true

View File

@ -12,6 +12,6 @@
## Checks
- [ ] I've included any doc changes needed for https://microsoft.github.io/autogen/. See https://microsoft.github.io/autogen/docs/Contribute#documentation to build and test documentation locally.
- [ ] I've included any doc changes needed for <https://microsoft.github.io/autogen/>. See <https://github.com/microsoft/autogen/blob/main/CONTRIBUTING.md> to build and test documentation locally.
- [ ] I've added tests (if relevant) corresponding to the changes introduced in this PR.
- [ ] I've made sure all auto checks have passed.

View File

@ -149,9 +149,79 @@ jobs:
name: coverage-${{ env.PKG_NAME }}
path: ./python/coverage_${{ env.PKG_NAME }}.xml
test-grpc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
version: "0.5.18"
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Run uv sync
run: |
uv sync --locked --all-extras
working-directory: ./python
- name: Run task
run: |
source ${{ github.workspace }}/python/.venv/bin/activate
poe --directory ./packages/autogen-ext test-grpc
working-directory: ./python
- name: Move coverage file
run: |
mv ./packages/autogen-ext/coverage.xml coverage_autogen-ext-grpc.xml
working-directory: ./python
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-autogen-ext-grpc
path: ./python/coverage_autogen-ext-grpc.xml
test-autogen-ext-pwsh:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
version: "0.5.18"
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install Python deps
run: |
uv sync --locked --all-extras
shell: pwsh
working-directory: ./python
- name: Run tests for Windows
run: |
.venv/Scripts/activate.ps1
poe --directory ./packages/autogen-ext test-windows
shell: pwsh
working-directory: ./python
- name: Move coverage file
run: |
mv ./packages/autogen-ext/coverage.xml coverage_autogen_ext_windows.xml
working-directory: ./python
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-autogen-ext-windows
path: ./python/coverage_autogen_ext_windows.xml
codecov:
runs-on: ubuntu-latest
needs: [test]
needs: [test, test-grpc]
strategy:
matrix:
package:
@ -159,6 +229,7 @@ jobs:
"./packages/autogen-core",
"./packages/autogen-ext",
"./packages/autogen-agentchat",
"autogen-ext-grpc",
]
steps:
- uses: actions/checkout@v4

View File

@ -106,6 +106,11 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- if: matrix.build-mode == 'manual'
name: Setup .NET 9.0
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- if: matrix.build-mode == 'manual'
shell: bash
working-directory: dotnet

View File

@ -33,26 +33,19 @@ jobs:
[
# For main use the workflow target
{ ref: "${{github.ref}}", dest-dir: dev, uv-version: "0.5.13", sphinx-release-override: "dev" },
{ ref: "v0.4.4", dest-dir: stable, uv-version: "0.5.13", sphinx-release-override: "stable" },
{ ref: "v0.4.0.dev0", dest-dir: "0.4.0.dev0", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev1", dest-dir: "0.4.0.dev1", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev2", dest-dir: "0.4.0.dev2", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev3", dest-dir: "0.4.0.dev3", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev4", dest-dir: "0.4.0.dev4", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev5", dest-dir: "0.4.0.dev5", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev6", dest-dir: "0.4.0.dev6", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev7", dest-dir: "0.4.0.dev7", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev8", dest-dir: "0.4.0.dev8", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev9", dest-dir: "0.4.0.dev9", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev10", dest-dir: "0.4.0.dev10", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev11", dest-dir: "0.4.0.dev11", uv-version: "0.5.11", sphinx-release-override: "" },
{ ref: "v0.4.0.dev12", dest-dir: "0.4.0.dev12", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "v0.4.0.dev13", dest-dir: "0.4.0.dev13", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "python-v0.5.2", dest-dir: stable, uv-version: "0.5.13", sphinx-release-override: "stable" },
{ ref: "v0.4.0.post1", dest-dir: "0.4.0", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "v0.4.1", dest-dir: "0.4.1", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "v0.4.2", dest-dir: "0.4.2", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "v0.4.3", dest-dir: "0.4.3", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "v0.4.4", dest-dir: "0.4.4", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "python-v0.4.5", dest-dir: "0.4.5", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "python-v0.4.6", dest-dir: "0.4.6", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "python-v0.4.7", dest-dir: "0.4.7", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "python-v0.4.8", dest-dir: "0.4.8", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "python-v0.4.9-website", dest-dir: "0.4.9", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "python-v0.5.1", dest-dir: "0.5.1", uv-version: "0.5.13", sphinx-release-override: "" },
{ ref: "python-v0.5.2", dest-dir: "0.5.2", uv-version: "0.5.13", sphinx-release-override: "" },
]
steps:
- name: Checkout

View File

@ -46,8 +46,9 @@ jobs:
- name: workflows has changes
run: echo "workflows has changes"
if: steps.filter.outputs.workflows == 'true'
build:
name: Dotnet Build
name: Dotnet Build & Test
needs: paths-filter
if: needs.paths-filter.outputs.hasChanges == 'true'
defaults:
@ -64,22 +65,13 @@ jobs:
- uses: actions/checkout@v4
with:
lfs: true
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install jupyter and ipykernel
run: |
python -m pip install --upgrade pip
python -m pip install jupyter
python -m pip install ipykernel
- name: list available kernels
run: |
python -m jupyter kernelspec list
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
version: "0.5.18"
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: uv sync --locked --all-extras
working-directory: ./python
- name: Prepare python venv
@ -89,10 +81,12 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Setup .NET 9.0
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: Restore dependencies
run: |
# dotnet nuget add source --name dotnet-tool https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json --configfile NuGet.config
dotnet restore -bl
run: dotnet restore -bl
- name: Format check
run: |
echo "Format check"
@ -102,8 +96,45 @@ jobs:
run: |
echo "Build AutoGen"
dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true
- name: Unit Test
run: dotnet test --no-build -bl --configuration Release --filter type=!integration
- name: Unit Test V1
run: dotnet test --no-build -bl --configuration Release --filter "Category=UnitV1"
- name: Unit Test V2 (With Coverage)
run: dotnet test --no-build -bl --configuration Release --filter "Category=UnitV2" --collect:"XPlat Code Coverage"
- name: Install Dev Certs for GRPC
if: matrix.os == 'ubuntu-latest'
run: dotnet dev-certs https --trust
- name: GRPC Tests (With Coverage)
if: matrix.os == 'ubuntu-latest'
run: dotnet test --no-build -bl --configuration Release --filter "Category=GRPC" --collect:"XPlat Code Coverage"
- name: Generate & Merge Coverage Report
if: matrix.os == 'ubuntu-latest'
run: |
# Install reportgenerator
dotnet tool install -g dotnet-reportgenerator-globaltool || dotnet tool update -g dotnet-reportgenerator-globaltool
# Ensure output directory exists
mkdir -p ${{ github.workspace }}/dotnet/coverage-report
# Merge all coverage reports and generate HTML + XML
reportgenerator \
-reports:${{ github.workspace }}/dotnet/**/TestResults/**/coverage.cobertura.xml \
-targetdir:${{ github.workspace }}/dotnet/coverage-report \
-reporttypes:"Cobertura;Html"
ls -R ${{ github.workspace }}/dotnet/coverage-report
- name: Upload Merged Coverage Report
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: CodeCoverageReport
path: ${{ github.workspace }}/dotnet/coverage-report/
retention-days: 7
- name: Upload Coverage to Codecov
if: matrix.os == 'ubuntu-latest'
uses: codecov/codecov-action@v5
with:
files: ${{ github.workspace }}/dotnet/coverage-report/*.xml
flags: unittests
name: dotnet-codecov
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
integration-test:
strategy:
@ -142,7 +173,7 @@ jobs:
dotnet-version: '9.0.x'
- name: Install Temp Global.JSON
run: |
echo "{\"sdk\": {\"version\": \"9.0.101\"}}" > global.json
echo "{\"sdk\": {\"version\": \"9.0\"}}" > global.json
- name: Install .NET Aspire workload
run: dotnet workload install aspire
- name: Install dev certs
@ -155,7 +186,7 @@ jobs:
echo "Build AutoGen"
dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true
- name: Integration Test
run: dotnet --version && dotnet test --no-build -bl --configuration Release --filter type=integration
run: dotnet --version && dotnet test --no-build -bl --configuration Release --filter "Category=Integration"
- name: Restore the global.json
run: rm global.json && git checkout -- global.json
@ -180,6 +211,10 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Setup .NET 9.0
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: publish AOT testApp, assert static analysis warning count, and run the app
shell: pwsh
@ -222,6 +257,12 @@ jobs:
with:
dotnet-version: '8.0.x'
global-json-file: dotnet/global.json
- name: Setup .NET 9.0
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.0.x'
- name: Install dev certs
run: dotnet --version && dotnet dev-certs https --trust
- name: Restore dependencies
run: |
dotnet restore -bl

View File

@ -52,6 +52,7 @@ jobs:
run: |
echo "Build AutoGen"
dotnet build --no-restore --configuration Release -bl /p:SignAssembly=true
- run: sudo dotnet dev-certs https --trust --no-password
- name: Unit Test
run: dotnet test --no-build -bl --configuration Release
env:

55
.github/workflows/integration.yml vendored Normal file
View File

@ -0,0 +1,55 @@
name: Integration
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to run tests'
required: true
type: string
jobs:
test:
runs-on: ubuntu-latest
environment: integration
strategy:
matrix:
package:
[
"./packages/autogen-core",
"./packages/autogen-ext",
"./packages/autogen-agentchat",
]
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch }}
- uses: astral-sh/setup-uv@v5
with:
enable-cache: true
version: "0.5.18"
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Run uv sync
run: |
uv sync --locked --all-extras
echo "PKG_NAME=$(basename '${{ matrix.package }}')" >> $GITHUB_ENV
working-directory: ./python
- name: Run task
run: |
source ${{ github.workspace }}/python/.venv/bin/activate
poe --directory ${{ matrix.package }} test
working-directory: ./python
- name: Move coverage file
run: |
mv ${{ matrix.package }}/coverage.xml coverage_${{ env.PKG_NAME }}.xml
working-directory: ./python
- name: Upload coverage artifact
uses: actions/upload-artifact@v4
with:
name: coverage-${{ env.PKG_NAME }}
path: ./python/coverage_${{ env.PKG_NAME }}.xml

View File

@ -1,18 +0,0 @@
name: Label issues with needs-triage
on:
issues:
types:
- reopened
- opened
jobs:
label_issues:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- run: gh issue edit "$NUMBER" --add-label "$LABELS"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.issue.number }}
LABELS: needs-triage

View File

@ -6,10 +6,9 @@ on:
- "0.2.*"
workflow_dispatch:
inputs:
branch:
description: 'Branch to deploy the package'
tag:
description: 'Tag to deploy the package'
required: true
default: '0.2'
permissions: {}
jobs:
deploy:
@ -27,7 +26,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.branch }}
ref: ${{ github.event.inputs.tag }}
- name: Build
shell: pwsh
run: |

5
.gitignore vendored
View File

@ -198,4 +198,7 @@ notebook/coding
artifacts
# project data
registry.json
registry.json
# files created by the gitty agent in python/samples/gitty
.gitty/

View File

@ -34,7 +34,7 @@ For common tasks that are helpful during development and run in CI, see [here](.
## Roadmap
We use GitHub issues and milestones to track our roadmap. You can view the upcoming milestones [here]([Roadmap Issues](https://aka.ms/autogen-roadmap).
We use GitHub issues and milestones to track our roadmap. You can view the upcoming milestones [here]([Roadmap Issues](https://aka.ms/autogen-roadmap)).
## Versioning
@ -48,11 +48,11 @@ We will update verion numbers according to the following rules:
## Release process
1. Create a PR that updates the version numbers across the codebase ([example](https://github.com/microsoft/autogen/pull/4359))
2. The docs CI will fail for the PR, but this is expected and will be resolved in the next step
2. After merging the PR, create and push a tag that corresponds to the new verion. For example, for `0.4.0.dev13`:
2. The docs CI will fail for the PR, but this is expected and will be resolved in the next step
3. After merging the PR, create and push a tag that corresponds to the new verion. For example, for `0.4.0.dev13`:
- `git tag v0.4.0.dev13 && git push origin v0.4.0.dev13`
3. Restart the docs CI by finding the failed [job corresponding to the `push` event](https://github.com/microsoft/autogen/actions/workflows/docs.yml) and restarting all jobs
4. Run [this](https://github.com/microsoft/autogen/actions/workflows/single-python-package.yml) workflow for each of the packages that need to be released and get an approval for the release for it to run
4. Restart the docs CI by finding the failed [job corresponding to the `push` event](https://github.com/microsoft/autogen/actions/workflows/docs.yml) and restarting all jobs
5. Run [this](https://github.com/microsoft/autogen/actions/workflows/single-python-package.yml) workflow for each of the packages that need to be released and get an approval for the release for it to run
## Triage process

View File

@ -7,9 +7,14 @@
[![LinkedIn](https://img.shields.io/badge/LinkedIn-Company?style=flat&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/105812540)
[![Discord](https://img.shields.io/badge/discord-chat-green?logo=discord)](https://aka.ms/autogen-discord)
[![Documentation](https://img.shields.io/badge/Documentation-AutoGen-blue?logo=read-the-docs)](https://microsoft.github.io/autogen/)
[![Blog](https://img.shields.io/badge/Blog-AutoGen-blue?logo=blogger)](https://devblogs.microsoft.com/autogen/)
</div>
<div align="center" style="background-color: rgba(255, 235, 59, 0.5); padding: 10px; border-radius: 5px; margin: 20px 0;">
<strong>Important:</strong> This is the official project. We are not affiliated with any fork or startup. See our <a href="https://x.com/pyautogen/status/1857264760951296210">statement</a>.
</div>
# AutoGen
**AutoGen** is a framework for creating multi-agent AI applications that can act autonomously or work alongside humans.
@ -42,22 +47,24 @@ from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
async def main() -> None:
agent = AssistantAgent("assistant", OpenAIChatCompletionClient(model="gpt-4o"))
model_client = OpenAIChatCompletionClient(model="gpt-4o")
agent = AssistantAgent("assistant", model_client=model_client)
print(await agent.run(task="Say 'Hello World!'"))
await model_client.close()
asyncio.run(main())
```
### Team
### Web Browsing Agent Team
Create a group chat team with an assistant agent, a web surfer agent, and a user proxy agent
Create a group chat team with a web surfer agent and a user proxy agent
for web browsing tasks. You need to install [playwright](https://playwright.dev/python/docs/library).
```python
# pip install -U autogen-agentchat autogen-ext[openai,web-surfer]
# playwright install
import asyncio
from autogen_agentchat.agents import AssistantAgent, UserProxyAgent
from autogen_agentchat.agents import UserProxyAgent
from autogen_agentchat.conditions import TextMentionTermination
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.ui import Console
@ -66,12 +73,21 @@ from autogen_ext.agents.web_surfer import MultimodalWebSurfer
async def main() -> None:
model_client = OpenAIChatCompletionClient(model="gpt-4o")
assistant = AssistantAgent("assistant", model_client)
web_surfer = MultimodalWebSurfer("web_surfer", model_client)
# The web surfer will open a Chromium browser window to perform web browsing tasks.
web_surfer = MultimodalWebSurfer("web_surfer", model_client, headless=False, animate_actions=True)
# The user proxy agent is used to get user input after each step of the web surfer.
# NOTE: you can skip input by pressing Enter.
user_proxy = UserProxyAgent("user_proxy")
termination = TextMentionTermination("exit") # Type 'exit' to end the conversation.
team = RoundRobinGroupChat([web_surfer, assistant, user_proxy], termination_condition=termination)
await Console(team.run_stream(task="Find information about AutoGen and write a short summary."))
# The termination condition is set to end the conversation when the user types 'exit'.
termination = TextMentionTermination("exit", sources=["user_proxy"])
# Web surfer and user proxy take turns in a round-robin fashion.
team = RoundRobinGroupChat([web_surfer, user_proxy], termination_condition=termination)
try:
# Start the team and wait for it to terminate.
await Console(team.run_stream(task="Find information about AutoGen and write a short summary."))
finally:
await web_surfer.close()
await model_client.close()
asyncio.run(main())
```
@ -96,7 +112,7 @@ The AutoGen ecosystem provides everything you need to create AI agents, especial
The _framework_ uses a layered and extensible design. Layers have clearly divided responsibilities and build on top of layers below. This design enables you to use the framework at different levels of abstraction, from high-level APIs to low-level components.
- [Core API](./python/packages/autogen-core/) implements message passing, event-driven agents, and local and distributed runtime for flexibility and power. It also support cross-language support for .NET and Python.
- [AgentChat API](./python/packages/autogen-agentchat/) implements a simpler but opinionated API rapid for prototyping. This API is built on top of the Core API and is closest to what users of v0.2 are familiar with and supports familiar multi-agent patterns such as two-agent chat or group chats.
- [AgentChat API](./python/packages/autogen-agentchat/) implements a simpler but opinionated API for rapid prototyping. This API is built on top of the Core API and is closest to what users of v0.2 are familiar with and supports common multi-agent patterns such as two-agent chat or group chats.
- [Extensions API](./python/packages/autogen-ext/) enables first- and third-party extensions continuously expanding framework capabilities. It support specific implementation of LLM clients (e.g., OpenAI, AzureOpenAI), and capabilities such as code execution.
The ecosystem also supports two essential _developer tools_:
@ -108,7 +124,7 @@ The ecosystem also supports two essential _developer tools_:
- [AutoGen Studio](./python/packages/autogen-studio/) provides a no-code GUI for building multi-agent applications.
- [AutoGen Bench](./python/packages/agbench/) provides a benchmarking suite for evaluating agent performance.
You can use the AutoGen framework and developer tools to create applications for your domain. For example, [Magentic-One](./python/packages/magentic-one-cli/) is a state-of-art multi-agent team built using AgentChat API and Extensions API that can handle variety of tasks that require web browsing, code execution, and file handling.
You can use the AutoGen framework and developer tools to create applications for your domain. For example, [Magentic-One](./python/packages/magentic-one-cli/) is a state-of-the-art multi-agent team built using AgentChat API and Extensions API that can handle a variety of tasks that require web browsing, code execution, and file handling.
With AutoGen you get to join and contribute to a thriving ecosystem. We host weekly office hours and talks with maintainers and community. We also have a [Discord server](https://aka.ms/autogen-discord) for real-time chat, GitHub Discussions for Q&A, and a blog for tutorials and updates.
@ -118,19 +134,18 @@ With AutoGen you get to join and contribute to a thriving ecosystem. We host wee
| | [![Python](https://img.shields.io/badge/AutoGen-Python-blue?logo=python&logoColor=white)](./python) | [![.NET](https://img.shields.io/badge/AutoGen-.NET-green?logo=.net&logoColor=white)](./dotnet) | [![Studio](https://img.shields.io/badge/AutoGen-Studio-purple?logo=visual-studio&logoColor=white)](./python/packages/autogen-studio) |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Installation | [![Installation](https://img.shields.io/badge/Install-blue)](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/installation.html) | \* | [![Install](https://img.shields.io/badge/Install-purple)](https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/installation.html) |
| Quickstart | [![Quickstart](https://img.shields.io/badge/Quickstart-blue)](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/quickstart.html#) | \* | [![Usage](https://img.shields.io/badge/Quickstart-blue)](https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/usage.html#) |
| Tutorial | [![Tutorial](https://img.shields.io/badge/Tutorial-blue)](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/tutorial/index.html) | \* | [![Usage](https://img.shields.io/badge/Quickstart-blue)](https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/usage.html#) |
| API Reference | [![API](https://img.shields.io/badge/Docs-blue)](https://microsoft.github.io/autogen/stable/reference/index.html#) | \* | [![API](https://img.shields.io/badge/Docs-purple)](https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/usage.html) |
| Packages | [![PyPi autogen-core](https://img.shields.io/badge/PyPi-autogen--core-blue?logo=pypi)](https://pypi.org/project/autogen-core/) <br> [![PyPi autogen-agentchat](https://img.shields.io/badge/PyPi-autogen--agentchat-blue?logo=pypi)](https://pypi.org/project/autogen-agentchat/) <br> [![PyPi autogen-ext](https://img.shields.io/badge/PyPi-autogen--ext-blue?logo=pypi)](https://pypi.org/project/autogen-ext/) | \* | [![PyPi autogenstudio](https://img.shields.io/badge/PyPi-autogenstudio-purple?logo=pypi)](https://pypi.org/project/autogenstudio/) |
| Installation | [![Installation](https://img.shields.io/badge/Install-blue)](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/installation.html) | [![Install](https://img.shields.io/badge/Install-green)](https://microsoft.github.io/autogen/dotnet/dev/core/installation.html) | [![Install](https://img.shields.io/badge/Install-purple)](https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/installation.html) |
| Quickstart | [![Quickstart](https://img.shields.io/badge/Quickstart-blue)](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/quickstart.html#) | [![Quickstart](https://img.shields.io/badge/Quickstart-green)](https://microsoft.github.io/autogen/dotnet/dev/core/index.html) | [![Usage](https://img.shields.io/badge/Quickstart-purple)](https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/usage.html#) |
| Tutorial | [![Tutorial](https://img.shields.io/badge/Tutorial-blue)](https://microsoft.github.io/autogen/stable/user-guide/agentchat-user-guide/tutorial/index.html) | [![Tutorial](https://img.shields.io/badge/Tutorial-green)](https://microsoft.github.io/autogen/dotnet/dev/core/tutorial.html) | [![Usage](https://img.shields.io/badge/Tutorial-purple)](https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/usage.html#) |
| API Reference | [![API](https://img.shields.io/badge/Docs-blue)](https://microsoft.github.io/autogen/stable/reference/index.html#) | [![API](https://img.shields.io/badge/Docs-green)](https://microsoft.github.io/autogen/dotnet/dev/api/Microsoft.AutoGen.Contracts.html) | [![API](https://img.shields.io/badge/Docs-purple)](https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/usage.html) |
| Packages | [![PyPi autogen-core](https://img.shields.io/badge/PyPi-autogen--core-blue?logo=pypi)](https://pypi.org/project/autogen-core/) <br> [![PyPi autogen-agentchat](https://img.shields.io/badge/PyPi-autogen--agentchat-blue?logo=pypi)](https://pypi.org/project/autogen-agentchat/) <br> [![PyPi autogen-ext](https://img.shields.io/badge/PyPi-autogen--ext-blue?logo=pypi)](https://pypi.org/project/autogen-ext/) | [![NuGet Contracts](https://img.shields.io/badge/NuGet-Contracts-green?logo=nuget)](https://www.nuget.org/packages/Microsoft.AutoGen.Contracts/) <br> [![NuGet Core](https://img.shields.io/badge/NuGet-Core-green?logo=nuget)](https://www.nuget.org/packages/Microsoft.AutoGen.Core/) <br> [![NuGet Core.Grpc](https://img.shields.io/badge/NuGet-Core.Grpc-green?logo=nuget)](https://www.nuget.org/packages/Microsoft.AutoGen.Core.Grpc/) <br> [![NuGet RuntimeGateway.Grpc](https://img.shields.io/badge/NuGet-RuntimeGateway.Grpc-green?logo=nuget)](https://www.nuget.org/packages/Microsoft.AutoGen.RuntimeGateway.Grpc/) | [![PyPi autogenstudio](https://img.shields.io/badge/PyPi-autogenstudio-purple?logo=pypi)](https://pypi.org/project/autogenstudio/) |
</div>
\*_Releasing soon_
Interested in contributing? See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines on how to get started. We welcome contributions of all kinds, including bug fixes, new features, and documentation improvements. Join our community and help us make AutoGen better!
Have questions? Check out our [Frequently Asked Questions (FAQ)](./FAQ.md) for answers to common queries. If you don't find what you're looking for, feel free to ask in our [GitHub Discussions](https://github.com/microsoft/autogen/discussions) or join our [Discord server](https://aka.ms/autogen-discord) for real-time support.
Have questions? Check out our [Frequently Asked Questions (FAQ)](./FAQ.md) for answers to common queries. If you don't find what you're looking for, feel free to ask in our [GitHub Discussions](https://github.com/microsoft/autogen/discussions) or join our [Discord server](https://aka.ms/autogen-discord) for real-time support. You can also read our [blog](https://devblogs.microsoft.com/autogen/) for updates.
## Legal Notices

View File

@ -11,7 +11,7 @@ Each event in the system is defined using the [CloudEvents Specification](https:
1. *id* - A unique id (eg. a UUID).
2. *source* - A URI or URN indicating the event's origin.
3. *type* - The namespace of the event - prefixed with a reverse-DNS name.
- The prefixed domain dictates the organization which defines the semantics of this event type: e.g `com.github.pull_request.opened` or `com.example.object.deleted.v2`), and optionally fields describing the data schema/content-type or extensions.
- The prefixed domain dictates the organization which defines the semantics of this event type: e.g (`com.github.pull_request.opened` or `com.example.object.deleted.v2`), and optionally fields describing the data schema/content-type or extensions.
## Event Handlers

View File

@ -62,7 +62,7 @@ For this subscription source should map directly to agent key.
This subscription will therefore receive all events for the following well known topics:
- `{AgentType}:` - General purpose direct messages. These should be routed to the approriate message handler.
- `{AgentType}:rpc_request={RequesterAgentType}` - RPC request messages. These should be routed to the approriate RPC handler, and RequesterAgentType used to publish the response
- `{AgentType}:` - General purpose direct messages. These should be routed to the appropriate message handler.
- `{AgentType}:rpc_request={RequesterAgentType}` - RPC request messages. These should be routed to the appropriate RPC handler, and RequesterAgentType used to publish the response
- `{AgentType}:rpc_response={RequestId}` - RPC response messages. These should be routed back to the response future of the caller.
- `{AgentType}:error={RequestId}` - Error message that corresponds to the given request.

View File

@ -1,13 +1,16 @@
## How to build and run the website
# How to build and run the website
### Prerequisites
- dotnet 7.0 or later
## Prerequisites
- dotnet 8.0 or later
## Build
### Build
Firstly, go to autogen/dotnet folder and run the following command to build the website:
```bash
dotnet tool restore
dotnet tool run docfx website/docfx.json --serve
dotnet tool run docfx ../docs/dotnet/docfx.json --serve
```
After the command is executed, you can open your browser and navigate to `http://localhost:8080` to view the website.
After the command is executed, you can open your browser and navigate to `http://localhost:8080` to view the website.

View File

@ -1,7 +1,165 @@
# AutoGen Core
AutoGen Core for .NET follows the same concepts and conventions of its Python counterpart. In fact, in order to understand the concepts in the .NET version, we recommend reading the Python documentation first. Unless otherwise stated, the concepts in the Python version map to .NET.
AutoGen Core for .NET follows the same concepts and conventions of its Python counterpart. In fact, in order to understand the concepts in the .NET version, we recommend reading the [Python documentation](https://microsoft.github.io/autogen/stable/) first. Unless otherwise stated, the concepts in the Python version map to .NET.
Any important differences between the language versions are documented in the [Differences from Python](./differences-from-python.md) section. For things that only affect a given language, such as dependency injection or host builder patterns, these will not be specified in the differences document.
For .NET we are starting with the core functionality and will be expanding support progressively. So far the core abstractions of Agent and Runtime are available. The InProcessRuntime is the only runtime available at this time. We will be expanding to cross language support in upcoming releases.
## Getting Started
You can obtain the SDK as a nuget package or by cloning the repository. The SDK is available on [NuGet](https://www.nuget.org/packages/Microsoft.AutoGen).
Minimally you will need the following:
```bash
dotnet add package Microsoft.AutoGen.Contracts
dotnet add package Microsoft.AutoGen.Core
```
See [Installation](./installation.md) for more detailed notes on installing all the related packages.
You can quickly get started by looking at the samples in the [samples](https://github.com/microsoft/autogen/tree/main/dotnet/samples) directory of the repository.
### Creating an Agent
To create an agent, you can inherit from BaseAgent and implement event handlers for the events you care about. Here is a minimal example demonstrating how to inherit from BaseAgent and implement an event handler:
```csharp
public class MyAgent : BaseAgent, IHandle<MyMessage>
{
// ...
public async ValueTask HandleAsync(MyMessage item, MessageContext context)
{
// ...logic here...
}
}
```
By overriding BaseAgent, you gain access to the runtime and logging utilities, and by implementing IHandle<T>, you can easily define event-handling methods for your custom messages.
### Running an Agent in an Application
To run your agent in an application, you can use the `AgentsAppBuilder` class. Here is an example of how to run an agent 'HelloAgent' in an application:
```csharp
AgentsAppBuilder appBuilder = new AgentsAppBuilder()
.UseInProcessRuntime(deliverToSelf: true)
.AddAgent<HelloAgent>("HelloAgent");
var app = await appBuilder.BuildAsync();
// start the app by publishing a message to the runtime
await app.PublishMessageAsync(new NewMessageReceived
{
Message = "Hello from .NET"
}, new TopicId("HelloTopic"));
// Wait for shutdown
await app.WaitForShutdownAsync();
```
## .NET SDK Runtimes
The .NET SDK includes both an InMemory Single Process Runtime and a Remote, Distributed Runtime meant for running your agents in the cloud. The Distributed Runtime supports running agents in python and in .NET, allowing those agents to talk to one another. The distributed runtime uses Microsoft Orleans to provide resilience, persistence, and integration with messaging services such as Azure Event Hubs. The xlang functionality requires that your agent's Messages are serializable as CloudEvents. The messages are exchanged as CloudEvents over Grpc, and the runtime takes care of ensuring that the messages are delivered to the correct agents.
To use the Distributed Runtime, you will need to add the following package to your project:
```bash
dotnet add package Microsoft.AutoGen.Core.Grpc
```
This is the package that runs in the application with your agent(s) and connects to the distributed system.
To Run the backend/server side you need:
```bash
dotnet add package Microsoft.AutoGen.RuntimeGateway
dotnet add package Microsoft.AutoGen.AgentHost
```
You can run the backend on its own:
```bash
dotnet run --project Microsoft.AutoGen.AgentHost
```
or you can run iclude it inside your own application:
```csharp
using Microsoft.AutoGen.RuntimeGateway;
using Microsoft.AutoGen.AgentHost;
var autogenBackend = await Microsoft.AutoGen.RuntimeGateway.Grpc.Host.StartAsync(local: false, useGrpc: true).ConfigureAwait(false);
```
You can also install the runtime as a dotnet tool:
```
dotnet pack --no-build --configuration Release --output './output/release' -bl\n
dotnet tool install --add-source ./output/release Microsoft.AutoGen.AgentHost
# run the tool
# dotnet agenthost
# or just...
agenthost
```
### Running Multiple Agents and the Runtime in separate processes with .NET Aspire
The [Hello.AppHost project](https://github.com/microsoft/autogen/blob/50d7587a4649504af3bb79ab928b2a3882a1a394/dotnet/samples/Hello/Hello.AppHost/Program.cs#L4) illustrates how to orchestrate a distributed system with multiple agents and the runtime in separate processes using .NET Aspire. It also points to a [python agent that illustrates how to run agents in different languages in the same distributed system](https://github.com/microsoft/autogen/blob/50d7587a4649504af3bb79ab928b2a3882a1a394/python/samples/core_xlang_hello_python_agent/README.md#L1).
```csharp
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using Microsoft.Extensions.Hosting;
var builder = DistributedApplication.CreateBuilder(args);
var backend = builder.AddProject<Projects.Microsoft_AutoGen_AgentHost>("backend").WithExternalHttpEndpoints();
var client = builder.AddProject<Projects.HelloAgent>("HelloAgentsDotNET")
.WithReference(backend)
.WithEnvironment("AGENT_HOST", backend.GetEndpoint("https"))
.WithEnvironment("STAY_ALIVE_ON_GOODBYE", "true")
.WaitFor(backend);
// xlang is over http for now - in prod use TLS between containers
builder.AddPythonApp("HelloAgentsPython", "../../../../python/samples/core_xlang_hello_python_agent", "hello_python_agent.py", "../../.venv")
.WithReference(backend)
.WithEnvironment("AGENT_HOST", backend.GetEndpoint("http"))
.WithEnvironment("STAY_ALIVE_ON_GOODBYE", "true")
.WithEnvironment("GRPC_DNS_RESOLVER", "native")
.WithOtlpExporter()
.WaitFor(client);
using var app = builder.Build();
await app.StartAsync();
var url = backend.GetEndpoint("http").Url;
Console.WriteLine("Backend URL: " + url);
await app.WaitForShutdownAsync();
```
You can find more examples of how to use Aspire and XLang agents in the [Microsoft.AutoGen.Integration.Tests.AppHost](https://github.com/microsoft/autogen/blob/acd7e864300e24a3ee67a89a916436e8894bb143/dotnet/test/Microsoft.AutoGen.Integration.Tests.AppHosts/) directory.
### Configuring Logging
The SDK uses the Microsoft.Extensions.Logging framework for logging. Here is an example appsettings.json file with some useful defaults:
```json
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.Hosting.Lifetime": "Information",
"Microsoft.AspNetCore": "Information",
"Microsoft": "Information",
"Microsoft.Orleans": "Warning",
"Orleans.Runtime": "Error",
"Grpc": "Information"
}
},
"AllowedHosts": "*",
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
}
}
}
```
### Defining Message Types in Protocol Buffers
A convenient way to define common event or message types to be used in both python and .NET agents is to define your events. This is covered here: [Using Protocol Buffers to Define Message Types](./protobuf-message-types.md).

View File

@ -20,3 +20,29 @@ Or, add via `<PackageReference>`
<PackageReference Include="Microsoft.AutoGen.Contracts" Version="0.4.0-dev.1" />
<PackageReference Include="Microsoft.AutoGen.Core" Version="0.4.0-dev.1" />
```
# Additional Packages
The *Core* and *Contracts* packages will give you what you need for writing and running agents using the Core API within a single process.
- *Microsoft.AutoGen.AgentChat* - An implementation of the AgentChat package for building chat-centric agent orchestration on top of the Core SDK
- *Microsoft.AutoGen.Agents* - a package that has a small number of default agents you can use.
- *Microsoft.AutoGen.Extensions* - Extensions to support closely related projects including Aspire, Microsoft.Extensions.AI, and Semantic Kernel
```sh
dotnet add package Microsoft.AutoGen.AgentChat --version 0.4.0-dev-1
dotnet add package Microsoft.AutoGen.Agents --version 0.4.0-dev-1
dotnet add package Microsoft.AutoGen.Extensions --version 0.4.0-dev-1
```
To enable running a system with agents in different processes that allows for x-language communication between python and .NET agents, there are additional packages:
- *Microsoft.AutoGen.Core.Grpc* - the .NET client runtime for agents in a distributed system. It has the same API as *Microsoft.AutoGen.Core*.
- *Microsoft.AutoGen.RuntimeGatewway.Grpc* - the .NET server side of the distributed system that allows you to run multiple gateways to manage fleets of agents and enables x-language interoperability.
- *Microsoft.AutoGen.AgentHost* - A .NET Aspire project that hosts the Grpc Service
```sh
dotnet add package Microsoft.AutoGen.Core.Grpc --version 0.4.0-dev-1
dotnet add package Microsoft.AutoGen.RuntimeGateway.Grpc --version 0.4.0-dev-1
dotnet add package Microsoft.AutoGen.AgentHost --version 0.4.0-dev-1
```

View File

@ -7,4 +7,4 @@
- name: Differences from Python
href: differences-from-python.md
- name: Protobuf message types
href: protobuf-message-types.md
href: protobuf-message-types.md

View File

@ -5,7 +5,11 @@
{
"files": [
"src/Microsoft.AutoGen/Core/**/*.csproj",
"src/Microsoft.AutoGen/Contracts/**/*.csproj"
"src/Microsoft.AutoGen/Contracts/**/*.csproj",
"src/Microsoft.AutoGen/Core.Grpc/**/*.csproj",
"src/Microsoft.AutoGen/AgentHost/**/*.csproj",
"src/Microsoft.AutoGen/RuntimeGateway.Grpc/**/*.csproj",
"src/Microsoft.AutoGen/Extensions/**/*.csproj"
],
"src": "../../dotnet/"
}
@ -69,4 +73,4 @@
"keepFileLink": false,
"disableGitFeatures": false
}
}
}

View File

@ -1,15 +1,6 @@
---
_disableAffix: true
---
<style>
.center {
text-align: center;
}
.subheader {
font-size: 1.5em;
}
</style>
<div class="center">
<h1>AutoGen .NET</h1>
@ -23,7 +14,46 @@ _disableAffix: true
<div class="card">
<div class="card-body">
<h5 class="card-title">Core</h5>
<p>
[![dotnet-ci](https://github.com/microsoft/autogen/actions/workflows/dotnet-build.yml/badge.svg)](https://github.com/microsoft/autogen/actions/workflows/dotnet-build.yml)
[![NuGet version](https://badge.fury.io/nu/Microsoft.AutoGen.Contracts.svg)](https://badge.fury.io/nu/Microsoft.AutoGen.Contracts)
[![NuGet version](https://badge.fury.io/nu/Microsoft.AutoGen.Core.svg)](https://badge.fury.io/nu/Microsoft.AutoGen.Core)
[![NuGet version](https://badge.fury.io/nu/Microsoft.AutoGen.Core.Grpc.svg)](https://badge.fury.io/nu/Microsoft.AutoGen.Core.Grpc)
[![NuGet version](https://badge.fury.io/nu/Microsoft.AutoGen.RuntimeGateway.Grpc.svg)](https://badge.fury.io/nu/Microsoft.AutoGen.RuntimeGateway.Grpc)
[![NuGet version](https://badge.fury.io/nu/Microsoft.AutoGen.AgentHost.svg)](https://badge.fury.io/nu/Microsoft.AutoGen.AgentHost)
</p>
<p class="card-text">An event-driven programming framework for building scalable multi-agent AI systems.</p>
- Deterministic and dynamic agentic workflows for business processes
- Research on multi-agent collaboration
- Distributed agents for multi-language applications
- integration with event-driven, cloud native applications
*Start here if you are building workflows or distributed agent systems*
<p>
<div class="highlight">
<pre id="codecell0" tabindex="0">
```bash
dotnet add package Microsoft.AutoGen.Contracts
dotnet add package Microsoft.AutoGen.Core
# optionally - for distributed agent systems:
dotnet add package Microsoft.AutoGen.RuntimeGateway.Grpc
dotnet add package Microsoft.AutoGen.AgentHost
# other optional packages
dotnet add package Microsoft.AutoGen.Agents
dotnet add package Microsoft.AutoGen.Extensions.Aspire
dotnet add package Microsoft.AutoGen.Extensions.MEAI
dotnet add package Microsoft.AutoGen.Extensions.SemanticKernel
```
</pre></div></p>
<p>
<a href="core/index.md" class="btn btn-primary">Get started</a>
</div>
</div>

View File

@ -2,3 +2,114 @@
height: 50px;
margin-right: 0.5rem;
}
.bd-footer {
font-size: 0.8rem;
}
html[data-theme="light"] {
--pst-color-primary: hsl(222.2 47.4% 11.2%);
--pst-color-secondary: #007bff;
--pst-color-secondary-bg: #007bff;
--pst-color-accent: #007bff;
--sd-color-secondary-highlight: #0062cc;
--pst-color-shadow: rgba(0, 0, 0, 0.0);
}
html[data-theme="dark"] {
--pst-color-primary: hsl(213 31% 91%);
--pst-color-secondary: #007bff;
--pst-color-secondary-bg: #007bff;
--pst-color-accent: #007bff;
--sd-color-secondary-highlight: #0062cc;
--pst-color-shadow: rgba(0, 0, 0, 0.0);
}
.bd-header-announcement {
color: white;
}
.bd-header-announcement a {
color: white;
}
.bd-header-announcement a:hover {
color: white;
text-shadow: 0.5px 0 0 currentColor;
}
nav.bd-links .current>a {
box-shadow: inset 1px 0 0 var(--pst-color-primary);
}
html[data-theme="light"] .bd-header {
border-bottom: 1px solid var(--pst-color-border);
}
.admonition, div.admonition {
border: 1px solid var(--pst-color-border);
}
.api-card {
text-align: center;
font-size: 1.2rem;
}
.api-card svg {
font-size: 2rem;
}
.search-button-field {
border-radius: var(--bs-btn-border-radius);
}
.bd-content .sd-tab-set .sd-tab-content {
border: none;
border-top: 3px solid var(--pst-color-border);
}
.bd-content .sd-tab-set>input:checked+label {
border: none;
transform: translateY(0);
font-weight: 600;
border-bottom: 2px solid var(--pst-color-secondary);
}
.bd-content .sd-tab-set>label {
background-color: transparent;
border: none;
}
.center {
text-align: center;
}
.subheader {
font-size: 1.5em;
}
.hero-title {
font-size: 60px;
font-weight: bold;
margin: 2rem auto 0;
}
.wip-card {
border: 1px solid var(--pst-color-success);
background-color: var(--pst-color-success-bg);
border-radius: .25rem;
padding: 0.3rem;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 1rem;
}
.card-title {
font-size: 1.2rem;
font-weight: bold;
}
.card-title svg {
font-size: 2rem;
vertical-align: bottom;
margin-right: 5px;
}

View File

@ -1,14 +1,69 @@
[
{
"name": "0.4.4 (stable)",
"name": "dev (main)",
"version": "dev",
"url": "/autogen/dev/"
},
{
"name": "0.5.2 (stable)",
"version": "stable",
"url": "/autogen/stable/",
"preferred": true
},
{
"name": "dev (main)",
"version": "dev",
"url": "/autogen/dev/"
"name": "0.5.1",
"version": "0.5.1",
"url": "/autogen/0.5.1/"
},
{
"name": "0.4.9",
"version": "0.4.9",
"url": "/autogen/0.4.9/"
},
{
"name": "0.4.8",
"version": "0.4.8",
"url": "/autogen/0.4.8/"
},
{
"name": "0.4.7",
"version": "0.4.7",
"url": "/autogen/0.4.7/"
},
{
"name": "0.4.6",
"version": "0.4.6",
"url": "/autogen/0.4.6/"
},
{
"name": "0.4.5",
"version": "0.4.5",
"url": "/autogen/0.4.5/"
},
{
"name": "0.4.4",
"version": "0.4.4",
"url": "/autogen/0.4.4/"
},
{
"name": "0.4.3",
"version": "0.4.3",
"url": "/autogen/0.4.3/"
},
{
"name": "0.4.2",
"version": "0.4.2",
"url": "/autogen/0.4.2/"
},
{
"name": "0.4.1",
"version": "0.4.1",
"url": "/autogen/0.4.1/"
},
{
"name": "0.4.0",
"version": "0.4.0",
"url": "/autogen/0.4.0/"
},
{
"name": "0.2",

View File

@ -6,13 +6,15 @@
"version": "0.1.205",
"commands": [
"dotnet-repl"
]
],
"rollForward": true
},
"docfx": {
"version": "2.67.5",
"commands": [
"docfx"
]
],
"rollForward": true
}
}
}

View File

@ -15,7 +15,7 @@ foreach ($line in $($publishOutput -split "`r`n"))
}
}
pushd $rootDirectory/artifacts/bin/AutoGen.AotCompatibility.Tests/release
pushd $rootDirectory/artifacts/bin/AutoGen.AotCompatibility.Tests/release/native
Write-Host "Executing test App..."
./AutoGen.AotCompatibility.Tests

View File

@ -118,6 +118,36 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hello", "Hello", "{F42F9C8E
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Grpc", "src\Microsoft.AutoGen\Core.Grpc\Microsoft.AutoGen.Core.Grpc.csproj", "{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GettingStartedGrpc", "samples\GettingStartedGrpc\GettingStartedGrpc.csproj", "{C3740DF1-18B1-4607-81E4-302F0308C848}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Core.Grpc.Tests", "test\Microsoft.AutoGen.Core.Grpc.Tests\Microsoft.AutoGen.Core.Grpc.Tests.csproj", "{23A028D3-5EB1-4FA0-9CD1-A1340B830579}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.RuntimeGateway.Grpc", "src\Microsoft.AutoGen\RuntimeGateway.Grpc\Microsoft.AutoGen.RuntimeGateway.Grpc.csproj", "{BE420A71-7615-4DFD-BE94-9409397949F1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.RuntimeGateway.Grpc.Tests", "test\Microsoft.AutoGen.RuntimeGateway.Grpc.Tests\Microsoft.AutoGen.RuntimeGateway.Grpc.Tests.csproj", "{CDD859F3-1B60-4ECE-8472-54DF8EFCA682}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Integration.Tests", "test\Microsoft.AutoGen.Integration.Tests\Microsoft.AutoGen.Integration.Tests.csproj", "{7A11022E-4E5D-4A4A-AADF-E715C2ECF800}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.AgentHost", "src\Microsoft.AutoGen\AgentHost\Microsoft.AutoGen.AgentHost.csproj", "{50C2E8D5-68AB-45A3-B96F-355E1F8AC039}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hello.AppHost", "samples\Hello\Hello.AppHost\Hello.AppHost.csproj", "{B8E77E57-C983-4EEA-9589-906271486D80}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.AutoGen", "Microsoft.AutoGen", "{81BA12F2-2D2F-42C1-AF83-FBDAA1A78A45}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.Agents", "src\Microsoft.AutoGen\Agents\Microsoft.AutoGen.Agents.csproj", "{EF954ED3-87D5-40F1-8557-E7179F43EA0E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.AgentChat", "src\Microsoft.AutoGen\AgentChat\Microsoft.AutoGen.AgentChat.csproj", "{7F828599-56E8-4597-8F68-EE26FD631417}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AutoGen.AgentChat.Tests", "test\Microsoft.AutoGen.AgentChat.Tests\Microsoft.AutoGen.AgentChat.Tests.csproj", "{217A4F86-8ADD-4998-90BA-880092A019F5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.AutoGen.Integration.Tests.AppHosts", "Microsoft.AutoGen.Integration.Tests.AppHosts", "{D1C2B0BB-1276-4146-A699-D1983AE8ED04}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloAgentTests", "test\Microsoft.AutoGen.Integration.Tests.AppHosts\HelloAgentTests\HelloAgentTests.csproj", "{CD10E29A-725E-4BEF-9CFF-6C0E0A652926}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InMemoryTests.AppHost", "test\Microsoft.AutoGen.Integration.Tests.AppHosts\InMemoryTests.AppHost\InMemoryTests.AppHost.csproj", "{1E4E1ED4-7701-4A05-A861-64461C3B1EE3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XlangTests.AppHost", "test\Microsoft.AutoGen.Integration.Tests.AppHosts\XLangTests.AppHost\XlangTests.AppHost.csproj", "{62CDFB27-3B02-4D4B-B789-8AAD5E20688A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -296,16 +326,70 @@ Global
{70A8D4B5-D0A6-4098-A6F3-6ED274B65E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{70A8D4B5-D0A6-4098-A6F3-6ED274B65E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{70A8D4B5-D0A6-4098-A6F3-6ED274B65E7D}.Release|Any CPU.Build.0 = Release|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.CoreOnly|Any CPU.ActiveCfg = Debug|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.CoreOnly|Any CPU.Build.0 = Debug|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.Release|Any CPU.Build.0 = Release|Any CPU
{AAD593FE-A49B-425E-A9FE-A0022CD25E3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AAD593FE-A49B-425E-A9FE-A0022CD25E3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AAD593FE-A49B-425E-A9FE-A0022CD25E3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AAD593FE-A49B-425E-A9FE-A0022CD25E3D}.Release|Any CPU.Build.0 = Release|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135}.Release|Any CPU.Build.0 = Release|Any CPU
{C3740DF1-18B1-4607-81E4-302F0308C848}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C3740DF1-18B1-4607-81E4-302F0308C848}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3740DF1-18B1-4607-81E4-302F0308C848}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3740DF1-18B1-4607-81E4-302F0308C848}.Release|Any CPU.Build.0 = Release|Any CPU
{23A028D3-5EB1-4FA0-9CD1-A1340B830579}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23A028D3-5EB1-4FA0-9CD1-A1340B830579}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23A028D3-5EB1-4FA0-9CD1-A1340B830579}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23A028D3-5EB1-4FA0-9CD1-A1340B830579}.Release|Any CPU.Build.0 = Release|Any CPU
{BE420A71-7615-4DFD-BE94-9409397949F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE420A71-7615-4DFD-BE94-9409397949F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE420A71-7615-4DFD-BE94-9409397949F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE420A71-7615-4DFD-BE94-9409397949F1}.Release|Any CPU.Build.0 = Release|Any CPU
{CDD859F3-1B60-4ECE-8472-54DF8EFCA682}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CDD859F3-1B60-4ECE-8472-54DF8EFCA682}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CDD859F3-1B60-4ECE-8472-54DF8EFCA682}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CDD859F3-1B60-4ECE-8472-54DF8EFCA682}.Release|Any CPU.Build.0 = Release|Any CPU
{7A11022E-4E5D-4A4A-AADF-E715C2ECF800}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7A11022E-4E5D-4A4A-AADF-E715C2ECF800}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7A11022E-4E5D-4A4A-AADF-E715C2ECF800}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7A11022E-4E5D-4A4A-AADF-E715C2ECF800}.Release|Any CPU.Build.0 = Release|Any CPU
{50C2E8D5-68AB-45A3-B96F-355E1F8AC039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{50C2E8D5-68AB-45A3-B96F-355E1F8AC039}.Debug|Any CPU.Build.0 = Debug|Any CPU
{50C2E8D5-68AB-45A3-B96F-355E1F8AC039}.Release|Any CPU.ActiveCfg = Release|Any CPU
{50C2E8D5-68AB-45A3-B96F-355E1F8AC039}.Release|Any CPU.Build.0 = Release|Any CPU
{B8E77E57-C983-4EEA-9589-906271486D80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B8E77E57-C983-4EEA-9589-906271486D80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8E77E57-C983-4EEA-9589-906271486D80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8E77E57-C983-4EEA-9589-906271486D80}.Release|Any CPU.Build.0 = Release|Any CPU
{EF954ED3-87D5-40F1-8557-E7179F43EA0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF954ED3-87D5-40F1-8557-E7179F43EA0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF954ED3-87D5-40F1-8557-E7179F43EA0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF954ED3-87D5-40F1-8557-E7179F43EA0E}.Release|Any CPU.Build.0 = Release|Any CPU
{7F828599-56E8-4597-8F68-EE26FD631417}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F828599-56E8-4597-8F68-EE26FD631417}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F828599-56E8-4597-8F68-EE26FD631417}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F828599-56E8-4597-8F68-EE26FD631417}.Release|Any CPU.Build.0 = Release|Any CPU
{217A4F86-8ADD-4998-90BA-880092A019F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{217A4F86-8ADD-4998-90BA-880092A019F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{217A4F86-8ADD-4998-90BA-880092A019F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{217A4F86-8ADD-4998-90BA-880092A019F5}.Release|Any CPU.Build.0 = Release|Any CPU
{0C371D65-7EF9-44EA-8128-A105DA82A80E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C371D65-7EF9-44EA-8128-A105DA82A80E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C371D65-7EF9-44EA-8128-A105DA82A80E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C371D65-7EF9-44EA-8128-A105DA82A80E}.Release|Any CPU.Build.0 = Release|Any CPU
{CD10E29A-725E-4BEF-9CFF-6C0E0A652926}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CD10E29A-725E-4BEF-9CFF-6C0E0A652926}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD10E29A-725E-4BEF-9CFF-6C0E0A652926}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD10E29A-725E-4BEF-9CFF-6C0E0A652926}.Release|Any CPU.Build.0 = Release|Any CPU
{1E4E1ED4-7701-4A05-A861-64461C3B1EE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E4E1ED4-7701-4A05-A861-64461C3B1EE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E4E1ED4-7701-4A05-A861-64461C3B1EE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E4E1ED4-7701-4A05-A861-64461C3B1EE3}.Release|Any CPU.Build.0 = Release|Any CPU
{62CDFB27-3B02-4D4B-B789-8AAD5E20688A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62CDFB27-3B02-4D4B-B789-8AAD5E20688A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62CDFB27-3B02-4D4B-B789-8AAD5E20688A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62CDFB27-3B02-4D4B-B789-8AAD5E20688A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -356,9 +440,24 @@ Global
{EAFFE339-26CB-4019-991D-BCCE8E7D33A1} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
{58AD8E1D-83BD-4950-A324-1A20677D78D9} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
{70A8D4B5-D0A6-4098-A6F3-6ED274B65E7D} = {CE0AA8D5-12B8-4628-9589-DAD8CB0DDCF6}
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{AAD593FE-A49B-425E-A9FE-A0022CD25E3D} = {F42F9C8E-7BD9-4687-9B63-AFFA461AF5C1}
{F42F9C8E-7BD9-4687-9B63-AFFA461AF5C1} = {CE0AA8D5-12B8-4628-9589-DAD8CB0DDCF6}
{3D83C6DB-ACEA-48F3-959F-145CCD2EE135} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{C3740DF1-18B1-4607-81E4-302F0308C848} = {CE0AA8D5-12B8-4628-9589-DAD8CB0DDCF6}
{23A028D3-5EB1-4FA0-9CD1-A1340B830579} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
{BE420A71-7615-4DFD-BE94-9409397949F1} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{CDD859F3-1B60-4ECE-8472-54DF8EFCA682} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
{7A11022E-4E5D-4A4A-AADF-E715C2ECF800} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
{50C2E8D5-68AB-45A3-B96F-355E1F8AC039} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{B8E77E57-C983-4EEA-9589-906271486D80} = {F42F9C8E-7BD9-4687-9B63-AFFA461AF5C1}
{81BA12F2-2D2F-42C1-AF83-FBDAA1A78A45} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{EF954ED3-87D5-40F1-8557-E7179F43EA0E} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{7F828599-56E8-4597-8F68-EE26FD631417} = {18BF8DD7-0585-48BF-8F97-AD333080CE06}
{217A4F86-8ADD-4998-90BA-880092A019F5} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
{D1C2B0BB-1276-4146-A699-D1983AE8ED04} = {F823671B-3ECA-4AE6-86DA-25E920D3FE64}
{CD10E29A-725E-4BEF-9CFF-6C0E0A652926} = {D1C2B0BB-1276-4146-A699-D1983AE8ED04}
{1E4E1ED4-7701-4A05-A861-64461C3B1EE3} = {D1C2B0BB-1276-4146-A699-D1983AE8ED04}
{62CDFB27-3B02-4D4B-B789-8AAD5E20688A} = {D1C2B0BB-1276-4146-A699-D1983AE8ED04}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {93384647-528D-46C8-922C-8DB36A382F0B}

View File

@ -2,10 +2,12 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<MicrosoftSemanticKernelVersion>1.22.0</MicrosoftSemanticKernelVersion>
<MicrosoftSemanticKernelExperimentalVersion>1.22.0-alpha</MicrosoftSemanticKernelExperimentalVersion>
<MicrosoftExtensionsAIVersion>9.0.0-preview.9.24525.1</MicrosoftExtensionsAIVersion>
<MicrosoftSemanticKernelStableVersion>1.45.0</MicrosoftSemanticKernelStableVersion>
<MicrosoftSemanticKernelPreviewVersion>$(MicrosoftSemanticKernelStableVersion)-preview</MicrosoftSemanticKernelPreviewVersion>
<MicrosoftSemanticKernelAlphaVersion>$(MicrosoftSemanticKernelStableVersion)-alpha</MicrosoftSemanticKernelAlphaVersion>
<MicrosoftExtensionsAIVersion>9.3.0-preview.1.25161.3</MicrosoftExtensionsAIVersion>
<MicrosoftExtensionConfiguration>9.0.0</MicrosoftExtensionConfiguration>
<MicrosoftExtensionDependencyInjection>9.0.0</MicrosoftExtensionDependencyInjection>
<MicrosoftExtensionDependencyInjection>9.0.3</MicrosoftExtensionDependencyInjection>
<MicrosoftExtensionLogging>9.0.0</MicrosoftExtensionLogging>
<MicrosoftExtensionOptions>9.0.0</MicrosoftExtensionOptions>
<MicrosoftOrleans>9.0.1</MicrosoftOrleans>
@ -18,7 +20,7 @@
<PackageVersion Include="Aspire.Hosting" Version="9.0.0" />
<PackageVersion Include="Aspire.Hosting.Python" Version="9.0.0" />
<PackageVersion Include="Aspire.Hosting.Testing" Version="9.0.0" />
<PackageVersion Include="Aspire.Azure.AI.OpenAI" Version="8.0.1-preview.8.24267.1" />
<PackageVersion Include="Aspire.Azure.AI.OpenAI" Version="9.0.0-preview.5.24551.3" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="9.0.0" />
<PackageVersion Include="Aspire.Hosting.Azure.ApplicationInsights" Version="9.0.0" />
<PackageVersion Include="Aspire.Hosting.Azure.CognitiveServices" Version="9.0.0" />
@ -27,9 +29,10 @@
<PackageVersion Include="Aspire.Hosting.Qdrant" Version="9.0.0" />
<PackageVersion Include="Aspire.Hosting.Redis" Version="8.2.0" />
<PackageVersion Include="AspNetCore.Authentication.ApiKey" Version="8.0.1" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.1.0-beta.2" />
<PackageVersion Include="Azure.AI.OpenAI" Version="2.2.0-beta.4" />
<PackageVersion Include="Azure.AI.Inference" Version="1.0.0-beta.1" />
<PackageVersion Include="Azure.Data.Tables" Version="12.9.1" />
<PackageVersion Include="Azure.Core" Version="1.44.1" />
<PackageVersion Include="Azure.Identity" Version="1.13.1" />
<PackageVersion Include="Azure.ResourceManager.ContainerInstance" Version="1.2.1" />
<PackageVersion Include="Azure.Storage.Files.Shares" Version="12.21.0" />
@ -100,18 +103,18 @@
<PackageVersion Include="Microsoft.Orleans.Streaming.EventHubs" Version="$(MicrosoftOrleans)" />
<PackageVersion Include="Microsoft.Orleans.TestingHost" Version="9.0.1" />
<PackageVersion Include="Microsoft.PowerShell.SDK" Version="7.5.0" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.29.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Agents.Core" Version="$(MicrosoftSemanticKernelExperimentalVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.AzureOpenAI" Version="1.29.0" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.Qdrant" Version="$(MicrosoftSemanticKernelExperimentalVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel.Plugins.Memory" Version="$(MicrosoftSemanticKernelExperimentalVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel.Plugins.Web" Version="$(MicrosoftSemanticKernelExperimentalVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="$(MicrosoftSemanticKernelStableVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel.Agents.Core" Version="$(MicrosoftSemanticKernelStableVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.AzureOpenAI" Version="$(MicrosoftSemanticKernelStableVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel.Connectors.Qdrant" Version="$(MicrosoftSemanticKernelPreviewVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel.Plugins.Memory" Version="$(MicrosoftSemanticKernelAlphaVersion)" />
<PackageVersion Include="Microsoft.SemanticKernel.Plugins.Web" Version="$(MicrosoftSemanticKernelAlphaVersion)" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Octokit" Version="13.0.1" />
<PackageVersion Include="Octokit.Webhooks.AspNetCore" Version="2.4.1" />
<PackageVersion Include="OpenAI" Version="2.1.0-beta.2" />
<PackageVersion Include="OpenAI" Version="2.2.0-beta.4" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.10.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.10.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="$(OpenTelemetryInstrumentation)" />
@ -127,7 +130,7 @@
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="8.2.1" />
<PackageVersion Include="System.IO.Packaging" Version="9.0.0" />
<PackageVersion Include="System.Memory.Data" Version="9.0.0" />
<PackageVersion Include="System.Text.Json" Version="9.0.0" />
<PackageVersion Include="System.Text.Json" Version="9.0.3" />
<PackageVersion Include="xunit" Version="2.9.2" />
<PackageVersion Include="xunit.runner.console" Version="2.9.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />

View File

@ -2,7 +2,7 @@
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VersionPrefix>0.4.0</VersionPrefix>
<VersionPrefixForAutoGen0_2>0.2.2</VersionPrefixForAutoGen0_2>
<VersionPrefixForAutoGen0_2>0.2.3</VersionPrefixForAutoGen0_2>
<Authors>Microsoft</Authors>
<PackageProjectUrl>https://microsoft.github.io/autogen-for-net/</PackageProjectUrl>
<RepositoryUrl>https://github.com/microsoft/autogen</RepositoryUrl>

View File

@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.401",
"rollForward": "latestMinor"
"version": "9.0.100",
"rollForward": "latestFeature"
}
}

View File

@ -50,7 +50,7 @@ public class Example10_SemanticKernel
kernel.Plugins.AddFromObject(new LightPlugin());
var skAgent = kernel
.ToSemanticKernelAgent(name: "assistant", systemMessage: "You control the light", settings);
.ToSemanticKernelAgent(name: "assistant", systemMessage: "You control the light", settings: settings);
// Send a message to the skAgent, the skAgent supports the following message types:
// - IMessage<ChatMessageContent>

View File

@ -42,8 +42,6 @@ public class Tool_Call_With_Ollama_And_LiteLLM
});
#endregion Create_tools
#region Create_Agent
var liteLLMUrl = "http://localhost:4000";
// api-key is not required for local server
// so you can use any string here
var openAIClient = new OpenAIClient(new ApiKeyCredential("api-key"), new OpenAIClientOptions
@ -59,7 +57,7 @@ public class Tool_Call_With_Ollama_And_LiteLLM
.RegisterMiddleware(functionMiddleware)
.RegisterPrintMessage();
var reply = await agent.SendAsync("what's the weather in new york");
await agent.SendAsync("what's the weather in new york");
#endregion Create_Agent
}
}

View File

@ -40,6 +40,6 @@ public class DummyAgent : IStreamingAgent
foreach (var c in reply)
{
yield return new TextMessageUpdate(Role.Assistant, c.ToString(), this.Name);
};
}
}
}

View File

@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Checker.cs
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.Extensions.Hosting;
using TerminationF = System.Func<int, bool>;
namespace GettingStartedGrpcSample;
[TypeSubscription("default")]
public class Checker(
AgentId id,
IAgentRuntime runtime,
IHostApplicationLifetime hostApplicationLifetime,
TerminationF runUntilFunc
) :
BaseAgent(id, runtime, "Modifier", null),
IHandle<Events.CountUpdate>
{
public async ValueTask HandleAsync(Events.CountUpdate item, MessageContext messageContext)
{
if (!runUntilFunc(item.NewCount))
{
Console.WriteLine($"\nChecker:\n{item.NewCount} passed the check, continue.");
await this.PublishMessageAsync(new Events.CountMessage { Content = item.NewCount }, new TopicId("default"));
}
else
{
Console.WriteLine($"\nChecker:\n{item.NewCount} failed the check, stopping.");
hostApplicationLifetime.StopApplication();
}
}
}

View File

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>getting_started</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AutoGen\Contracts\Microsoft.AutoGen.Contracts.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AutoGen\Core\Microsoft.AutoGen.Core.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AutoGen\Core.Grpc\Microsoft.AutoGen.Core.Grpc.csproj" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="message.proto" GrpcServices="Client" Link="Protos\message.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Modifier.cs
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using ModifyF = System.Func<int, int>;
namespace GettingStartedGrpcSample;
[TypeSubscription("default")]
public class Modifier(
AgentId id,
IAgentRuntime runtime,
ModifyF modifyFunc
) :
BaseAgent(id, runtime, "Modifier", null),
IHandle<Events.CountMessage>
{
public async ValueTask HandleAsync(Events.CountMessage item, MessageContext messageContext)
{
int newValue = modifyFunc(item.Content);
Console.WriteLine($"\nModifier:\nModified {item.Content} to {newValue}");
var updateMessage = new Events.CountUpdate { NewCount = newValue };
await this.PublishMessageAsync(updateMessage, topic: new TopicId("default"));
}
}

View File

@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using GettingStartedGrpcSample;
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.AutoGen.Core.Grpc;
using Microsoft.Extensions.DependencyInjection.Extensions;
using ModifyF = System.Func<int, int>;
using TerminationF = System.Func<int, bool>;
ModifyF modifyFunc = (int x) => x - 1;
TerminationF runUntilFunc = (int x) =>
{
return x <= 1;
};
AgentsAppBuilder appBuilder = new AgentsAppBuilder();
appBuilder.AddGrpcAgentWorker("http://localhost:50051");
appBuilder.Services.TryAddSingleton(modifyFunc);
appBuilder.Services.TryAddSingleton(runUntilFunc);
appBuilder.AddAgent<Checker>("Checker");
appBuilder.AddAgent<Modifier>("Modifier");
var app = await appBuilder.BuildAsync();
await app.StartAsync();
// Send the initial count to the agents app, running on the `local` runtime, and pass through the registered services via the application `builder`
await app.PublishMessageAsync(new GettingStartedGrpcSample.Events.CountMessage
{
Content = 10
}, new TopicId("default"));
// Run until application shutdown
await app.WaitForShutdownAsync();

View File

@ -0,0 +1,11 @@
syntax = "proto3";
option csharp_namespace = "GettingStartedGrpcSample.Events";
message CountMessage {
int32 content = 1;
}
message CountUpdate {
int32 new_count = 1;
}

View File

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// HelloAgent.cs
using Microsoft.AutoGen.Agents;
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.Extensions.Hosting;

View File

@ -21,10 +21,12 @@
<ItemGroup>
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Contracts\Microsoft.AutoGen.Contracts.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Core.Grpc\Microsoft.AutoGen.Core.Grpc.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Core\Microsoft.AutoGen.Core.csproj" />
<ProjectReference Include="..\..\..\src\Microsoft.AutoGen\Core.Grpc\Microsoft.AutoGen.Core.Grpc.csproj" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="..\protos\agent_events.proto" Link="protos\agent_events.proto" />
<Protobuf Include="..\..\..\src\Microsoft.AutoGen\Agents\protos\agent_events.proto" Link="protos\agent_events.proto" />
</ItemGroup>
</Project>

View File

@ -1,16 +1,82 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Program.cs
using Microsoft.AutoGen.Agents;
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.AutoGen.Core.Grpc;
using Samples;
// Set up app builder for in-process runtime, allow message delivery to self, and add the Hello agent
AgentsAppBuilder appBuilder = new AgentsAppBuilder()
.UseInProcessRuntime(deliverToSelf: true)
.AddAgent<HelloAgent>("HelloAgent");
string? hostAddress = null;
bool in_host_address = false;
bool sendHello = true;
foreach (string arg in args)
{
switch (arg)
{
case "--host":
in_host_address = true;
break;
case "--nosend":
sendHello = false;
break;
case "-h":
case "--help":
PrintHelp();
Environment.Exit(0);
break;
default:
if (in_host_address)
{
hostAddress = arg;
}
break;
}
}
hostAddress ??= Environment.GetEnvironmentVariable("AGENT_HOST");
var appBuilder = new AgentsAppBuilder(); // Create app builder
// if we are using distributed, we need the AGENT_HOST var defined and then we will use the grpc runtime
bool usingGrpc = false;
if (hostAddress is string agentHost)
{
usingGrpc = true;
Console.WriteLine($"connecting to {agentHost}");
appBuilder.AddGrpcAgentWorker(agentHost)
.AddAgent<HelloAgent>("HelloAgent");
}
else
{
// Set up app builder for in-process runtime, allow message delivery to self, and add the Hello agent
appBuilder.UseInProcessRuntime(deliverToSelf: true).AddAgent<HelloAgent>("HelloAgent");
}
var app = await appBuilder.BuildAsync(); // Build the app
await app.StartAsync();
// Create a custom message type from proto and define message
NewMessageReceived message = new NewMessageReceived { Message = "Hello World!" };
await app.PublishMessageAsync(message, new TopicId("HelloTopic")); // Publish custom message (handler has been set in HelloAgent)
await app.WaitForShutdownAsync(); // Wait for shutdown from agent
if (sendHello)
{
var message = new NewMessageReceived { Message = "Hello World!" };
await app.PublishMessageAsync(message, new TopicId("HelloTopic")).ConfigureAwait(false); // Publish custom message (handler has been set in HelloAgent)
}
else if (!usingGrpc)
{
Console.Write("Warning: Using --nosend with the InProcessRuntime will hang. Terminating.");
Environment.Exit(-1);
}
await app.WaitForShutdownAsync().ConfigureAwait(false); // Wait for shutdown from agent
static void PrintHelp()
{
/*
HelloAgent [--host <hostAddress>] [--nosend]
--host Use gRPC gateway at <hostAddress>; this can also be set using the AGENT_HOST Environment Variable
--nosend Do not send the starting message. Note: This means HelloAgent will wait until some other agent will send
that message. This will not work when using the InProcessRuntime.
*/
Console.WriteLine("HelloAgent [--host <hostAddress>] [--nosend]");
Console.WriteLine(" --host \tUse gRPC gateway at <hostAddress>; this can also be set using the AGENT_HOST Environment Variable");
Console.WriteLine(" --nosend \tDo not send the starting message. Note: This means HelloAgent will wait until some other agent will send");
}

View File

@ -144,13 +144,13 @@ public static class AgentExtension
chatHistory.Add(msg);
}
var intermediateChatHistory = new List<IMessage>();
await foreach (var msg in agent.SendAsync(receiver, chatHistory, maxRound, ct))
{
chatHistory.Add(msg);
intermediateChatHistory.Add(msg);
}
return chatHistory;
return chatHistory.Concat(intermediateChatHistory);
}
[Obsolete("use GroupChatExtension.SendAsync")]

View File

@ -4,6 +4,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Extensions.AI;
@ -69,36 +71,48 @@ public class FunctionContract
/// </summary>
public string? ReturnDescription { get; set; }
public static implicit operator FunctionContract(AIFunctionMetadata metadata)
public static implicit operator FunctionContract(AIFunction function)
{
var openapiScheme = function.JsonSchema;
var parameters = new List<FunctionParameterContract>();
string[] isRequiredProperties = [];
if (openapiScheme.TryGetProperty("required", out var requiredElement))
{
isRequiredProperties = requiredElement.Deserialize<string[]>() ?? [];
}
var parameterList = function.UnderlyingMethod?.GetParameters() ?? Array.Empty<ParameterInfo>();
if (openapiScheme.TryGetProperty("properties", out var propertiesElement))
{
var properties = propertiesElement.Deserialize<Dictionary<string, JsonElement>>() ?? new Dictionary<string, JsonElement>();
foreach (var property in properties)
{
var parameterType = parameterList.FirstOrDefault(p => p.Name == property.Key)?.ParameterType;
var parameter = new FunctionParameterContract
{
Name = property.Key,
ParameterType = parameterType, // TODO: Need to get the type from the schema
IsRequired = isRequiredProperties.Contains(property.Key),
};
if (property.Value.TryGetProperty("description", out var descriptionElement))
{
parameter.Description = descriptionElement.GetString();
}
if (property.Value.TryGetProperty("default", out var defaultValueElement))
{
parameter.DefaultValue = defaultValueElement.Deserialize<object>();
}
parameters.Add(parameter);
}
}
return new FunctionContract
{
Namespace = metadata.AdditionalProperties.ContainsKey(NamespaceKey) ? metadata.AdditionalProperties[NamespaceKey] as string : null,
ClassName = metadata.AdditionalProperties.ContainsKey(ClassNameKey) ? metadata.AdditionalProperties[ClassNameKey] as string : null,
Name = metadata.Name,
Description = metadata.Description,
Parameters = metadata.Parameters?.Select(p => (FunctionParameterContract)p).ToList(),
ReturnType = metadata.ReturnParameter.ParameterType,
ReturnDescription = metadata.ReturnParameter.Description,
};
}
public static implicit operator AIFunctionMetadata(FunctionContract contract)
{
return new AIFunctionMetadata(contract.Name)
{
Description = contract.Description,
ReturnParameter = new AIFunctionReturnParameterMetadata()
{
Description = contract.ReturnDescription,
ParameterType = contract.ReturnType,
},
AdditionalProperties = new Dictionary<string, object?>
{
[NamespaceKey] = contract.Namespace,
[ClassNameKey] = contract.ClassName,
},
Parameters = [.. contract.Parameters?.Select(p => (AIFunctionParameterMetadata)p)!],
Namespace = function.AdditionalProperties.ContainsKey(NamespaceKey) ? function.AdditionalProperties[NamespaceKey] as string : null,
ClassName = function.AdditionalProperties.ContainsKey(ClassNameKey) ? function.AdditionalProperties[ClassNameKey] as string : null,
Name = function.Name,
Description = function.Description,
Parameters = parameters,
};
}
}
@ -132,29 +146,4 @@ public class FunctionParameterContract
/// The default value of the parameter.
/// </summary>
public object? DefaultValue { get; set; }
// convert to/from FunctionParameterMetadata
public static implicit operator FunctionParameterContract(AIFunctionParameterMetadata metadata)
{
return new FunctionParameterContract
{
Name = metadata.Name,
Description = metadata.Description,
ParameterType = metadata.ParameterType,
IsRequired = metadata.IsRequired,
DefaultValue = metadata.DefaultValue,
};
}
public static implicit operator AIFunctionParameterMetadata(FunctionParameterContract contract)
{
return new AIFunctionParameterMetadata(contract.Name!)
{
DefaultValue = contract.DefaultValue,
Description = contract.Description,
IsRequired = contract.IsRequired,
ParameterType = contract.ParameterType,
HasDefaultValue = contract.DefaultValue != null,
};
}
}

View File

@ -53,9 +53,9 @@ public class FunctionCallMiddleware : IStreamingMiddleware
public FunctionCallMiddleware(IEnumerable<AIFunction> functions, string? name = null)
{
this.Name = name ?? nameof(FunctionCallMiddleware);
this.functions = functions.Select(f => (FunctionContract)f.Metadata).ToArray();
this.functions = functions.Select(f => (FunctionContract)f).ToArray();
this.functionMap = functions.Select(f => (f.Metadata.Name, this.AIToolInvokeWrapper(f.InvokeAsync))).ToDictionary(f => f.Name, f => f.Item2);
this.functionMap = functions.Select(f => (f.Name, this.AIToolInvokeWrapper(f.InvokeAsync))).ToDictionary(f => f.Name, f => f.Item2);
}
public string? Name { get; }

View File

@ -8,9 +8,9 @@ namespace AutoGen.SemanticKernel.Extension;
public static class KernelExtension
{
public static SemanticKernelAgent ToSemanticKernelAgent(this Kernel kernel, string name, string systemMessage = "You are a helpful AI assistant", PromptExecutionSettings? settings = null)
public static SemanticKernelAgent ToSemanticKernelAgent(this Kernel kernel, string name, string systemMessage = "You are a helpful AI assistant", string? modelServiceId = null, PromptExecutionSettings? settings = null)
{
return new SemanticKernelAgent(kernel, name, systemMessage, settings);
return new SemanticKernelAgent(kernel, name, systemMessage, modelServiceId, settings);
}
/// <summary>

View File

@ -32,17 +32,28 @@ public class SemanticKernelAgent : IStreamingAgent
{
private readonly Kernel _kernel;
private readonly string _systemMessage;
private readonly string? _modelServiceId;
private readonly PromptExecutionSettings? _settings;
/// <summary>
/// Create a new instance of <see cref="SemanticKernelAgent"/>
/// </summary>
/// <param name="kernel">The Semantic Kernel - Kernel object</param>
/// <param name="name">The name of the agent.</param>
/// <param name="systemMessage">The system message.</param>
/// <param name="modelServiceId">Optional serviceId for the model.</param>
/// <param name="settings">The prompt execution settings.</param>
public SemanticKernelAgent(
Kernel kernel,
string name,
string systemMessage = "You are a helpful AI assistant",
string? modelServiceId = null,
PromptExecutionSettings? settings = null)
{
_kernel = kernel;
this.Name = name;
_systemMessage = systemMessage;
_modelServiceId = modelServiceId;
_settings = settings;
}
@ -52,7 +63,7 @@ public class SemanticKernelAgent : IStreamingAgent
{
var chatHistory = BuildChatHistory(messages);
var option = BuildOption(options);
var chatService = _kernel.GetRequiredService<IChatCompletionService>();
var chatService = GetChatCompletionService();
var reply = await chatService.GetChatMessageContentsAsync(chatHistory, option, _kernel, cancellationToken);
@ -71,7 +82,7 @@ public class SemanticKernelAgent : IStreamingAgent
{
var chatHistory = BuildChatHistory(messages);
var option = BuildOption(options);
var chatService = _kernel.GetRequiredService<IChatCompletionService>();
var chatService = GetChatCompletionService();
var response = chatService.GetStreamingChatMessageContentsAsync(chatHistory, option, _kernel, cancellationToken);
await foreach (var content in response)
@ -108,6 +119,13 @@ public class SemanticKernelAgent : IStreamingAgent
};
}
private IChatCompletionService GetChatCompletionService()
{
return string.IsNullOrEmpty(_modelServiceId)
? _kernel.GetRequiredService<IChatCompletionService>()
: _kernel.GetRequiredService<IChatCompletionService>(_modelServiceId);
}
private IEnumerable<ChatMessageContent> ProcessMessage(IEnumerable<IMessage> messages)
{
return messages.Select(m => m switch

View File

@ -26,8 +26,9 @@ public class SemanticKernelChatCompletionAgent : IAgent
public async Task<IMessage> GenerateReplyAsync(IEnumerable<IMessage> messages, GenerateReplyOptions? options = null,
CancellationToken cancellationToken = default)
{
ChatMessageContent[] reply = await _chatCompletionAgent
.InvokeAsync(BuildChatHistory(messages), cancellationToken: cancellationToken)
var agentThread = new ChatHistoryAgentThread(BuildChatHistory(messages));
var reply = await _chatCompletionAgent
.InvokeAsync(agentThread, cancellationToken: cancellationToken)
.ToArrayAsync(cancellationToken: cancellationToken);
return reply.Length > 1

View File

@ -0,0 +1,194 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ChatAgent.cs
using System.Text.RegularExpressions;
using Microsoft.AutoGen.Contracts;
namespace Microsoft.AutoGen.AgentChat.Abstractions;
/// <summary>
/// A valid name for an agent.
/// </summary>
/// <remarks>
/// To ensure parity with Python, we require agent names to be Python identifiers.
/// </remarks>
public struct AgentName
{
//
// TODO: Ensure that only valid C# identifiers can pass the validation on Python?
/*
From https://docs.python.org/3/reference/lexical_analysis.html#identifiers:
```
identifier ::= xid_start xid_continue*
id_start ::= <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property>
id_continue ::= <all characters in id_start, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>
xid_start ::= <all characters in id_start whose NFKC normalization is in "id_start xid_continue*">
xid_continue ::= <all characters in id_continue whose NFKC normalization is in "id_continue*">
```
Note: we are not going to deal with normalization; it would require a lot of effort for likely little gain
(this will mean that, strictly speaking, .NET will support a subset of the identifiers that Python does)
The Unicode category codes mentioned above stand for:
* Lu - uppercase letters
* Ll - lowercase letters
* Lt - titlecase letters
* Lm - modifier letters
* Lo - other letters
* Nl - letter numbers*
* Mn - nonspacing marks
* Mc - spacing combining marks*
* Nd - decimal numbers
* Pc - connector punctuations
Of these, most are captured by "word characters" in .NET, \w, only needing \p{Nl} and \p{Mc} to be added.
While Copilot /thinks/ that \p{Pc} is needed, it is not, as it is part of \w in .NET.
* Other_ID_Start - explicit list of characters in PropList.txt to support backwards compatibility
* Other_ID_Continue - likewise
# ================================================
1885..1886 ; Other_ID_Start # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
2118 ; Other_ID_Start # Sm SCRIPT CAPITAL P
212E ; Other_ID_Start # So ESTIMATED SYMBOL
309B..309C ; Other_ID_Start # Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
# Total code points: 6
The pattern for this in .NET is [\u1185-\u1186\u2118\u212E\u309B-\u309C]
# ================================================
00B7 ; Other_ID_Continue # Po MIDDLE DOT
0387 ; Other_ID_Continue # Po GREEK ANO TELEIA
1369..1371 ; Other_ID_Continue # No [9] ETHIOPIC DIGIT ONE..ETHIOPIC DIGIT NINE
19DA ; Other_ID_Continue # No NEW TAI LUE THAM DIGIT ONE
200C..200D ; Other_ID_Continue # Cf [2] ZERO WIDTH NON-JOINER..ZERO WIDTH JOINER
30FB ; Other_ID_Continue # Po KATAKANA MIDDLE DOT
FF65 ; Other_ID_Continue # Po HALFWIDTH KATAKANA MIDDLE DOT
# Total code points: 16
The pattern for this in .NET is [\u00B7\u0387\u1369-\u1371\u19DA\u200C\u200D\u30FB\uFF65]
# ================================================
Classes for "IdStart": {Lu, Ll, Lt, Lm, Lo, Nl, '_', Other_ID_Start}
pattern: [\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}_\u1185-\u1186\u2118\u212E\u309B-\u309C]
Classes for "IdContinue": {\w, Nl, Mc, Other_ID_Start, Other_ID_Continue}
pattern: [\w\p{Nl}\p{Mc}_\u1185-\u1186\u2118\u212E\u309B-\u309C\u00B7\u0387\u1369-\u1371\u19DA\u200C\u200D\u30FB\uFF65]
Match group for identifiers:
(?<ident>(?:[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}_\u1185-\u1186\u2118\u212E\u309B-\u309C])(?:[\w\p{Nl}\p{Mc}_\u1185-\u1186\u2118\u212E\u309B-\u309C\u00B7\u0387\u1369-\u1371\u19DA\u200C\u200D\u30FB\uFF65])*)
*/
private const string IdStartClass = @"[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}_\u1185-\u1186\u2118\u212E\u309B-\u309C]";
private const string IdContinueClass = @"[\w\p{Nl}\p{Mc}_\u1185-\u1186\u2118\u212E\u309B-\u309C\u00B7\u0387\u1369-\u1371\u19DA\u200C\u200D\u30FB\uFF65]";
private static readonly Regex AgentNameRegex = new Regex($"^{IdStartClass}{IdContinueClass}*$", RegexOptions.Compiled | RegexOptions.Singleline);
public string Value { get; }
public AgentName(string name)
{
AgentName.CheckValid(name);
this.Value = name;
}
public static bool IsValid(string name) => AgentNameRegex.IsMatch(name);
public static void CheckValid(string name)
{
if (!AgentName.IsValid(name))
{
throw new ArgumentException($"Agent name '{name}' is not a valid identifier.");
}
}
// Implicit cast to string
public static implicit operator string(AgentName agentName) => agentName.Value;
}
/// <summary>
/// A response from calling <see cref="IChatAgent"/>'s <see cref="IHandleChat{TIn, Response}.HandleAsync(TIn)"/>."/>
/// </summary>
public class Response
{
/// <summary>
/// A chat message produced by the agent as a response.
/// </summary>
public required ChatMessage Message { get; set; }
/// <summary>
/// Inner messages produced by the agent.
/// </summary>
public List<AgentMessage>? InnerMessages { get; set; }
}
/// <summary>
/// Base class for representing a stream of messages interspacing responses (<typeparamref name="TResponse"/>) and
/// internal processing messages (<typeparamref name="TInternalMessage"/>). This functions as a discriminated union.
/// </summary>
/// <typeparam name="TResponse">The response type. Usually <see cref="Response"/>.</typeparam>
/// <typeparam name="TInternalMessage">The ineternal message type. Usually <see cref="AgentMessage"/>.</typeparam>
public class StreamingFrame<TResponse, TInternalMessage>() where TInternalMessage : AgentMessage
{
public enum FrameType
{
InternalMessage,
Response
}
public FrameType Type { get; set; }
public TInternalMessage? InternalMessage { get; set; }
public TResponse? Response { get; set; }
}
/// <summary>
/// Base class for representing a stream of messages with internal messages of any <see cref="AgentMessage"/> subtype.
/// </summary>
/// <typeparam name="TResponse">The response type. Usually <see cref="Response"/>.</typeparam>
public class StreamingFrame<TResponse> : StreamingFrame<TResponse, AgentMessage>;
/// <summary>
/// The stream frame for <see cref="IChatAgent"/>'s <see cref="IHandleStream{TIn, ChatStreamFrame}.StreamAsync(TIn)"/>
/// </summary>
public class ChatStreamFrame : StreamingFrame<Response, AgentMessage>;
/// <summary>
/// An agent that can participate in a chat.
/// </summary>
public interface IChatAgent :
IHandleChat<IEnumerable<ChatMessage>, Response>,
IHandleStream<IEnumerable<ChatMessage>, ChatStreamFrame>,
ISaveState
{
/// <summary>
/// The name of the agent. This is used by team to uniquely identify the agent.It should be unique within the team.
/// </summary>
public AgentName Name { get; }
/// <summary>
/// The description of the agent. This is used by team to make decisions about which agents to use.The description
/// should describe the agent's capabilities and how to interact with it.
/// </summary>
public string Description { get; }
/// <summary>
/// The types of messages that the agent produces.
/// </summary>
public IEnumerable<Type> ProducedMessageTypes { get; } // TODO: Is there a way to make this part of the type somehow? Annotations, or IProduce<>? Do we ever actually access this?
/// <summary>
/// Reset the agent to its initialization state.
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public ValueTask ResetAsync(CancellationToken cancellationToken);
}

View File

@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Handoff.cs
namespace Microsoft.AutoGen.AgentChat.Abstractions;
/// <summary>
/// Handoff configuration.
/// </summary>
/// <param name="target">The name of the target agent receiving the handoff.</param>
/// <param name="description">The description of the handoff such as the condition under which it should happen and the target
/// agent's ability. If not provided, it is generated from the target agent's name.</param>
/// <param name="name">The name of this handoff configuration. If not provided, it is generated from the target agent's name.</param>
/// <param name="message">The message to the target agent. If not provided, it is generated from the target agent's name.</param>
public class Handoff(string target, string? description = null, string? name = null, string? message = null)
{
private static string? CheckName(string? name)
{
if (name != null && !AgentName.IsValid(name))
{
throw new ArgumentException($"Handoff name '{name}' is not a valid identifier.");
}
return name;
}
/// <summary>
/// The name of the target agent receiving the handoff.
/// </summary>
public AgentName Target { get; } = new AgentName(target);
/// <summary>
/// The description of the handoff such as the condition under which it should happen and the target.
/// </summary>
public string Description { get; } = description ?? $"Handoff to {target}";
/// <summary>
/// The name of this handoff configuration.
/// </summary>
public string Name { get; } = CheckName(name) ?? $"transfer_to_{target.ToLowerInvariant()}";
/// <summary>
/// The content of the HandoffMessage that will be sent.
/// </summary>
public string Message { get; } = message ?? $"Transferred to {target}, adopting the role of {target} immediately.";
/// <summary>
/// Handoff Tool to execute the handoff.
/// </summary>
public ITool HandoffTool => new CallableTool(this.Name, this.Description, () => { return this.Message; });
}

View File

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ITeam.cs
using Microsoft.AutoGen.Contracts;
namespace Microsoft.AutoGen.AgentChat.Abstractions;
/// <summary>
/// A team of agents.
/// </summary>
public interface ITeam : ITaskRunner, ISaveState
{
/// <summary>
/// Reset the team and all its participants to its initial state.
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns>A <see cref="ValueTask"/> representing the asynchronous operation.</returns>
ValueTask ResetAsync(CancellationToken cancellationToken = default);
}

View File

@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// MessageHandling.cs
namespace Microsoft.AutoGen.AgentChat.Abstractions;
public interface IHandleChat<in TIn>
{
public ValueTask HandleAsync(TIn item)
{
return this.HandleAsync(item, CancellationToken.None);
}
public ValueTask HandleAsync(TIn item, CancellationToken cancellationToken);
}
public interface IHandleChat<in TIn, TOut> // TODO: Map this to IHandle<> somehow?
{
public ValueTask<TOut> HandleAsync(TIn item)
{
return this.HandleAsync(item, CancellationToken.None);
}
public ValueTask<TOut> HandleAsync(TIn item, CancellationToken cancellationToken);
}
public interface IHandleDefault : IHandleChat<object>
{
}
public interface IHandleStream<in TIn, TOut>
{
public IAsyncEnumerable<TOut> StreamAsync(TIn item)
{
return this.StreamAsync(item, CancellationToken.None);
}
public IAsyncEnumerable<TOut> StreamAsync(TIn item, CancellationToken cancellationToken);
}

View File

@ -0,0 +1,755 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Messages.cs
using System.Collections;
using System.Diagnostics;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using Microsoft.AutoGen.AgentChat.GroupChat;
using Microsoft.Extensions.AI;
namespace Microsoft.AutoGen.AgentChat.Abstractions;
/// <summary>
/// The base class for all messages that can be sent between agents.
/// </summary>
/// <remarks>
/// This functions as a combination of both <c>BaseMessage</c> and <c>AgentMessage</c> on the Python side.
/// </remarks>
public abstract class AgentMessage
{
/// <summary>
/// The name of the agent that sent this message.
/// </summary>
public required string Source { get; set; }
/// <summary>
/// The <see cref="IChatClient"/> usage incurred when producing this message.
/// </summary>
public RequestUsage? ModelUsage { get; set; }
// IMPORTANT NOTE: Unlike the ITypeMarshal<AgentMessage, WireProtocol.AgentMessage> implementation in ProtobufTypeMarshal,
// the .ToWire() call on this is intended to be used for directly converting a concrete message type to its leaf representation.
// In the context of Protobuf these may not be the same due to discriminated union types being real types, as opposed to
// a runtime union restriction.
//public IMessage ToWire()
//{
// return this switch
// {
// ChatMessage chatMessage => ProtobufTypeMarshal.Convert<ChatMessage, WireProtocol.ChatMessage>(chatMessage),
// AgentEvent agentEvent => ProtobufTypeMarshal.Convert<AgentEvent, WireProtocol.AgentEvent>(agentEvent),
// _ => throw new InvalidOperationException($"Unknown type {this.GetType().Name}"),
// };
//}
}
/// <summary>
/// Events emitted by agents and teams when they work, not used for agent-to-agent communication.
/// </summary>
public abstract class AgentEvent : AgentMessage
{
public Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage()
=> ToCompletionClientMessage(role: ChatRole.Assistant);
/// <summary>
/// Converts the <see cref="AgentEvent"/> to a <see cref="Microsoft.Extensions.AI.ChatMessage"/>.
/// </summary>
/// <remarks>
/// This should usually be <see cref="ChatRole.Assistant"/>
/// </remarks>
/// <param name="role">The role of the agent that is sending the message.</param>
/// <returns>
/// A <see cref="Microsoft.Extensions.AI.ChatMessage"/> that represents the <see cref="AgentEvent"/>.
/// </returns>
public abstract Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role);
}
/// <summary>
/// Messages for agent-to-agent communication.
/// </summary>
public abstract class ChatMessage : AgentMessage
{
/// <summary>
/// Converts the <see cref="ChatMessage"/> to a <see cref="Microsoft.Extensions.AI.ChatMessage"/>.
/// </summary>
/// <param name="role">The role of the agent that is sending the message.</param>
/// <returns>
/// A <see cref="Microsoft.Extensions.AI.ChatMessage"/> that represents the <see cref="ChatMessage"/>.
/// </returns>
public abstract Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role);
}
// Leaf Classes
/// <summary>
/// A text message.
/// </summary>
public class TextMessage : ChatMessage
{
/// <summary>
/// The content of the message.
/// </summary>
public required string Content { get; set; }
/// <inheritdoc cref="ChatMessage.ToCompletionClientMessage(ChatRole)" />/>
public override Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role)
{
return new Microsoft.Extensions.AI.ChatMessage(role, this.Content) { AuthorName = this.Source };
}
}
/// <summary>
/// The data inside of a multi-modal message. Can be either a <c>string</c> or an Image.
/// </summary>
/// <remarks>
/// This presents an API surface around the types that are supported by AgentChat, rather
/// than allowing any <see cref="Microsoft.Extensions.AI.AIContent"/>.
/// </remarks>
public struct MultiModalData
{
/// <summary>
/// Supported <c>Type</c>s of <see cref="Microsoft.Extensions.AI.AIContent"/>.
/// </summary>
public enum Type
{
String, Image
}
/// <summary>
/// Checks the type of the <see cref="AIContent"/> and wraps it in a <see cref="MultiModalData"/> instance if
/// it is a supported type.
/// </summary>
/// <param name="item">The <see cref="AIContent"/> to wrap.</param>
/// <returns>A <see cref="MultiModalData"/> instance wrapping the <paramref name="item"/>.</returns>
/// <exception cref="ArgumentException">
/// Thrown if the <paramref name="item"/> is not a <see cref="TextContent"/> or <see cref="DataContent"/>.
/// </exception>
public static MultiModalData CheckTypeAndCreate(AIContent item)
{
if (item is TextContent text)
{
return new MultiModalData(text);
}
else if (item is DataContent image)
{
return new MultiModalData(image);
}
else
{
throw new ArgumentException("Only TextContent and ImageContent are allowed in MultiModalMessage");
}
}
/// <summary>
/// Initializes a new instance of the <see cref="MultiModalData"/> with a <see cref="string"/>.
/// </summary>
/// <param name="text">The text to wrap.</param>
public MultiModalData(string text)
{
ContentType = Type.String;
AIContent = new TextContent(text);
}
/// <summary>
/// Initializes a new instance of the <see cref="MultiModalData"/> with a <see cref="TextContent"/>.
/// </summary>
/// <param name="textContent">The <see cref="TextContent"/> to wrap.</param>
public MultiModalData(TextContent textContent)
{
ContentType = Type.String;
AIContent = textContent;
}
/// <summary>
/// Initializes a new instance of the <see cref="MultiModalData"/> with an <see cref="DataContent"/>.
/// </summary>
/// <param name="image">The image to wrap.</param>
public MultiModalData(DataContent image)
{
ContentType = Type.Image;
AIContent = image;
}
/// <summary>
/// Gets the <see cref="AIContent"/> wrapped by this instance.
/// </summary>
public Type ContentType { get; }
/// <summary>
/// Gets the <see cref="AIContent"/> wrapped by this instance.
/// </summary>
public AIContent AIContent { get; }
}
/// <summary>
/// A multi-modal message.
/// </summary>
public class MultiModalMessage : ChatMessage, IList<AIContent>
{
/// <inheritdoc cref="IList{T}.this" />"
public AIContent this[int index]
{
get => this.Content[index].AIContent;
set => this.Content[index] = MultiModalData.CheckTypeAndCreate(value);
}
/// <summary>
/// The contents of the message.
/// </summary>
public List<MultiModalData> Content { get; private set; } = new List<MultiModalData>();
/// <inheritdoc cref="ICollection{AIContent}.Count" />
public int Count => this.Content.Count;
/// <inheritdoc cref="ICollection{AIContent}.IsReadOnly" />
public bool IsReadOnly => false;
/// <summary>
/// Adds a range of <see cref="MultiModalData"/> to the message. The type does not need
/// to be checked because it was already validated when the <see cref="MultiModalData"/>
/// was created.
/// </summary>
/// <param name="items">The items to add.</param>
internal void AddRangeUnchecked(IEnumerable<MultiModalData> items)
{
this.Content.AddRange(items);
}
/// <summary>
/// Checks and adds a range of <see cref="AIContent"/> to the message.
/// </summary>
/// <param name="items">The items to add.</param>
public void AddRange(IEnumerable<AIContent> items)
{
foreach (AIContent item in items)
{
this.Content.Add(MultiModalData.CheckTypeAndCreate(item));
}
}
/// <summary>
/// Adds a range of <see cref="string"/> to the message.
/// </summary>
/// <param name="textItems">The items to add.</param>
public void AddRange(IEnumerable<TextContent> textItems)
{
foreach (TextContent item in textItems)
{
this.Add(item);
}
}
/// <summary>
/// Adds a range of <see cref="string"/> to the message.
/// </summary>
/// <param name="textItems">The items to add.</param>
public void AddRange(IEnumerable<string> textItems)
{
foreach (string item in textItems)
{
this.Add(item);
}
}
/// <summary>
/// Adds a range of <see cref="DataContent"/> to the message.
/// </summary>
/// <param name="images">The items to add.</param>
public void AddRange(IEnumerable<DataContent> images)
{
foreach (DataContent image in images)
{
this.Add(image);
}
}
/// <summary>
/// Checks and adds an <see cref="AIContent"/> to the message.
/// </summary>
/// <param name="item">The item to add.</param>
public void Add(AIContent item)
{
this.Content.Add(MultiModalData.CheckTypeAndCreate(item));
}
/// <summary>
/// Adds a <see cref="string"/> to the message.
/// </summary>
/// <param name="text">The text to add.</param>
public void Add(string text)
{
this.Content.Add(new(text));
}
/// <summary>
/// Adds a <see cref="TextContent"/> to the message.
/// </summary>
/// <param name="image">The image to add.</param>
public void Add(DataContent image)
{
this.Content.Add(new(image));
}
/// <summary>
/// Adds a <see cref="TextContent"/> to the message.
/// </summary>
/// <param name="text">The <see cref="TextContent"/> to add.</param>
public void Add(TextContent text)
{
this.Content.Add(new(text));
}
/// <inheritdoc cref="ICollection{AIContent}.Clear" />
public void Clear()
{
this.Content.Clear();
}
/// <inheritdoc cref="ICollection{AIContent}.Contains" />
public bool Contains(AIContent item)
{
return this.Content.Any(x => x.AIContent == item);
}
/// <inheritdoc cref="ICollection{AIContent}.CopyTo" />
public void CopyTo(AIContent[] array, int arrayIndex)
{
if (array == null)
{
throw new ArgumentNullException(nameof(array));
}
if (arrayIndex < 0 || arrayIndex >= array.Length)
{
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
}
if (array.Length - arrayIndex < this.Content.Count)
{
throw new ArgumentException("The number of elements in the source is greater than the available space from arrayIndex to the end of the destination array.");
}
for (var i = 0; i < this.Content.Count; i++)
{
array[arrayIndex + i] = this.Content[i].AIContent;
}
}
/// <inheritdoc cref="IEnumerable{AIContent}.GetEnumerator" />
public IEnumerator<AIContent> GetEnumerator()
{
return this.Content.Select(x => x.AIContent).GetEnumerator();
}
/// <inheritdoc cref="IList{AIContent}.IndexOf" />
public int IndexOf(AIContent item)
{
return this.Content.FindIndex(x => x.AIContent == item);
}
/// <inheritdoc cref="IList{String}.IndexOf(String)"/>
public int IndexOf(string text)
{
return this.Content.FindIndex(x => x.ContentType == MultiModalData.Type.String && ((TextContent)x.AIContent).Text == text);
}
/// <inheritdoc cref="IList{AIContent}.Insert" />/>
public void Insert(int index, AIContent item)
{
this.Content.Insert(index, MultiModalData.CheckTypeAndCreate(item));
}
/// <inheritdoc cref="IList{String}.Insert(int, String)"/>
public void Insert(int index, string text)
{
this.Content.Insert(index, new(text));
}
/// <inheritdoc cref="IList{TextContent}.Insert(int, TextContent)"/>
public void Insert(int index, TextContent text)
{
this.Content.Insert(index, new(text));
}
/// <inheritdoc cref="IList{ImageContent}.Insert(int, ImageContent)"/>
public void Insert(int index, DataContent image)
{
this.Content.Insert(index, new(image));
}
/// <inheritdoc cref="ICollection{AIContent}.Remove" />
public bool Remove(AIContent item)
{
int targetIndex = Content.FindIndex(x => x.AIContent == item);
if (targetIndex == -1)
{
return false;
}
this.Content.RemoveAt(targetIndex);
return true;
}
/// <inheritdoc cref="IList{AIContent}.RemoveAt" />
public void RemoveAt(int index)
{
this.Content.RemoveAt(index);
}
/// <inheritdoc cref="IEnumerable.GetEnumerator" />
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
/// <inheritdoc cref="ChatMessage.ToCompletionClientMessage(ChatRole)" />/>
public override Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role)
{
StringBuilder contentBuilder = new StringBuilder();
foreach (MultiModalData item in this.Content)
{
if (item.ContentType == MultiModalData.Type.String)
{
contentBuilder.AppendLine(item.AIContent.RawRepresentation as string ?? "");
}
else if (item.ContentType == MultiModalData.Type.Image)
{
contentBuilder.AppendLine("[Image]");
}
}
return new Microsoft.Extensions.AI.ChatMessage(role, contentBuilder.ToString()) { AuthorName = this.Source };
}
}
/// <summary>
/// A message requesting stop of a conversation.
/// </summary>
public class StopMessage : ChatMessage
{
public required string Content { get; set; }
public override Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role)
{
Debug.Assert(role == ChatRole.Assistant, "StopMessage can only come from agents in the Assistant Role");
return new Microsoft.Extensions.AI.ChatMessage(ChatRole.Assistant, this.Content) { AuthorName = this.Source };
}
}
/// <summary>
/// A message requesting handoff of a conversation to another agent.
/// </summary>
public class HandoffMessage : ChatMessage
{
/// <summary>
/// The name of the target agent to handoff to.
/// </summary>
public required string Target { get; set; }
/// <summary>
/// The handoff message to the target agent.
/// </summary>
public required string Context { get; set; }
/// <inheritdoc cref="ChatMessage.ToCompletionClientMessage(ChatRole)" />/>
public override Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role)
{
Debug.Assert(role == ChatRole.Assistant, "HandoffMessage can only come from agents in the Assistant Role");
return new Microsoft.Extensions.AI.ChatMessage(ChatRole.Assistant, this.Context) { AuthorName = this.Source };
}
}
/// <summary>
/// A request to call a function.
/// </summary>
public class FunctionCall
{
// TODO: Should this be part of the Autogen "Core" (and what does that even mean on the .NET side?)
// It is unfortuante that we have to duplicate this type, but in order to be compatible with Python, it is necessary for
// us to be able to process incoming FunctionCalls with parameters in the form of a JSON string. This means that without
// knowing the target function, and unless the types are specified inline in the JSON, we cannot deserialize them in a
// generic manner (or we need to have a central registry of function calls, which is undesirable).
// The solution, for now, is to keep the representation as JSON and provide a helper that binds the JSON to a candidate
// schema.
/// <summary>
/// An identifier representing this specific request. Responses will include this identifier.
/// </summary>
public required string Id { get; set; }
/// <summary>
/// The arguments to pass to the function in JSON format.
/// </summary>
public string? Arguments { get; set; }
/// <summary>
/// The name of the function to call.
/// </summary>
public required string Name { get; set; }
}
/// <summary>
/// The result of a function call.
/// </summary>
public class FunctionExecutionResult
{
/// <summary>
/// The identifier of the request that this result is for.
/// </summary>
public required string Id { get; set; }
/// <summary>
/// The name of the function that was called.
/// </summary>
public required string Name { get; set; }
/// <summary>
/// The result of calling the function.
/// </summary>
public required string Content { get; set; }
}
/// <summary>
/// An event signaling a request to use tools.
/// </summary>
public class ToolCallRequestEvent : AgentEvent
{
/// <summary>
/// The tool calls.
/// </summary>
public List<FunctionCall> Content { get; private set; } = new List<FunctionCall>();
/// <inheritdoc cref="AgentEvent.ToCompletionClientMessage(ChatRole)" />/>
public override Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role)
{
Debug.Assert(role == ChatRole.Assistant, "ToolCallMessage can only come from agents in the Assistant Role");
return new Microsoft.Extensions.AI.ChatMessage(ChatRole.Assistant, (IList<AIContent>)this.Content) { AuthorName = this.Source };
}
}
/// <summary>
/// An event signaling the execution of tool calls.
/// </summary>
public class ToolCallExecutionEvent : AgentEvent
{
/// <summary>
/// The tool call results.
/// </summary>
public List<FunctionExecutionResult> Content { get; private set; } = new List<FunctionExecutionResult>();
/// <inheritdoc cref="AgentEvent.ToCompletionClientMessage(ChatRole)" />/>
public override Microsoft.Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role)
{
Debug.Assert(role == ChatRole.Tool, "ToolCallResultMessage can only come from agents in the Tool Role");
return new Microsoft.Extensions.AI.ChatMessage(ChatRole.Tool, (IList<AIContent>)this.Content) { AuthorName = this.Source };
}
}
/// <summary>
/// A message summarizing the results of tool calls.
/// </summary>
public class ToolCallSummaryMessage : ChatMessage
{
/// <summary>
/// Summary of the tool call results.
/// </summary>
public required string Content { get; set; }
public override Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role)
{
Debug.Assert(role == ChatRole.Assistant, "ToolCallSummaryMessage can only come from agents in the Assistant Role");
return new Microsoft.Extensions.AI.ChatMessage(ChatRole.Assistant, this.Content) { AuthorName = this.Source };
}
}
/// <summary>
/// An event signaling that the user proxy has requested user input. Published prior to invoking the
/// input callback.
/// </summary>
public class UserInputRequestedEvent : AgentEvent
{
/// <summary>
/// Identifier for the user input request.
/// </summary>
public required string RequestId { get; set; }
/// <inheritdoc cref="AgentEvent.ToCompletionClientMessage(ChatRole)" />/>
public override Extensions.AI.ChatMessage ToCompletionClientMessage(ChatRole role)
{
throw new Exception("UserInputRequestedEvent should not be sent to the completion client");
}
}
public static class CompletionChatMessageExtensions
{
/// <summary>
/// Flattens a <see cref="Microsoft.Extensions.AI.ChatMessage"/> into a single <see cref="Microsoft.Extensions.AI.ChatMessage"/>
/// containing all of the content in the original message as a single string.
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="msg">
/// The <see cref="Microsoft.Extensions.AI.ChatMessage"/> to flatten.
/// </param>
/// <returns>
/// A new <see cref="Microsoft.Extensions.AI.ChatMessage"/> that is a flattened version of the input.
/// </returns>
public static Microsoft.Extensions.AI.ChatMessage Flatten(this Microsoft.Extensions.AI.ChatMessage msg)
{
if (msg.Contents.Count == 1 && msg.Contents[0] is TextContent)
{
return msg;
}
StringBuilder contentBuilder = new StringBuilder();
foreach (AIContent content in msg.Contents)
{
if (content is TextContent textContent)
{
contentBuilder.AppendLine(textContent.Text);
}
else if (content is DataContent)
{
contentBuilder.AppendLine("[Image]");
}
else
{
contentBuilder.AppendLine($"[{content.GetType().Name}]");
}
}
return new Microsoft.Extensions.AI.ChatMessage(msg.Role, contentBuilder.ToString())
{
AuthorName = msg.AuthorName,
AdditionalProperties = msg.AdditionalProperties
};
}
}
public static class MessageSerializationHelpers
{
internal sealed class TypeNode(Type type)
{
public Type Type { get; } = type;
public TypeNode? Parent { get; set; }
public TypeNode Root => this.Parent?.Root ?? this;
public List<TypeNode> Children { get; } = new List<TypeNode>();
public IEnumerable<Type> ChildrenTransitiveClosure
{
get
{
return this.Children.Select(c => c.Type)
.Concat(Children.SelectMany(c => c.ChildrenTransitiveClosure));
}
}
}
internal sealed class TypeTree
{
private static IEnumerable<Type> GetDerivedTypes(Type type)
{
// Across all assemblies
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
// Get all types in the assembly
foreach (var derivedType in assembly.GetTypes().Where(t => type.IsAssignableFrom(t) && t != type))
{
yield return derivedType;
}
}
}
private TypeNode EnsureTypeNode(Type type)
{
if (!this.TypeNodes.TryGetValue(type, out TypeNode? currentNode))
{
currentNode = this.TypeNodes[type] = new TypeNode(type);
}
return currentNode;
}
private void EnsureType(Type type)
{
TypeNode? currentNode = this.EnsureTypeNode(type);
while (currentNode != null &&
currentNode.Parent == null &&
!this.RootTypes.Contains(currentNode.Type))
{
Type parentType = currentNode.Type.BaseType
?? throw new InvalidOperationException("We should never have a non-Root, underived base");
TypeNode parentNode = this.EnsureTypeNode(parentType);
currentNode.Parent = parentNode;
parentNode.Children.Add(currentNode);
currentNode = parentNode;
}
}
public HashSet<Type> RootTypes { get; }
public Dictionary<Type, TypeNode> TypeNodes { get; } = new Dictionary<Type, TypeNode>();
public TypeTree(params Type[] rootTypes)
{
this.RootTypes = new HashSet<Type>();
foreach (var rootType in rootTypes)
{
// Check that there are no other types that this type derives from in the root types
// or vice versa
if (this.RootTypes.Any(t => t.IsAssignableFrom(rootType) || rootType.IsAssignableFrom(t)))
{
throw new ArgumentException($"Root types cannot be derived from each other: {rootType.Name}");
}
this.RootTypes.Add(rootType);
this.EnsureType(rootType);
foreach (var derivedType in GetDerivedTypes(rootType))
{
this.EnsureType(derivedType);
}
}
}
}
internal static readonly TypeTree MessageTypeTree = new(typeof(AgentMessage), typeof(GroupChatEventBase));
internal sealed class MessagesTypeInfoResolver : DefaultJsonTypeInfoResolver
{
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
JsonTypeInfo baseTypeInfo = base.GetTypeInfo(type, options);
if (MessageTypeTree.TypeNodes.TryGetValue(type, out TypeNode? typeNode) &&
typeNode.Children.Any()) // Only add polymorphism info if there are derived children
{
if (baseTypeInfo.PolymorphismOptions == null)
{
baseTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions();
}
baseTypeInfo.PolymorphismOptions.IgnoreUnrecognizedTypeDiscriminators = true;
baseTypeInfo.PolymorphismOptions.UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization;
foreach (Type childType in typeNode.ChildrenTransitiveClosure)
{
if (childType.IsAbstract || childType.IsInterface || childType.IsGenericTypeDefinition)
{
// Can only deserialize concrete, complete types.
continue;
}
baseTypeInfo.PolymorphismOptions.DerivedTypes.Add(new JsonDerivedType(childType, childType.FullName ?? childType.Name));
}
}
return baseTypeInfo;
}
}
}

View File

@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ModelContext.cs
using System.Text.Json;
using Microsoft.AutoGen.AgentChat.State;
using Microsoft.AutoGen.Contracts;
using LLMMessage = Microsoft.Extensions.AI.ChatMessage;
namespace Microsoft.AutoGen.AgentChat.Abstractions;
public interface IModelContext : ISaveState
{
public void Add(LLMMessage message);
public void Clear();
public IEnumerable<LLMMessage> Messages { get; }
}
public sealed class ModelContextState : BaseState
{
public List<LLMMessage> Messages { get; set; } = new();
}
public abstract class ModelContextBase : IModelContext
{
protected readonly List<LLMMessage> messages;
public abstract IEnumerable<LLMMessage> Messages { get; }
public ModelContextBase(params IEnumerable<LLMMessage> messages)
{
this.messages = [.. messages];
}
public void Add(LLMMessage message)
{
this.messages.Add(message);
}
public void Clear()
{
this.messages.Clear();
}
public ValueTask<JsonElement> SaveStateAsync()
{
SerializedState state = SerializedState.Create(new ModelContextState { Messages = this.messages });
return ValueTask.FromResult(state.AsJson());
}
public ValueTask LoadStateAsync(JsonElement state)
{
SerializedState serializedState = new(state);
ModelContextState modelContextState = serializedState.As<ModelContextState>();
this.messages.Clear();
this.messages.AddRange(modelContextState.Messages);
return ValueTask.CompletedTask;
}
}
public sealed class UnboundedModelContext : ModelContextBase
{
public UnboundedModelContext(params IEnumerable<LLMMessage> messages) : base(messages)
{
}
public override IEnumerable<LLMMessage> Messages => this.messages;
}
// TODO: Promote ModelContext to AutoGen.Core

View File

@ -0,0 +1,117 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Tasks.cs
namespace Microsoft.AutoGen.AgentChat.Abstractions;
/// <summary>
/// Result of running a task.
/// </summary>
/// <param name="messages">Messages produced by the task.</param>
public struct TaskResult(List<AgentMessage> messages)
{
/// <summary>
/// Message produced by the task.
/// </summary>
public List<AgentMessage> Messages { get; } = messages;
/// <summary>
/// The reason the task stopped.
/// </summary>
public string? StopReason = null;
}
/// <summary>
/// The stream frame for <see cref="ITaskRunner.StreamAsync(string, CancellationToken)"/>.
/// </summary>
public class TaskFrame : StreamingFrame<TaskResult>
{
/// <summary>
/// Create a new <see cref="TaskFrame"/> with a response.
/// </summary>
/// <param name="response">Result of running a task.</param>
public TaskFrame(TaskResult response)
{
this.Response = response;
this.Type = TaskFrame.FrameType.Response;
}
/// <summary>
/// Create a new <see cref="TaskFrame"/> with an internal message.
/// </summary>
/// <param name="message">The internal message.</param>
public TaskFrame(AgentMessage message)
{
this.InternalMessage = message;
this.Type = TaskFrame.FrameType.InternalMessage;
}
}
/// <summary>
/// A task runner.
/// </summary>
public interface ITaskRunner
{
private static ChatMessage ToMessage(string task) => new TextMessage { Content = task, Source = "user" };
/// <summary>
/// Run the task and return the result.
/// </summary>
/// <param name="task">The task definition in text form.</param>
/// <param name="cancellationToken"></param>
/// <returns>The result of running the task.</returns>
public async ValueTask<TaskResult> RunAsync(string task, CancellationToken cancellationToken = default) =>
await this.RunAsync(ToMessage(task)!, cancellationToken);
/// <summary>
/// Run the task and return the result.
/// </summary>
/// <remarks>
/// The runner is stateful and a subsequent call to this method will continue from where the previous
/// call left off.If the task is not specified,the runner will continue with the current task.
/// </remarks>
/// <param name="task">The task definition as a message.</param>
/// <param name="cancellationToken"></param>
/// <returns>The result of running the task.</returns>
/// <exception cref="InvalidOperationException">If no response is generated.</exception>
public async ValueTask<TaskResult> RunAsync(ChatMessage task, CancellationToken cancellationToken = default)
{
await foreach (TaskFrame frame in this.StreamAsync(task, cancellationToken))
{
if (frame.Type == TaskFrame.FrameType.Response)
{
return frame.Response!;
}
}
throw new InvalidOperationException("The stream should have returned the final result.");
}
/// <summary>
/// Run the task and produce a stream of <see cref="TaskFrame"/> and the final <see cref="TaskResult"/>
/// is the last frame in the stream.
/// </summary>
/// <remarks>
/// The runner is stateful and a subsequent call to this method will continue from where the previous
/// call left off.If the task is not specified,the runner will continue with the current task.
/// </remarks>
/// <param name="task">The task definition as a string.</param>
/// <param name="cancellationToken"></param>
/// <returns>A stream of <see cref="TaskFrame"/> containing internal messages and intermediate results followed by
/// the final <see cref="TaskResult"/></returns>
public IAsyncEnumerable<TaskFrame> StreamAsync(string task, CancellationToken cancellationToken = default) =>
this.StreamAsync(ToMessage(task), cancellationToken);
/// <summary>
/// Run the task and produce a stream of <see cref="TaskFrame"/> and the final <see cref="TaskResult"/>
/// is the last frame in the stream.
/// </summary>
/// <remarks>
/// The runner is stateful and a subsequent call to this method will continue from where the previous
/// call left off.If the task is not specified,the runner will continue with the current task.
/// </remarks>
/// <param name="task">The task definition as a message.</param>
/// <param name="cancellationToken"></param>
/// <returns>A stream of <see cref="TaskFrame"/> containing internal messages and intermediate results followed by
/// the final <see cref="TaskResult"/></returns>
public IAsyncEnumerable<TaskFrame> StreamAsync(ChatMessage? task, CancellationToken cancellationToken = default);
}

View File

@ -0,0 +1,208 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Termination.cs
namespace Microsoft.AutoGen.AgentChat.Abstractions;
public static class TerminationConditionExtensions
{
/// <summary>
/// Combine this termination condition with another using a logical OR.
/// </summary>
/// <param name="other">Another termination condition.</param>
/// <returns>The combined termination condition, with appropriate short-circuiting.</returns>
public static ITerminationCondition Or(this ITerminationCondition this_, ITerminationCondition other)
{
return new CombinerCondition(CombinerCondition.Or, this_, other);
}
/// <summary>
/// Combine this termination condition with another using a logical AND.
/// </summary>
/// <param name="other">Another termination condition.</param>
/// <returns>The combined termination condition, with appropriate short-circuiting.</returns>
public static ITerminationCondition And(this ITerminationCondition this_, ITerminationCondition other)
{
return new CombinerCondition(CombinerCondition.And, this_, other);
}
}
/// <summary>
/// A stateful condition that determines when a conversation should be terminated.
///
/// A termination condition takes a sequences of <see cref="AgentMessage"/> objects since the last time the
/// condition was checked, and returns a <see cref="StopMessage"/> if the conversation should be terminated,
/// or <c>null</c> otherwise.
///
/// Once a termination condition has been reached, it must be <see cref="Reset()"/> before it can be used again.
///
/// Termination conditions can be combined using the <see cref="TerminationConditionExtensions.Or"/> and
/// <see cref="TerminationConditionExtensions.And"/> methods.
/// </summary>
public interface ITerminationCondition
{
/// <summary>
/// Checks if the termination condition has been reached
/// </summary>
public bool IsTerminated { get; }
/// <summary>
/// Check if the conversation should be terminated based on the messages received
/// since the last time the condition was called.
/// Return a <see cref="StopMessage"/> if the conversation should be terminated, or <c>null</c> otherwise.
/// </summary>
/// <param name="messages">The messages received since the last time the condition was called.</param>
/// <returns>A <see cref="StopMessage"/> if the conversation should be terminated, or <c>null</c>
/// otherwise.</returns>
/// <exception cref="TerminatedException">If the termination condition has already been reached.</exception>
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages);
/// <summary>
/// Resets the termination condition.
/// </summary>
public void Reset();
/// <summary>
/// Combine two termination conditions with another using an associative, short-circuiting OR.
/// </summary>
/// <param name="left">
/// The left-hand side termination condition. If this condition is already a disjunction, the RHS condition is added to the list of clauses.
/// </param>
/// <param name="right">
/// The right-hand side termination condition. If the LHS condition is already a disjunction, this condition is added to the list of clauses.
/// </param>
/// <returns>
/// The combined termination condition, with appropriate short-circuiting.
/// </returns>
public static ITerminationCondition operator |(ITerminationCondition left, ITerminationCondition right)
{
return left.Or(right);
}
/// <summary>
/// Combine two termination conditions with another using an associative, short-circuiting AND.
/// </summary>
/// <param name="left">
/// The left-hand side termination condition. If this condition is already a conjunction, the RHS condition is added to the list of clauses.
/// </param>
/// <param name="right">
/// The right-hand side termination condition. If the LHS condition is already a conjunction, this condition is added to the list of clauses.
/// </param>
/// <returns>
/// The combined termination condition, with appropriate short-circuiting.
/// </returns>
public static ITerminationCondition operator &(ITerminationCondition left, ITerminationCondition right)
{
return left.And(right);
}
}
/// <summary>
/// Exception thrown when a termination condition has already been reached.
/// </summary>
public sealed class TerminatedException : Exception
{
public TerminatedException() : base("The termination condition has already been reached.")
{
}
}
/// <summary>
/// A termination condition that combines multiple termination conditions using a logical AND or OR.
/// </summary>
internal sealed class CombinerCondition : ITerminationCondition
{
public const bool Conjunction = true;
public const bool Disjunction = false;
public const bool And = Conjunction;
public const bool Or = Disjunction;
private List<StopMessage> stopMessages = new List<StopMessage>();
private List<ITerminationCondition> clauses;
private readonly bool conjunction;
/// <summary>
/// Create a new <see cref="CombinerCondition"/> with the given conjunction and clauses.
/// </summary>
/// <param name="conjunction">The conjunction to use when combining the clauses.</param>
/// <param name="clauses">The termination conditions to combine.</param>
public CombinerCondition(bool conjunction, params IEnumerable<ITerminationCondition> clauses)
{
// Flatten the list of clauses by unwrapping included CombinerConditions if their
// conjunctions match (since combiners with associative conjunctions can be hoisted).
IEnumerable<ITerminationCondition> flattened =
clauses.SelectMany(c =>
(c is CombinerCondition combiner && combiner.conjunction == conjunction)
? (IEnumerable<ITerminationCondition>)combiner.clauses
: new[] { c });
this.conjunction = conjunction;
this.clauses = flattened.ToList();
}
/// <inheritdoc cref="ITerminationCondition.IsTerminated" />
public bool IsTerminated { get; private set; }
/// <inheritdoc cref="ITerminationCondition.Reset" />
public void Reset()
{
this.stopMessages.Clear();
this.clauses.ForEach(c => c.Reset());
this.IsTerminated = false;
}
/// <inheritdoc cref="ITerminationCondition.CheckAndUpdateAsync" />
public async ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
// When operating as a conjunction, we may be accumulated terminating conditions, but we will not fire until
// all of them are complete. In this case, we need to avoid continuing to interact with already terminated
// clauses, because trying to update them will throw
var candidateTerminations = this.conjunction ? this.clauses.Where(clause => !clause.IsTerminated) : clauses;
// TODO: Do we really need these to be ValueTasks? (Alternatively: Do we really need to run them explicitly
// on every invocation, or is a Worker pattern more appropriate?)
List<Task<StopMessage?>> tasks = candidateTerminations.Select(c => c.CheckAndUpdateAsync(messages).AsTask()).ToList();
StopMessage?[] results = await Task.WhenAll(tasks);
bool raiseTermination = this.conjunction; // if or, we start with false until we observe a true
// if and, we start with true until we observe a false
foreach (StopMessage? maybeStop in results)
{
if (maybeStop != null)
{
this.stopMessages.Add(maybeStop);
if (!this.conjunction)
{
// If any clause terminates, the disjunction terminates
raiseTermination = true;
}
}
else if (this.conjunction)
{
// If any clause does not terminate, the conjunction does not terminate
raiseTermination = false;
}
}
if (raiseTermination)
{
this.IsTerminated = true;
return new StopMessage
{
Content = string.Join("; ", stopMessages.Select(sm => sm.Content)),
Source = string.Join(", ", stopMessages.Select(sm => sm.Source))
};
}
return null;
}
}

View File

@ -0,0 +1,124 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Tools.cs
using System.Reflection;
using Microsoft.Extensions.AI;
namespace Microsoft.AutoGen.AgentChat.Abstractions;
// TODO: This likely should live as a "Component" in an Agent-building ClassLib?
// It seems like it could have applicability beyond AgentChat.
public class ParameterSchema(string name, Type type, bool isRequired = false, object? defaultValue = default)
{
public string Name { get; } = name;
public Type Type { get; } = type;
public bool IsRequired { get; } = isRequired;
public object? DefaultValue { get; } = defaultValue;
public static implicit operator ParameterSchema(ParameterInfo parameterInfo)
{
Type parameterType = parameterInfo.ParameterType;
return ParameterSchema<object>.Create(parameterType, parameterInfo.Name!, parameterInfo.HasDefaultValue, parameterInfo.DefaultValue);
}
}
// TODO: Can this be obviated by AIFunctionParameter?
public class ParameterSchema<T>(string name, bool isRequired = false, T? defaultValue = default)
: ParameterSchema(name, typeof(T), isRequired, defaultValue)
{
public static ParameterSchema Create(Type type, string name, bool isRequired = false, object? defaultValue = default)
{
Type parameterSchemaType = typeof(ParameterSchema<>).MakeGenericType(type);
ParameterSchema? maybeResult = Activator.CreateInstance(parameterSchemaType, name, isRequired, defaultValue) as ParameterSchema;
return maybeResult!;
}
}
/// <summary>
/// A tool that can be executed by agents.
/// </summary>
public interface ITool
{
public string Name { get; }
public string Description { get; }
public IEnumerable<ParameterSchema> Parameters { get; }
// TODO: State serialization
// TODO: Can we somehow make this a ValueTask?
public Task<object> ExecuteAsync(IEnumerable<object> parameters, CancellationToken cancellationToken = default);
/// <summary>
/// This tool represented as an <see cref="AIFunction"/>.
/// </summary>
public AIFunction AIFunction
{
get
{
return CallableTool.CreateAIFunction(this.Name, this.Description, this.ExecuteAsync);
}
}
}
public static class TypeExtensions
{
private static ISet<Type> TaskTypes = new HashSet<Type>([typeof(Task<>), typeof(ValueTask<>)]);
public static Type UnwrapReturnIfAsync(this Type type)
{
if (type.IsGenericType && TaskTypes.Contains(type.GetGenericTypeDefinition()))
{
return type.GetGenericArguments()[0];
}
else if (type == typeof(Task) || type == typeof(ValueTask))
{
return typeof(void);
}
else
{
return type;
}
}
}
/// <summary>
/// Projects a <see cref="AIFunction"/> as an <see cref="ITool"/>.
/// </summary>
/// <param name="aiFunction">The <see cref="AIFunction"/> to wrap.</param>
public class AIFunctionTool(AIFunction aiFunction) : ITool
{
/// <inheritdoc cref="ITool.AIFunction" />
public AIFunction AIFunction { get; } = aiFunction;
/// <inheritdoc cref="ITool.Name" />
public string Name => this.AIFunction.Name;
/// <inheritdoc cref="ITool.Description" />
public string Description => this.AIFunction.Description;
/// <inheritdoc cref="ITool.Parameters" />
public IEnumerable<ParameterSchema> Parameters => from rawParameter in this.AIFunction.UnderlyingMethod!.GetParameters()
select (ParameterSchema)rawParameter;
/// <inheritdoc cref="ITool.ExecuteAsync" />
public Task<object> ExecuteAsync(IEnumerable<object> parameters, CancellationToken cancellationToken = default)
=> this.ExecuteAsync(parameters, cancellationToken);
}
/// <summary>
/// Projects a <c>delegate</c> as a <see cref="ITool"/> by wrapping it in <see cref="AIFunction"/>.
/// </summary>
/// <param name="name">The name of the tool.</param>
/// <param name="description">The description of the tool.</param>
/// <param name="callable">The <c>delegate</c> to wrap.</param>
public class CallableTool(string name, string description, Delegate callable)
: AIFunctionTool(CreateAIFunction(name, description, callable))
{
internal static AIFunction CreateAIFunction(string name, string description, Delegate callable)
{
return AIFunctionFactory.Create(callable, name: name, description: description);
}
}

View File

@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Usage.cs
namespace Microsoft.AutoGen.AgentChat.Abstractions;
public struct RequestUsage
{
public int PromptTokens { get; set; }
public int CompletionTokens { get; set; }
}

View File

@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ChatAgentBase.cs
using System.Runtime.CompilerServices;
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Agents;
/// <summary>
/// Base class for a chat agent.
/// </summary>
public abstract class ChatAgentBase : IChatAgent
{
public ChatAgentBase(string name, string description)
{
Name = new AgentName(name);
Description = description;
}
/// <inheritdoc cref="IChatAgent.Name"/>
public AgentName Name { get; }
/// <inheritdoc cref="IChatAgent.Description"/>
public string Description { get; }
/// <inheritdoc cref="IHandleStream{TIn, TOut}.StreamAsync(TIn, CancellationToken)"/>
public virtual async IAsyncEnumerable<ChatStreamFrame> StreamAsync(IEnumerable<ChatMessage> item, [EnumeratorCancellation] CancellationToken cancellationToken)
{
Response response = await (this).HandleAsync(item, cancellationToken);
if (response.InnerMessages != null)
{
foreach (var message in response.InnerMessages)
{
// It would be really nice to have type unions in .NET; need to think about how to make this interface nicer.
yield return new ChatStreamFrame { Type = ChatStreamFrame.FrameType.InternalMessage, InternalMessage = message };
}
}
yield return new ChatStreamFrame { Type = ChatStreamFrame.FrameType.Response, Response = response };
}
/// <inheritdoc cref="IChatAgent.ProducedMessageTypes"/>
public abstract IEnumerable<Type> ProducedMessageTypes { get; }
/// <inheritdoc cref="IHandleChat{TIn, TOut}.HandleAsync(TIn, CancellationToken)"/>
public abstract ValueTask<Response> HandleAsync(IEnumerable<ChatMessage> item, CancellationToken cancellationToken);
/// <inheritdoc cref="IChatAgent.ResetAsync(CancellationToken)"/>
public abstract ValueTask ResetAsync(CancellationToken cancellationToken);
}

View File

@ -0,0 +1,119 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ChatAgentRouter.cs
using System.Text.Json;
using Microsoft.AutoGen.AgentChat.Abstractions;
using Microsoft.AutoGen.AgentChat.State;
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
public struct AgentChatConfig(IChatAgent chatAgent, string parentTopicType, string outputTopicType)
{
public string ParticipantTopicType => this.Name;
public string ParentTopicType { get; } = parentTopicType;
public string OutputTopicType { get; } = outputTopicType;
public IChatAgent ChatAgent { get; } = chatAgent;
public string Name => this.ChatAgent.Name;
public string Description => this.ChatAgent.Description;
}
internal sealed class ChatAgentRouter : HostableAgentAdapter,
IHandle<GroupChatStart>,
IHandle<GroupChatAgentResponse>,
IHandle<GroupChatRequestPublish>,
IHandle<GroupChatReset>,
ISaveState
{
private readonly TopicId parentTopic;
private readonly TopicId outputTopic;
private readonly IChatAgent agent;
public ChatAgentRouter(AgentInstantiationContext agentCtx, AgentChatConfig config, ILogger<BaseAgent>? logger = null) : base(agentCtx, config.Description, logger)
{
this.parentTopic = new TopicId(config.ParentTopicType, this.Id.Key);
this.outputTopic = new TopicId(config.OutputTopicType, this.Id.Key);
this.agent = config.ChatAgent;
}
public List<ChatMessage> MessageBuffer { get; private set; } = new();
public ValueTask HandleAsync(GroupChatStart item, MessageContext messageContext)
{
if (item.Messages != null)
{
this.MessageBuffer.AddRange(item.Messages);
}
return ValueTask.CompletedTask;
}
public ValueTask HandleAsync(GroupChatAgentResponse item, MessageContext messageContext)
{
this.MessageBuffer.Add(item.AgentResponse.Message);
return ValueTask.CompletedTask;
}
public async ValueTask HandleAsync(GroupChatRequestPublish item, MessageContext messageContext)
{
Response? response = null;
// TODO: Is there a better abstraction here than IAsyncEnumerable? Though the akwardness mainly comes from
// the lack of real type unions in C#, which is why we need to create the StreamingFrame type in the first
// place.
await foreach (ChatStreamFrame frame in this.agent.StreamAsync(this.MessageBuffer, messageContext.CancellationToken))
{
switch (frame.Type)
{
case ChatStreamFrame.FrameType.Response:
await this.PublishMessageAsync(new GroupChatMessage { Message = frame.Response!.Message }, this.outputTopic);
response = frame.Response;
break;
case ChatStreamFrame.FrameType.InternalMessage:
await this.PublishMessageAsync(new GroupChatMessage { Message = frame.InternalMessage! }, this.outputTopic);
break;
}
}
if (response == null)
{
throw new InvalidOperationException("The agent did not produce a final response. Check the agent's on_messages_stream method.");
}
this.MessageBuffer.Clear();
await this.PublishMessageAsync(new GroupChatAgentResponse { AgentResponse = response }, this.parentTopic);
}
public ValueTask HandleAsync(GroupChatReset item, MessageContext messageContext)
{
this.MessageBuffer.Clear();
return this.agent.ResetAsync(messageContext.CancellationToken);
}
async ValueTask<JsonElement> ISaveState.SaveStateAsync()
{
ChatAgentContainerState state = new ChatAgentContainerState
{
AgentState = new SerializedState(await this.agent.SaveStateAsync()),
MessageBuffer = this.MessageBuffer
};
return SerializedState.Create(state).AsJson();
}
ValueTask ISaveState.LoadStateAsync(JsonElement state)
{
ChatAgentContainerState parsedState = new SerializedState(state).As<ChatAgentContainerState>();
this.MessageBuffer = parsedState.MessageBuffer;
return this.agent.LoadStateAsync(parsedState.AgentState.AsJson());
}
}

View File

@ -0,0 +1,84 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Events.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
// using ProtobufTypeMarshal = Microsoft.AutoGen.AgentChat.WireProtocol.ProtobufTypeMarshal;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
public class GroupChatEventBase /*: IWireable*/
{
// public IMessage ToWire()
// {
// return this switch
// {
// GroupChatStart groupChatStart => ProtobufTypeMarshal.Convert<GroupChatStart, WireProtocol.GroupChatStart>(groupChatStart),
// GroupChatAgentResponse groupChatAgentResponse => ProtobufTypeMarshal.Convert<GroupChatAgentResponse, WireProtocol.GroupChatResponse>(groupChatAgentResponse),
// GroupChatRequestPublish groupChatRequestPublish => ProtobufTypeMarshal.Convert<GroupChatRequestPublish, WireProtocol.GroupChatRequestPublish>(groupChatRequestPublish),
// GroupChatMessage groupChatMessage => ProtobufTypeMarshal.Convert<GroupChatMessage, WireProtocol.GroupChatMessage>(groupChatMessage),
// GroupChatTermination groupChatTermination => ProtobufTypeMarshal.Convert<GroupChatTermination, WireProtocol.GroupChatTermination>(groupChatTermination),
// GroupChatReset groupChatReset => ProtobufTypeMarshal.Convert<GroupChatReset, WireProtocol.GroupChatReset>(groupChatReset),
// _ => throw new InvalidOperationException($"Unknown type {this.GetType().Name}"),
// };
// }
}
/// <summary>
/// A request to start a group chat.
/// </summary>
public class GroupChatStart : GroupChatEventBase
{
/// <summary>
/// An optional list of messages to start the group chat.
/// </summary>
public List<ChatMessage>? Messages { get; set; }
}
/// <summary>
/// A response published to a group chat.
/// </summary>
public class GroupChatAgentResponse : GroupChatEventBase
{
/// <summary>
/// The response from a agent.
/// </summary>
public required Response AgentResponse { get; set; }
}
/// <summary>
/// A request to publish a message to a group chat.
/// </summary>
public class GroupChatRequestPublish : GroupChatEventBase
{
}
/// <summary>
/// A message from a group chat.
/// </summary>
public class GroupChatMessage : GroupChatEventBase
{
/// <summary>
/// The message that was published.
/// </summary>
public required AgentMessage Message { get; set; }
}
/// <summary>
/// A message indicating that group chat was terminated.
/// </summary>
public class GroupChatTermination : GroupChatEventBase
{
/// <summary>
/// The stop message that indicates the reason of termination.
/// </summary>
public required StopMessage Message { get; set; }
}
/// <summary>
/// A request to reset the agents in the group chat.
/// </summary>
public class GroupChatReset : GroupChatEventBase
{
}

View File

@ -0,0 +1,350 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// GroupChatBase.cs
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.Json;
using Microsoft.AutoGen.AgentChat.Abstractions;
using Microsoft.AutoGen.AgentChat.State;
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
internal static class AgentsRuntimeExtensions
{
public static async ValueTask<AgentType> RegisterChatAgentAsync(this IAgentRuntime runtime, AgentChatConfig config)
{
AgentType type = config.Name;
AgentType resultType = await runtime.RegisterAgentFactoryAsync(type,
(id, runtime) =>
{
AgentInstantiationContext agentContext = new AgentInstantiationContext(id, runtime);
return ValueTask.FromResult<IHostableAgent>(new ChatAgentRouter(agentContext, config));
});
await runtime.AddSubscriptionAsync(new TypeSubscription(config.ParticipantTopicType, type));
await runtime.AddSubscriptionAsync(new TypeSubscription(config.ParentTopicType, type));
return resultType;
}
public static async ValueTask<AgentType> RegisterGroupChatManagerAsync<TManager>(this IAgentRuntime runtime, GroupChatOptions options, string teamId, Func<GroupChatOptions, TManager> factory)
where TManager : GroupChatManagerBase
{
AgentType type = GroupChatBase<TManager>.GroupChatManagerTopicType;
AgentId expectedId = new AgentId(type, teamId);
AgentType resultType = await runtime.RegisterAgentFactoryAsync(type,
(id, runtime) =>
{
Debug.Assert(expectedId == id, $"Expecting the AgentId {expectedId} to be the teamId {id}");
AgentInstantiationContext agentContext = new AgentInstantiationContext(id, runtime);
TManager gcm = factory(options); // TODO: Should we allow this to be async?
return ValueTask.FromResult<IHostableAgent>(new GroupChatHandlerRouter<TManager>(agentContext, gcm));
});
await runtime.AddSubscriptionAsync(new TypeSubscription(GroupChatBase<TManager>.GroupChatManagerTopicType, resultType));
await runtime.AddSubscriptionAsync(new TypeSubscription(options.GroupChatTopicType, resultType));
return resultType;
}
public static async ValueTask<AgentType> RegisterOutputCollectorAsync(this IAgentRuntime runtime, IOutputCollectionSink sink, string outputTopicType)
{
AgentType type = GroupChatBase<GroupChatManagerBase>.CollectorAgentType;
AgentType resultType = await runtime.RegisterAgentFactoryAsync(type,
(id, runtime) =>
{
AgentInstantiationContext agentContext = new AgentInstantiationContext(id, runtime);
return ValueTask.FromResult<IHostableAgent>(new OutputCollectorAgent(agentContext, sink));
});
await runtime.AddSubscriptionAsync(new TypeSubscription(outputTopicType, type));
return resultType;
}
}
public abstract class GroupChatBase<TManager> : ITeam where TManager : GroupChatManagerBase
{
// TODO: Where do these come from?
internal const string GroupTopicType = "group_topic";
internal const string OutputTopicType = "output_topic";
internal const string GroupChatManagerTopicType = "group_chat_manager";
internal const string CollectorAgentType = "collect_output_messages";
private GroupChatOptions GroupChatOptions { get; }
private readonly RuntimeLayer runtimeLayer;
private Dictionary<string, AgentChatConfig> Participants { get; } = new();
protected GroupChatBase(List<IChatAgent> participants, ITerminationCondition? terminationCondition = null, int? maxTurns = null)
{
this.GroupChatOptions = new GroupChatOptions(GroupTopicType, OutputTopicType)
{
TerminationCondition = terminationCondition,
MaxTurns = maxTurns,
};
foreach (var participant in participants)
{
AgentChatConfig config = new AgentChatConfig(participant, GroupTopicType, OutputTopicType);
this.Participants[participant.Name] = config;
this.GroupChatOptions.Participants[participant.Name] = new GroupParticipant(config.ParticipantTopicType, participant.Description);
}
this.TeamId = Guid.NewGuid().ToString().ToLowerInvariant();
this.runtimeLayer = new RuntimeLayer(this);
this.RunManager = new(this.InitializationLayersInternal);
}
public string TeamId
{
get;
private set;
}
public virtual TManager CreateChatManager(GroupChatOptions options)
{
try
{
if (Activator.CreateInstance(typeof(TManager), options) is TManager result)
{
return result;
}
}
catch (TargetInvocationException tie)
{
throw new Exception("Could not create chat manager", tie.InnerException);
}
catch (Exception ex)
{
throw new Exception("Could not create chat manager", ex);
}
throw new Exception("Could not create chat manager; make sure that it contains a ctor() or ctor(GroupChatOptions), or override the CreateChatManager method");
}
private sealed class RuntimeLayer(GroupChatBase<TManager> groupChat) : IRunContextLayer
{
public GroupChatBase<TManager> GroupChat { get; } = groupChat;
public InProcessRuntime? Runtime { get; private set; }
public OutputSink? OutputSink { get; private set; }
public Task? InitOnceTask { get; set; }
public Task ShutdownTask { get; set; } = Task.CompletedTask;
public async ValueTask DeinitializeAsync()
{
await this.ShutdownTask;
}
private async Task CreateRuntime()
{
this.Runtime = new InProcessRuntime();
foreach (AgentChatConfig config in this.GroupChat.Participants.Values)
{
await this.Runtime.RegisterChatAgentAsync(config);
}
await this.Runtime.RegisterGroupChatManagerAsync(this.GroupChat.GroupChatOptions, this.GroupChat.TeamId, this.GroupChat.CreateChatManager);
this.OutputSink = new OutputSink();
await this.Runtime.RegisterOutputCollectorAsync(this.OutputSink, this.GroupChat.GroupChatOptions.OutputTopicType);
}
public bool HasRunOnce => this.InitOnceTask != null;
public async ValueTask InitializeAsync()
{
if (this.InitOnceTask == null)
{
this.InitOnceTask = this.CreateRuntime();
}
await this.InitOnceTask;
await this.Runtime!.StartAsync();
}
}
private IRunContextLayer[] InitializationLayersInternal =>
[
this.runtimeLayer, ..this.InitializationLayers
];
protected virtual IEnumerable<IRunContextLayer> InitializationLayers => [];
private RunManager RunManager { get; }
public IAsyncEnumerable<TaskFrame> StreamAsync(string task, CancellationToken cancellationToken)
{
if (String.IsNullOrEmpty(task))
{
throw new ArgumentNullException(nameof(task));
}
// TODO: Send this on
TextMessage taskStart = new()
{
Content = task,
Source = "user"
};
return this.StreamAsync(taskStart, cancellationToken);
}
private InProcessRuntime? Runtime => this.runtimeLayer.Runtime;
private OutputSink? OutputSink => this.runtimeLayer.OutputSink;
private Task ShutdownTask
{
get => this.runtimeLayer.ShutdownTask;
set => this.runtimeLayer.ShutdownTask = value;
}
private Func<CancellationToken, ValueTask> PrepareStream(ChatMessage task)
{
GroupChatStart taskMessage = new GroupChatStart
{
Messages = [task]
};
return async (CancellationToken cancellationToken) =>
{
AgentId chatManagerId = new AgentId(GroupChatManagerTopicType, this.TeamId);
await this.Runtime!.SendMessageAsync(taskMessage, chatManagerId, cancellationToken: cancellationToken);
this.ShutdownTask = Task.Run(this.Runtime!.RunUntilIdleAsync);
};
}
private async IAsyncEnumerable<TaskFrame> StreamOutput([EnumeratorCancellation] CancellationToken cancellationToken)
{
List<AgentMessage> runMessages = new();
while (true)
{
OutputSink.SinkFrame frame = await this.OutputSink!.WaitForDataAsync(cancellationToken);
runMessages.AddRange(frame.Messages);
foreach (AgentMessage message in frame.Messages)
{
yield return new TaskFrame(message);
}
if (frame.IsTerminal)
{
TaskResult result = new TaskResult(runMessages);
yield return new TaskFrame(result);
break;
}
}
}
public IAsyncEnumerable<TaskFrame> StreamAsync(ChatMessage? task, CancellationToken cancellationToken = default)
{
if (task == null)
{
throw new ArgumentNullException(nameof(task));
}
const string TaskAlreadyRunning = "The task is already running";
return this.RunManager.StreamAsync(
this.StreamOutput,
cancellationToken,
this.PrepareStream(task),
TaskAlreadyRunning);
}
private async ValueTask ResetInternalAsync(CancellationToken cancel)
{
try
{
foreach (var participant in this.Participants.Values)
{
await this.Runtime!.SendMessageAsync(
new GroupChatReset(),
new AgentId(participant.ParticipantTopicType, this.TeamId),
cancellationToken: cancel);
}
await this.Runtime!.SendMessageAsync(
new GroupChatReset(),
new AgentId(GroupChatManagerTopicType, this.TeamId),
cancellationToken: cancel);
await this.Runtime!.RunUntilIdleAsync();
}
finally
{
this.OutputSink?.Reset();
}
}
public ValueTask ResetAsync(CancellationToken cancel)
{
const string TaskAlreadyRunning = "The group chat is currently running. It must be stopped before it can be reset.";
return this.RunManager.RunAsync(
this.ResetInternalAsync,
cancel,
message: TaskAlreadyRunning);
}
public ValueTask<JsonElement> SaveStateAsync()
{
if (!this.runtimeLayer.HasRunOnce)
{
throw new InvalidOperationException("The group chat has not been initialized. It must be run before it can be saved.");
}
const string TaskAlreadyRunning = "The team cannot be saved while it is running.";
return this.RunManager.RunAsync(
SaveStateInternalAsync,
CancellationToken.None, // TODO: Change this API?
message: TaskAlreadyRunning);
async ValueTask<JsonElement> SaveStateInternalAsync(CancellationToken _)
{
TeamState teamState = new()
{
TeamId = this.TeamId,
RuntimeState = await this.Runtime!.SaveStateAsync(),
};
JsonElement result = SerializedState.Create(teamState).AsJson();
await this.Runtime!.StopAsync();
return result;
}
}
public ValueTask LoadStateAsync(JsonElement state)
{
const string TaskAlreadyRunning = "The team cannot be loaded while it is running.";
return this.RunManager.RunAsync(
LoadStateInternalAsync,
CancellationToken.None, // TODO: Change this API?
message: TaskAlreadyRunning);
async ValueTask LoadStateInternalAsync(CancellationToken _)
{
TeamState parsedState = new SerializedState(state).As<TeamState>();
this.TeamId = parsedState.TeamId;
await this.Runtime!.LoadStateAsync(parsedState.RuntimeState.AsJson());
await this.Runtime!.StopAsync();
}
}
}

View File

@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// GroupChatHandlerRouter.cs
using System.Text.Json;
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
internal delegate ValueTask MessagePublishServicer(GroupChatEventBase event_, string topicType, CancellationToken cancellation = default);
internal interface IGroupChatHandler : IHandle<GroupChatStart>, IHandle<GroupChatAgentResponse>, IHandle<object>, ISaveState
{
public void AttachMessagePublishServicer(MessagePublishServicer? servicer = null);
public void DetachMessagePublishServicer() => this.AttachMessagePublishServicer(null);
}
internal sealed class GroupChatHandlerRouter<TManager> : HostableAgentAdapter,
IHandle<GroupChatStart>,
IHandle<GroupChatAgentResponse>,
IHandle<object>,
ISaveState
where TManager : GroupChatManagerBase, IGroupChatHandler
{
public const string DefaultDescription = "Group chat manager";
private TManager ChatManager { get; }
public GroupChatHandlerRouter(AgentInstantiationContext agentCtx, TManager chatManager, ILogger<BaseAgent>? logger = null) : base(agentCtx, DefaultDescription, logger)
{
this.ChatManager = chatManager;
this.ChatManager.AttachMessagePublishServicer(PublishMessageServicer);
}
private ValueTask PublishMessageServicer(GroupChatEventBase event_, string topicType, CancellationToken cancellation = default)
{
return this.PublishMessageAsync(event_, new TopicId(topicType, this.Id.Key), cancellationToken: cancellation);
}
public ValueTask HandleAsync(GroupChatStart item, MessageContext messageContext)
=> this.ChatManager.HandleAsync(item, messageContext);
public ValueTask HandleAsync(GroupChatAgentResponse item, MessageContext messageContext)
=> this.ChatManager.HandleAsync(item, messageContext);
public ValueTask HandleAsync(object item, MessageContext messageContext)
=> this.ChatManager.HandleAsync(item, messageContext);
ValueTask<JsonElement> ISaveState.SaveStateAsync()
=> this.ChatManager.SaveStateAsync();
ValueTask ISaveState.LoadStateAsync(JsonElement state)
=> this.ChatManager.LoadStateAsync(state);
}

View File

@ -0,0 +1,187 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// GroupChatManagerBase.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
using Microsoft.AutoGen.Contracts;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
public abstract class GroupChatManagerBase : IGroupChatHandler
{
private GroupChatOptions options;
// TODO: We may be able to abstract this out at the Core level
private MessagePublishServicer? PublishServicer { get; set; }
// It would be so awesome if we could avoid passing GroupChatOptions to the constructor
// and use something like Python's context manager mechanism to pick up the options from
// the logical stack. But that's very difficult in C#, because the user code could do all
// sorts of weird things like shunt the execution to a different thread. We cannot even
// assume that we are in an async context (much less that we are in the same async context)
public GroupChatManagerBase(GroupChatOptions options) : base()
{
this.options = options;
this.MessageThread = new List<AgentMessage>();
}
protected string GroupChatTopicType => this.options.GroupChatTopicType;
protected string OutputTopicType => this.options.OutputTopicType;
protected Dictionary<string, GroupParticipant> Participants => this.options.Participants;
protected ITerminationCondition? TerminationCondition => this.options.TerminationCondition;
protected int? MaxTurns => this.options.MaxTurns;
protected int CurrentTurn { get; set; }
protected List<AgentMessage> MessageThread;
void IGroupChatHandler.AttachMessagePublishServicer(MessagePublishServicer? servicer)
{
this.PublishServicer = servicer;
}
private ValueTask PublishMessageAsync(GroupChatEventBase message, string topicType, CancellationToken cancellation = default)
{
return this.PublishServicer?.Invoke(message, topicType, cancellation) ?? ValueTask.CompletedTask;
}
protected ValueTask PublishMessageAsync(ChatMessage message, string topicType, CancellationToken cancellation = default)
{
return this.PublishMessageAsync(new GroupChatMessage { Message = message }, topicType, cancellation);
}
protected virtual async ValueTask ValidateGroupState(List<ChatMessage>? messages)
{
}
public abstract ValueTask<string> SelectSpeakerAsync(List<AgentMessage> thread);
public async ValueTask HandleAsync(GroupChatStart item, MessageContext messageContext)
{
if (this.TerminationCondition != null && this.TerminationCondition.IsTerminated)
{
// skipReset is used here to match the Python code
await this.TerminateAsync("The chat has already terminated", skipReset: true);
StopMessage earlyStop = new StopMessage
{
Content = "The chat has already terminated",
Source = GroupChatBase<GroupChatManagerBase>.GroupChatManagerTopicType
};
await this.PublishMessageAsync(new GroupChatTermination { Message = earlyStop }, this.OutputTopicType);
return;
}
if (item.Messages != null)
{
this.MessageThread.AddRange(item.Messages);
}
await this.ValidateGroupState(item.Messages);
if (item.Messages != null)
{
await this.PublishMessageAsync(item, this.OutputTopicType);
await this.PublishMessageAsync(item, this.GroupChatTopicType);
// item.Messages is IList<ChatMessage> but we need IList<AgentMessage>
// Unfortunately, IList does not support type variance, so we have to do this rather ugly thing
// TODO: Check if we really need to have AgentMessage on the interface of ITerminationCondition
List<AgentMessage> converted = [.. item.Messages.Cast<AgentMessage>()];
if (await this.TerminateIfNeededAsync(converted))
{
return;
}
}
await this.ProcessNextSpeakerAsync();
}
public async ValueTask HandleAsync(GroupChatAgentResponse item, MessageContext messageContext)
{
List<AgentMessage> delta = new List<AgentMessage>();
if (item.AgentResponse.InnerMessages != null)
{
this.MessageThread.AddRange(item.AgentResponse.InnerMessages);
delta.AddRange(item.AgentResponse.InnerMessages);
}
this.MessageThread.Add(item.AgentResponse.Message);
delta.Add(item.AgentResponse.Message);
if (await this.TerminateIfNeededAsync(delta))
{
return;
}
this.CurrentTurn++;
if (this.MaxTurns.HasValue && this.MaxTurns.Value <= this.CurrentTurn)
{
await this.TerminateAsync($"Maximum number of turns ({this.MaxTurns.Value}) reached.");
return;
}
await this.ProcessNextSpeakerAsync();
}
private ValueTask TerminateAsync(string message, bool skipReset = false)
{
StopMessage stopMessage = new StopMessage
{
Content = message,
Source = GroupChatBase<GroupChatManagerBase>.GroupChatManagerTopicType
};
return this.TerminateAsync(stopMessage, skipReset);
}
private async ValueTask TerminateAsync(StopMessage stopMessage, bool skipReset = false)
{
await this.PublishMessageAsync(new GroupChatTermination { Message = stopMessage }, this.OutputTopicType);
if (!skipReset)
{
this.TerminationCondition?.Reset();
this.CurrentTurn = 0;
}
}
private async ValueTask<bool> TerminateIfNeededAsync(params IList<AgentMessage> incomingMessages)
{
if (this.TerminationCondition == null)
{
return false;
}
StopMessage? stopMessage = await this.TerminationCondition.CheckAndUpdateAsync(incomingMessages);
if (stopMessage != null)
{
await this.TerminateAsync(stopMessage);
return true;
}
return false;
}
// TODO: Figure out how to route this to the right method
//private ValueTask ProcessNextSpeakerAsync(params IList<AgentMessage> incomingMessages)
// => this.ProcessNextSpeakerAsync(incomingMessages);
private async ValueTask ProcessNextSpeakerAsync()
{
string nextSpeakerTopic = await this.SelectSpeakerAsync(this.MessageThread);
await this.PublishMessageAsync(new GroupChatRequestPublish { }, nextSpeakerTopic);
}
public ValueTask HandleAsync(object item, MessageContext messageContext)
{
throw new NotImplementedException();
}
}

View File

@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// GroupChatOptions.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
public struct GroupParticipant(string topicType, string description)
{
public string TopicType { get; } = topicType;
public string Description { get; } = description;
// Destructuring from a tuple
public GroupParticipant((string topicType, string description) tuple) : this(tuple.topicType, tuple.description)
{
}
// Destructuring to a tuple
public void Deconstruct(out string topicType, out string description)
{
topicType = this.TopicType;
description = this.Description;
}
public static implicit operator GroupParticipant((string topicType, string description) tuple) => new GroupParticipant(tuple);
public static implicit operator (string topicType, string description)(GroupParticipant participant) => (participant.TopicType, participant.Description);
}
public class GroupChatOptions(string groupTopicType, string outputTopicType)
{
public string GroupChatTopicType { get; } = groupTopicType;
public string OutputTopicType { get; } = outputTopicType;
public ITerminationCondition? TerminationCondition { get; set; }
public int? MaxTurns { get; set; }
public Dictionary<string, GroupParticipant> Participants { get; } = new Dictionary<string, GroupParticipant>();
}

View File

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// HostableAgentAdapter.cs
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
public class AgentInstantiationContext(AgentId id, IAgentRuntime runtime)
{
public AgentId Id { get; } = id;
public IAgentRuntime Runtime { get; } = runtime;
}
internal class HostableAgentAdapter : BaseAgent
{
public HostableAgentAdapter(AgentId id, IAgentRuntime runtime, string description, ILogger<BaseAgent>? logger = null) : base(id, runtime, description, logger)
{
}
public HostableAgentAdapter(AgentInstantiationContext agentCtx, string description, ILogger<BaseAgent>? logger = null) : base(agentCtx.Id, agentCtx.Runtime, description, logger)
{
}
}

View File

@ -0,0 +1,146 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// OutputCollectorAgent.cs
using System.Diagnostics;
using Microsoft.AutoGen.AgentChat.GroupChat;
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.AgentChat.Abstractions;
internal interface IOutputCollectionSink
{
public void CollectMessage(AgentMessage message);
public void Terminate(StopMessage message);
}
internal sealed class OutputSink : IOutputCollectionSink
{
public sealed class SinkFrame
{
public StopMessage? Termination { get; set; }
public List<AgentMessage> Messages { get; } = new();
public bool IsTerminal => this.Termination != null;
}
private readonly object sync = new();
private SemaphoreSlim semapohre = new SemaphoreSlim(0, 1);
private SinkFrame? receivingSinkFrame;
private void RunSynchronized(Action<SinkFrame> frameAction)
{
// Make sure we do not overlap with Terminate
lock (this.sync)
{
if (this.receivingSinkFrame == null)
{
this.receivingSinkFrame = new SinkFrame();
}
frameAction(this.receivingSinkFrame);
}
// TODO: Replace the Semaphore with a TaskSource approach
try
{
semapohre.Release();
}
catch (SemaphoreFullException) { }
}
public void CollectMessage(AgentMessage message)
{
this.RunSynchronized(
frame =>
{
frame.Messages.Add(message);
});
}
public void Terminate(StopMessage message)
{
this.RunSynchronized(
frame =>
{
frame.Termination = message;
});
}
public async Task<SinkFrame> WaitForDataAsync(CancellationToken cancellation)
{
while (true)
{
SinkFrame? lastFrame;
lock (this.sync)
{
lastFrame = Interlocked.Exchange(ref this.receivingSinkFrame, null);
if (lastFrame != null)
{
return lastFrame;
}
}
await this.semapohre.WaitAsync(cancellation);
}
}
internal void Reset()
{
lock (this.sync)
{
this.receivingSinkFrame = null;
}
}
}
// TODO: Abstract the core logic of this out into the equivalent of ClosureAgent, because that seems like a
// useful facility to have in Core
internal sealed class OutputCollectorAgent : BaseAgent,
IHandle<GroupChatStart>,
IHandle<GroupChatMessage>,
IHandle<GroupChatTermination>
{
private IOutputCollectionSink Sink { get; }
public OutputCollectorAgent(AgentInstantiationContext ctx, IOutputCollectionSink sink, ILogger<OutputCollectorAgent>? logger = null) : base(ctx.Id, ctx.Runtime, string.Empty, logger)
{
this.Sink = sink;
}
private void ForwardMessageInternal(ChatMessage message, CancellationToken cancel = default)
{
if (!cancel.IsCancellationRequested)
{
this.Sink.CollectMessage(message);
}
}
public ValueTask HandleAsync(GroupChatStart item, MessageContext context)
{
item.Messages?.ForEach(item => this.ForwardMessageInternal(item, context.CancellationToken));
return ValueTask.CompletedTask;
}
public ValueTask HandleAsync(GroupChatMessage item, MessageContext context)
{
Debug.Assert(item.Message is ChatMessage, "We should never receive internal messages into the output queue?");
if (item.Message is ChatMessage chatMessage)
{
this.ForwardMessageInternal(chatMessage, context.CancellationToken);
}
return ValueTask.CompletedTask;
}
public ValueTask HandleAsync(GroupChatTermination item, MessageContext context)
{
this.Sink.Terminate(item.Message);
return ValueTask.CompletedTask;
}
}

View File

@ -0,0 +1,83 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// RoundRobinGroupChat.cs
using System.Text.Json;
using Microsoft.AutoGen.AgentChat.Abstractions;
using Microsoft.AutoGen.AgentChat.State;
using Microsoft.AutoGen.Contracts;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
/// <summary>
/// A group chat manager that selects the next speaker in a round-robin fashion.
/// </summary>
public class RoundRobinGroupChatManager : GroupChatManagerBase, ISaveState
{
private readonly List<string> participantTopicTypes;
private int nextSpeakerIndex;
public RoundRobinGroupChatManager(GroupChatOptions options) : base(options)
{
this.participantTopicTypes = [.. from candidateTopic in options.Participants.Values
select candidateTopic.TopicType];
this.nextSpeakerIndex = 0;
}
public override ValueTask<string> SelectSpeakerAsync(List<AgentMessage> thread)
{
string result = this.participantTopicTypes[this.nextSpeakerIndex].ToString();
this.nextSpeakerIndex = (this.nextSpeakerIndex + 1) % this.participantTopicTypes.Count;
return ValueTask.FromResult(result);
}
ValueTask<JsonElement> ISaveState.SaveStateAsync()
{
RoundRobinManagerState state = new RoundRobinManagerState
{
NextSpeakerIndex = this.nextSpeakerIndex,
CurrentTurn = this.CurrentTurn,
MessageThread = this.MessageThread
};
return ValueTask.FromResult(SerializedState.Create(state).AsJson());
}
ValueTask ISaveState.LoadStateAsync(JsonElement state)
{
RoundRobinManagerState parsedState = new SerializedState(state).As<RoundRobinManagerState>();
this.MessageThread = parsedState.MessageThread;
this.CurrentTurn = parsedState.CurrentTurn;
this.nextSpeakerIndex = parsedState.NextSpeakerIndex;
return ValueTask.CompletedTask;
}
}
/// <summary>
/// A team that runs a group chat with a participants taking turns in a round-robin fashion to publish
/// a message to all.
///
/// If a single participant is in the team, the participant will be the only speaker.
/// </summary>
public class RoundRobinGroupChat : GroupChatBase<RoundRobinGroupChatManager>
{
/// <summary>
/// Initializes a new round-robin group chat.
/// </summary>
/// <param name="participants">The participants in the group chat.</param>
/// <param name="terminationCondition">
/// The termination condition for the group chat. Defaults to <c>null</c>. Without a termination
/// condition, the group chat will run indefinitely.
/// </param>
/// <param name="maxTurns">
/// The maximum number of turns for the group chat. Defaults to <c>null</c>, meaning no limit.
/// Note that the <see cref="ITerminationCondition"/> gets first priority for checking the termination
/// if both are provided.
/// </param>
public RoundRobinGroupChat(List<IChatAgent> participants, ITerminationCondition? terminationCondition = null, int? maxTurns = null) : base(participants, terminationCondition, maxTurns)
{
}
}

View File

@ -0,0 +1,297 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// RunContext.cs
using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Microsoft.AutoGen.AgentChat.GroupChat;
public abstract class LifecycleObject
{
private int initialized;
private void PrepareInitialize(Action errorAction)
{
if (Interlocked.CompareExchange(ref this.initialized, 1, 0) != 0)
{
errorAction();
}
}
private void PrepareDeinitialize(Action errorAction)
{
if (Interlocked.CompareExchange(ref this.initialized, 0, 1) != 1)
{
errorAction();
}
}
protected bool IsInitialized => Volatile.Read(ref this.initialized) == 1;
protected virtual void OnInitializeError() => throw new InvalidOperationException($"Error initializing: {this.GetType().FullName}; already initialized.");
protected virtual void OnDeinitializeError() => throw new InvalidOperationException($"Error deinitializing: {this.GetType().FullName}; not initialized.");
public ValueTask InitializeAsync()
{
this.PrepareInitialize(this.OnInitializeError);
return this.InitializeCore();
}
public ValueTask DeinitializeAsync()
{
this.PrepareDeinitialize(this.OnDeinitializeError);
return this.DeinitializeCore();
}
protected abstract ValueTask InitializeCore();
protected abstract ValueTask DeinitializeCore();
}
public interface IRunContextLayer
{
public ValueTask InitializeAsync();
public ValueTask DeinitializeAsync();
}
public sealed class RunContextStack : LifecycleObject, IRunContextLayer
{
private Stack<IRunContextLayer> Uninitialized { get; } = new();
private Stack<IRunContextLayer> Initialized { get; } = new();
public RunContextStack(params IEnumerable<IRunContextLayer> contextLayers)
{
this.Uninitialized = new Stack<IRunContextLayer>(contextLayers);
}
// TODO: There is probably a way to have a sound manner by which pushing/popping a layer when initialized
// would be allowed. But this is not necessary for now, so we will keep it simple.
public void PushLayer(IRunContextLayer layer)
{
if (this.IsInitialized)
{
throw new InvalidOperationException("Cannot push a layer while the context is initialized.");
}
this.Uninitialized.Push(layer);
}
public void PopLayer()
{
if (this.IsInitialized)
{
throw new InvalidOperationException("Cannot pop a layer while the context is initialized.");
}
}
private Action? initializeError;
protected override void OnInitializeError()
{
(this.initializeError ?? base.OnInitializeError)();
}
private Action? deinitializeError;
protected override void OnDeinitializeError()
{
(this.deinitializeError ?? base.OnDeinitializeError)();
}
public static IRunContextLayer OverrideErrors(Action? initializeError = null, Action? deinitializeError = null)
{
return new ErrorOverrideLayer(initializeError, deinitializeError);
}
private sealed class ErrorOverrideLayer(Action? initializeError = null, Action? deinitializeError = null)
: IRunContextLayer
{
public RunContextStack? Target { get; set; }
private Action? initializeErrorPrev;
private Action? deinitializeErrorPrev;
public ValueTask InitializeAsync()
{
if (initializeError != null)
{
this.initializeErrorPrev = Interlocked.CompareExchange(ref this.Target!.initializeError, initializeError, null);
}
if (deinitializeError != null)
{
this.deinitializeErrorPrev = Interlocked.CompareExchange(ref this.Target!.deinitializeError, deinitializeError, null);
}
return ValueTask.CompletedTask;
}
public ValueTask DeinitializeAsync()
{
if (this.initializeErrorPrev != null)
{
Interlocked.CompareExchange(ref this.Target!.initializeError, this.initializeErrorPrev, initializeError);
}
if (this.deinitializeErrorPrev != null)
{
Interlocked.CompareExchange(ref this.Target!.deinitializeError, this.deinitializeErrorPrev, deinitializeError);
}
return ValueTask.CompletedTask;
}
}
public ValueTask<IAsyncDisposable> Enter()
{
return RunTicket.Enter(this);
}
protected override async ValueTask InitializeCore()
{
while (this.Uninitialized.Count > 0)
{
IRunContextLayer layer = this.Uninitialized.Pop();
if (layer is ErrorOverrideLayer errorOverrideLayer)
{
errorOverrideLayer.Target = this;
}
await layer.InitializeAsync();
this.Initialized.Push(layer);
}
}
protected override async ValueTask DeinitializeCore()
{
while (this.Initialized.Count > 0)
{
IRunContextLayer layer = this.Initialized.Pop();
await layer.DeinitializeAsync();
this.Uninitialized.Push(layer);
}
}
private sealed class RunTicket : IAsyncDisposable
{
private RunContextStack contextStack;
private int disposed;
private RunTicket(RunContextStack contextStack)
{
Debug.Assert(contextStack.IsInitialized, "The context stack must be initialized.");
this.contextStack = contextStack;
}
public static async ValueTask<IAsyncDisposable> Enter(RunContextStack contextStack)
{
await contextStack.InitializeAsync();
return new RunTicket(contextStack);
}
public ValueTask DisposeAsync()
{
if (Interlocked.CompareExchange(ref this.disposed, 1, 0) == 0)
{
return this.contextStack.DeinitializeAsync();
}
return ValueTask.CompletedTask;
}
}
}
public sealed class RunManager
{
private RunContextStack runContextStack;
public RunManager(params IEnumerable<IRunContextLayer> contextLayers)
{
this.runContextStack = new RunContextStack(contextLayers);
}
private ValueTask<IAsyncDisposable> PrepareRunAsync(string? message = null)
{
if (message != null)
{
IRunContextLayer errorOverride = RunContextStack.OverrideErrors(() => throw new InvalidOperationException(message));
this.runContextStack.PushLayer(errorOverride);
}
return this.runContextStack.Enter();
}
private async ValueTask EndRunAsync(IAsyncDisposable? runDisposable, bool hadMessage)
{
if (runDisposable != null)
{
await runDisposable.DisposeAsync().ConfigureAwait(false);
}
if (hadMessage)
{
this.runContextStack.PopLayer();
}
}
public async ValueTask RunAsync(Func<CancellationToken, ValueTask> asyncAction, CancellationToken cancellation = default, Func<CancellationToken, ValueTask>? prepareAction = null, string? message = null)
{
IAsyncDisposable? runDisposable = null;
try
{
runDisposable = await this.PrepareRunAsync(message).ConfigureAwait(false);
if (prepareAction != null)
{
await prepareAction(cancellation).ConfigureAwait(false);
}
await asyncAction(cancellation).ConfigureAwait(false);
}
finally
{
await this.EndRunAsync(runDisposable, message != null).ConfigureAwait(false);
}
}
public async ValueTask<T> RunAsync<T>(Func<CancellationToken, ValueTask<T>> asyncAction, CancellationToken cancellation = default, Func<CancellationToken, ValueTask>? prepareAction = null, string? message = null)
{
IAsyncDisposable? runDisposable = null;
try
{
runDisposable = await this.PrepareRunAsync(message).ConfigureAwait(false);
if (prepareAction != null)
{
await prepareAction(cancellation).ConfigureAwait(false);
}
return await asyncAction(cancellation).ConfigureAwait(false);
}
finally
{
await this.EndRunAsync(runDisposable, message != null).ConfigureAwait(false);
}
}
public async IAsyncEnumerable<TItem> StreamAsync<TItem>(Func<CancellationToken, IAsyncEnumerable<TItem>> streamAction, [EnumeratorCancellation] CancellationToken cancellation = default, Func<CancellationToken, ValueTask>? prepareAction = null, string? message = null)
{
IAsyncDisposable? runDisposable = null;
try
{
runDisposable = await this.PrepareRunAsync(message).ConfigureAwait(false);
if (prepareAction != null)
{
await prepareAction(cancellation).ConfigureAwait(false);
}
await foreach (TItem item in streamAction(cancellation))
{
yield return item;
}
}
finally
{
await this.EndRunAsync(runDisposable, message != null).ConfigureAwait(false);
}
}
}

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<Import Project="$(RepoRoot)/nuget/nuget-package.props" />
<ItemGroup>
<ProjectReference Include="..\Contracts\Microsoft.AutoGen.Contracts.csproj" />
<ProjectReference Include="..\Core\Microsoft.AutoGen.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.AI" />
<PackageReference Include="Microsoft.Extensions.Hosting" />
<PackageReference Include="Microsoft.Extensions.Logging" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// BaseState.cs
namespace Microsoft.AutoGen.AgentChat.State;
[AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class StateSerializableAttribute : Attribute
{
public StateSerializableAttribute()
{
}
}
[StateSerializable]
public abstract class BaseState
{
public string Type => this.GetType().FullName!;
public string Version { get; set; } = "1.0.0"; // TODO: More rigorous state versioning?
}

View File

@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ChatAgentContainerState.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.State;
public class ChatAgentContainerState : BaseState
{
public required SerializedState AgentState { get; set; }
public List<ChatMessage> MessageBuffer { get; set; } = new();
}
public class GroupChatManagerStateBase : BaseState
{
public List<AgentMessage> MessageThread { get; set; } = new();
public int CurrentTurn { get; set; }
}
public class RoundRobinManagerState : GroupChatManagerStateBase
{
public int NextSpeakerIndex { get; set; }
}

View File

@ -0,0 +1,100 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SerializedState.cs
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.State;
public class SerializedStateConverter : JsonConverter<SerializedState>
{
public override SerializedState Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var json = JsonDocument.ParseValue(ref reader).RootElement;
var state = new SerializedState(json);
return state;
}
public override void Write(Utf8JsonWriter writer, SerializedState value, JsonSerializerOptions options)
{
value.AsJson().WriteTo(writer);
}
}
[JsonConverter(typeof(SerializedStateConverter))]
public class SerializedState
{
private readonly JsonSerializerOptions SerializerOptions = new()
{
Converters =
{
new SerializedStateConverter(),
},
TypeInfoResolver = new MessageSerializationHelpers.MessagesTypeInfoResolver(),
};
public JsonElement AsJson()
{
if (this.jsonValue != null)
{
return this.jsonValue.Value;
}
if (this.deserializedValue == null)
{
throw new InvalidOperationException("State is not initialized.");
}
this.jsonValue = JsonSerializer.SerializeToElement(this.deserializedValue, SerializerOptions);
return this.jsonValue.Value;
}
public static SerializedState Create<T>(T state) where T : notnull
{
return new SerializedState((object)state);
}
public T As<T>()
{
if (this.deserializedValue is T value)
{
return value;
}
if (this.deserializedValue != null)
{
throw new InvalidOperationException($"Cannot convert state of type {this.deserializedValue.GetType()} to {typeof(T)}.");
}
if (this.jsonValue == null)
{
throw new InvalidOperationException("State is not initialized.");
}
T? result = JsonSerializer.Deserialize<T>(this.jsonValue!.Value, SerializerOptions)
?? throw new InvalidOperationException($"Cannot deserialize state to {typeof(T)}.");
this.deserializedValue = result;
return result;
}
private object? deserializedValue;
private JsonElement? jsonValue;
private SerializedState(object state)
{
this.deserializedValue = state;
}
public SerializedState(JsonElement json)
{
this.jsonValue = json;
}
public static implicit operator SerializedState(JsonElement json)
{
return new SerializedState(json);
}
}

View File

@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// TeamState.cs
namespace Microsoft.AutoGen.AgentChat.State;
public sealed class TeamState : BaseState
{
public required string TeamId { get; set; }
public required SerializedState RuntimeState { get; set; }
}

View File

@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// ExternalTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// A <see cref="ITerminationCondition"/> that is externally controlled by calling the <see cref="Set"/> method.
/// </summary>
public sealed class ExternalTermination : ITerminationCondition
{
public ExternalTermination()
{
this.TerminationQueued = false;
this.IsTerminated = false;
}
public bool TerminationQueued { get; private set; }
public bool IsTerminated { get; private set; }
/// <summary>
/// Set the termination condition to terminated.
/// </summary>
public void Set()
{
this.TerminationQueued = true;
}
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
if (this.TerminationQueued)
{
this.IsTerminated = true;
string message = "External termination requested.";
StopMessage result = new() { Content = message, Source = nameof(ExternalTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.TerminationQueued = false;
this.IsTerminated = false;
}
}

View File

@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// FunctionCallTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate the conversation if a <see cref="ToolCallExecutionEvent"/> with a specific name is received.
/// </summary>
public sealed class FunctionCallTermination : ITerminationCondition
{
/// <summary>
/// Initializes a new instance of the <see cref="FunctionCallTermination"/> class.
/// </summary>
/// <param name="functionName">The name of the function to look for in the messages.</param>
public FunctionCallTermination(string functionName)
{
this.FunctionName = functionName;
this.IsTerminated = false;
}
public string FunctionName { get; }
public bool IsTerminated { get; private set; }
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
foreach (AgentMessage item in messages)
{
if (item is ToolCallExecutionEvent toolCallEvent && toolCallEvent.Content.Any(execution => execution.Name == this.FunctionName))
{
this.IsTerminated = true;
string message = $"Function '{this.FunctionName}' was executed.";
StopMessage result = new() { Content = message, Source = nameof(FunctionCallTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.IsTerminated = false;
}
}

View File

@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// HandoffTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate the conversation if a <see cref="HandoffMessage"/> with the given <see cref="HandoffMessage.Target"/>
/// is received.
/// </summary>
public sealed class HandoffTermination : ITerminationCondition
{
/// <summary>
/// Initializes a new instance of the <see cref="HandoffTermination"/> class.
/// </summary>
/// <param name="target">The target of the handoff message.</param>
public HandoffTermination(string target)
{
this.Target = target;
this.IsTerminated = false;
}
public string Target { get; }
public bool IsTerminated { get; private set; }
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
foreach (AgentMessage item in messages)
{
if (item is HandoffMessage handoffMessage && handoffMessage.Target == this.Target)
{
this.IsTerminated = true;
string message = $"Handoff to {handoffMessage.Target} from {handoffMessage.Source} detected.";
StopMessage result = new() { Content = message, Source = nameof(HandoffTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.IsTerminated = false;
}
}

View File

@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// MaxMessageTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate the conversation after a maximum number of messages have been exchanged.
/// </summary>
public sealed class MaxMessageTermination : ITerminationCondition
{
/// <summary>
/// Initializes a new instance of the <see cref="MaxMessageTermination"/> class.
/// </summary>
/// <param name="maxMessages">The maximum number of messages allowed in the conversation.</param>
public MaxMessageTermination(int maxMessages, bool includeAgentEvent = false)
{
this.MaxMessages = maxMessages;
this.MessageCount = 0;
this.IncludeAgentEvent = includeAgentEvent;
}
public int MaxMessages { get; }
public int MessageCount { get; private set; }
public bool IncludeAgentEvent { get; }
public bool IsTerminated => this.MessageCount >= this.MaxMessages;
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
this.MessageCount += messages.Where(m => this.IncludeAgentEvent || m is not AgentEvent).Count();
if (this.IsTerminated)
{
StopMessage result = new() { Content = "Max message count reached", Source = nameof(MaxMessageTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.MessageCount = 0;
}
}

View File

@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SourceMatchTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate the conversation after a specific source responds.
/// </summary>
public sealed class SourceMatchTermination : ITerminationCondition
{
/// <summary>
/// Initializes a new instance of the <see cref="SourceMatchTermination"/> class.
/// </summary>
/// <param name="sources">List of source names to terminate the conversation.</param>
public SourceMatchTermination(params IEnumerable<string> sources)
{
this.Sources = [.. sources];
}
public HashSet<string> Sources { get; }
public bool IsTerminated { get; private set; }
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
foreach (AgentMessage item in messages)
{
if (this.Sources.Contains(item.Source))
{
this.IsTerminated = true;
string message = $"'{item.Source}' answered.";
StopMessage result = new() { Content = message, Source = nameof(SourceMatchTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.IsTerminated = false;
}
}

View File

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// StopMessageTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate a conversation if a <see cref="StopMessage"/> is received.
/// </summary>
public class StopMessageTermination : ITerminationCondition
{
public bool IsTerminated { get; private set; }
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
foreach (AgentMessage item in messages)
{
if (item is StopMessage)
{
this.IsTerminated = true;
StopMessage result = new() { Content = "Stop message received", Source = nameof(StopMessageTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.IsTerminated = false;
}
}

View File

@ -0,0 +1,76 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// TextMentionTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
using Microsoft.Extensions.AI;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate the conversation if a specific text is mentioned.
/// </summary>
public sealed class TextMentionTermination : ITerminationCondition
{
/// <summary>
/// Initializes a new instance of the <see cref="TextMentionTermination"/> class.
/// </summary>
/// <param name="targetText">The text to look for in the messages.</param>
/// <param name="sources">Check only the messages of the specified agents for the text to look for.</param>
public TextMentionTermination(string targetText, IEnumerable<string>? sources = null)
{
this.TargetText = targetText;
this.Sources = sources != null ? [.. sources] : null;
this.IsTerminated = false;
}
public string TargetText { get; }
public HashSet<string>? Sources { get; }
public bool IsTerminated { get; private set; }
private bool CheckMultiModalData(MultiModalData data)
{
return data.ContentType == MultiModalData.Type.String &&
((TextContent)data.AIContent).Text.Contains(this.TargetText);
}
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
foreach (AgentMessage item in messages)
{
if (this.Sources != null && !this.Sources.Contains(item.Source))
{
continue;
}
bool hasMentions = item switch
{
TextMessage textMessage => textMessage.Content.Contains(this.TargetText),
MultiModalMessage multiModalMessage => multiModalMessage.Content.Any(CheckMultiModalData),
StopMessage stopMessage => stopMessage.Content.Contains(this.TargetText),
ToolCallSummaryMessage toolCallSummaryMessage => toolCallSummaryMessage.Content.Contains(this.TargetText),
_ => false
};
if (hasMentions)
{
this.IsTerminated = true;
StopMessage result = new() { Content = "Text mention received", Source = nameof(TextMentionTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.IsTerminated = false;
}
}

View File

@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// TextMessageTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate the conversation if a <see cref="TextMessage"/> is received.
///
/// This termination condition checks for TextMessage instances in the message sequence. When a TextMessage is found,
/// it terminates the conversation if either:
///
/// <list type="bullet">
/// <item>No source was specified (terminates on any <see cref="TextMessage"/>)</item>
/// <item>The message source matches the specified source</item>
/// </list>
///
/// </summary>
public sealed class TextMessageTermination : ITerminationCondition
{
/// <summary>
/// Initializes a new instance of the <see cref="TextMessageTermination"/> class.
/// </summary>
/// <param name="source">
/// The source name to match against incoming messages. If <c>null</c>, matches any source.
/// Defaults to <c>null</c>.
/// </param>
public TextMessageTermination(string? source = null)
{
this.Source = source;
this.IsTerminated = false;
}
public string? Source { get; }
public bool IsTerminated { get; private set; }
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
foreach (AgentMessage item in messages)
{
if (item is TextMessage textMessage && (this.Source == null || textMessage.Source == this.Source))
{
this.IsTerminated = true;
string message = $"Text message received from '{textMessage.Source}'.";
StopMessage result = new() { Content = message, Source = nameof(TextMessageTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.IsTerminated = false;
}
}

View File

@ -0,0 +1,59 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// TimeoutTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate the conversation after the specified duration has passed.
/// </summary>
public sealed class TimeoutTermination : ITerminationCondition
{
/// <summary>
/// Initializes a new instance of the <see cref="TimeoutTermination"/> class.
/// </summary>
/// <param name="timeout">The maximum duration before terminating the conversation.</param>
public TimeoutTermination(TimeSpan timeout)
{
this.Timeout = timeout;
this.StartTime = DateTime.UtcNow;
}
/// <summary>
/// Initializes a new instance of the <see cref="TimeoutTermination"/> class.
/// </summary>
/// <param name="seconds">The maximum duration in seconds before terminating the conversation.</param>
public TimeoutTermination(float seconds) : this(TimeSpan.FromSeconds(seconds))
{
}
public TimeSpan Timeout { get; }
public DateTime StartTime { get; private set; }
public bool IsTerminated { get; private set; }
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
if (DateTime.UtcNow - this.StartTime >= this.Timeout)
{
this.IsTerminated = true;
string message = $"Timeout of {this.Timeout.TotalSeconds} seconds reached.";
StopMessage result = new() { Content = message, Source = nameof(TimeoutTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.IsTerminated = false;
this.StartTime = DateTime.UtcNow;
}
}

View File

@ -0,0 +1,73 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// TokenUsageTermination.cs
using Microsoft.AutoGen.AgentChat.Abstractions;
namespace Microsoft.AutoGen.AgentChat.Terminations;
/// <summary>
/// Terminate the conversation if the token usage limit is reached.
/// </summary>
public sealed class TokenUsageTermination : ITerminationCondition
{
/// <summary>
/// Initializes a new instance of the <see cref="TokenUsageTermination"/> class.
/// </summary>
/// <param name="maxTotalTokens">The maximum total number of tokens allowed in the conversation.</param>
/// <param name="maxPromptTokens">The maximum number of prompt tokens allowed in the conversation.</param>
/// <param name="maxCompletionTokens">The maximum number of completion tokens allowed in the conversation.</param>
public TokenUsageTermination(int? maxTotalTokens = null, int? maxPromptTokens = null, int? maxCompletionTokens = null)
{
this.MaxTotalTokens = maxTotalTokens;
this.MaxPromptTokens = maxPromptTokens;
this.MaxCompletionTokens = maxCompletionTokens;
this.PromptTokenCount = 0;
this.CompletionTokenCount = 0;
}
public int? MaxTotalTokens { get; }
public int? MaxPromptTokens { get; }
public int? MaxCompletionTokens { get; }
public int TotalTokenCount => this.PromptTokenCount + this.CompletionTokenCount;
public int PromptTokenCount { get; private set; }
public int CompletionTokenCount { get; private set; }
public bool IsTerminated =>
(this.MaxTotalTokens != null && this.TotalTokenCount >= this.MaxTotalTokens) ||
(this.MaxPromptTokens != null && this.PromptTokenCount >= this.MaxPromptTokens) ||
(this.MaxCompletionTokens != null && this.CompletionTokenCount >= this.MaxCompletionTokens);
public ValueTask<StopMessage?> CheckAndUpdateAsync(IList<AgentMessage> messages)
{
if (this.IsTerminated)
{
throw new TerminatedException();
}
foreach (AgentMessage item in messages)
{
if (item.ModelUsage is RequestUsage usage)
{
this.PromptTokenCount += usage.PromptTokens;
this.CompletionTokenCount += usage.CompletionTokens;
}
}
if (this.IsTerminated)
{
string message = $"Token usage limit reached, total token count: {this.TotalTokenCount}, prompt token count: {this.PromptTokenCount}, completion token count: {this.CompletionTokenCount}.";
StopMessage result = new() { Content = message, Source = nameof(TokenUsageTermination) };
return ValueTask.FromResult<StopMessage?>(result);
}
return ValueTask.FromResult<StopMessage?>(null);
}
public void Reset()
{
this.PromptTokenCount = 0;
this.CompletionTokenCount = 0;
}
}

View File

@ -0,0 +1,31 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
!**/.gitignore
!.git/HEAD
!.git/config
!.git/packed-refs
!.git/refs/heads/**
/python

View File

@ -0,0 +1,34 @@
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
# This stage is used when running from VS in fast mode (Default for Debug configuration)
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app
EXPOSE 5001
# This stage is used to build the service project
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["dotnet/Directory.Packages.props", "dotnet/"]
COPY ["dotnet/Directory.Build.props", "dotnet/"]
COPY ["dotnet/Directory.Build.targets", "dotnet/"]
COPY ["dotnet/NuGet.config", "dotnet/"]
COPY ["dotnet/src/Microsoft.Autogen.AgentHost/Microsoft.Autogen.AgentHost.csproj", "dotnet/src/Microsoft.Autogen.AgentHost/"]
COPY ["dotnet/src/Microsoft.AutoGen.Runtime.Grpc/Microsoft.AutoGen.RuntimeGateway.Grpc.csproj", "dotnet/src/Microsoft.AutoGen.RuntimeGateway.Grpc/"]
COPY ["dotnet/src/Microsoft.AutoGen.Contracts/Microsoft.AutoGen.Contracts.csproj", "dotnet/src/Microsoft.AutoGen.Contracts/"]
RUN dotnet restore "./dotnet/src/Microsoft.Autogen.AgentHost/Microsoft.Autogen.AgentHost.csproj"
COPY . .
WORKDIR "/src/dotnet/src/Microsoft.Autogen.AgentHost"
RUN dotnet build "./Microsoft.Autogen.AgentHost.csproj" -c $BUILD_CONFIGURATION -o /app/build
# This stage is used to publish the service project to be copied to the final stage
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./Microsoft.Autogen.AgentHost.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "Microsoft.Autogen.AgentHost.dll"]

View File

@ -4,7 +4,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
namespace Microsoft.AutoGen.Runtime.Grpc;
namespace Microsoft.AutoGen.RuntimeGateway.Grpc;
public static class Host
{

View File

@ -6,7 +6,16 @@
<ContainerRepository>autogen-host</ContainerRepository>
<ContainerFamily>alpine</ContainerFamily>
<EnableSdkContainerSupport>true</EnableSdkContainerSupport>
</PropertyGroup>
<PackAsTool>true</PackAsTool>
<ToolCommandName>agenthost</ToolCommandName>
<PackageOutputPath>./nupkg</PackageOutputPath>
</PropertyGroup>
<Import Project="$(RepoRoot)/nuget/nuget-package.props" />
<ItemGroup>
<ContainerEnvironmentVariable Include="ASPNETCORE_HTTP_PORTS" Value="5001" />
<ContainerPort Include="5001" Type="tcp" />
@ -15,7 +24,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Runtime.Grpc\Microsoft.AutoGen.Runtime.Grpc.csproj" />
<ProjectReference Include="..\RuntimeGateway.Grpc\Microsoft.AutoGen.RuntimeGateway.Grpc.csproj" />
<ProjectReference Include="..\Extensions\Aspire\Microsoft.AutoGen.Extensions.Aspire.csproj" />
</ItemGroup>
</Project>

View File

@ -2,5 +2,5 @@
// Program.cs
using Microsoft.Extensions.Hosting;
var app = await Microsoft.AutoGen.Runtime.Grpc.Host.StartAsync(local: false, useGrpc: true).ConfigureAwait(false);
var app = await Microsoft.AutoGen.RuntimeGateway.Grpc.Host.StartAsync(local: false, useGrpc: true).ConfigureAwait(false);
await app.WaitForShutdownAsync();

View File

@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// InferenceAgent.cs
using Google.Protobuf;
using Microsoft.AutoGen.Contracts;
using Microsoft.AutoGen.Core;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.Agents;
/// <summary>
/// Base class for inference agents using the Microsoft.Extensions.AI library.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="id"></param>
/// <param name="runtime"></param>
/// <param name="name"></param>
/// <param name="logger"></param>
/// <param name="client"></param>
public abstract class InferenceAgent<T>(
AgentId id,
IAgentRuntime runtime,
string name,
ILogger<InferenceAgent<T>>? logger,
IChatClient client)
: BaseAgent(id, runtime, name, logger)
where T : IMessage, new()
{
protected IChatClient ChatClient { get; } = client;
private ILogger<InferenceAgent<T>>? Logger => _logger as ILogger<InferenceAgent<T>>;
private Task<ChatResponse> CompleteAsync(
IList<ChatMessage> chatMessages,
ChatOptions? options = null,
CancellationToken cancellationToken = default)
{
return ChatClient.GetResponseAsync(chatMessages, options, cancellationToken);
}
private IAsyncEnumerable<ChatResponseUpdate> CompleteStreamingAsync(
IList<ChatMessage> chatMessages,
ChatOptions? options = null,
CancellationToken cancellationToken = default)
{
return ChatClient.GetStreamingResponseAsync(chatMessages, options, cancellationToken);
}
}

View File

@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IHandleConsole.cs
using Microsoft.AutoGen.Contracts;
namespace Microsoft.AutoGen.Agents;
/// <summary>
/// Default interface methods for an event handler for Input and Output that writes or reads from the console
/// Can be used inside your agents by inheriting from this interface
/// public class MyAgent : BaseAgent, IHandleConsole
/// </summary>
public interface IHandleConsole : IHandle<Output>, IHandle<Input>, IProcessIO
{
/// <summary>
/// Prototype for Publish Message Async method
/// </summary>
/// <param name="message"></param>
/// <param name="topic"></param>
/// <param name="messageId"></param>
/// <param name="cancellationToken"></param>
/// <returns>ValueTask</returns>
ValueTask PublishMessageAsync(object message, TopicId topic, string? messageId = null, CancellationToken cancellationToken = default);
/// <summary>
/// Receives events of type Output and writes them to the console
/// then runs the ProcessOutputAsync method which you should implement in your agent
/// </summary>
/// <param name="item"></param>
/// <param name="messageContext"></param>
/// <returns>ValueTask</returns>
async ValueTask IHandle<Output>.HandleAsync(Output item, MessageContext messageContext)
{
// Assuming item has a property `Message` that we want to write to the console
Console.WriteLine(item.Message);
await ProcessOutputAsync(item.Message);
var evt = new OutputWritten
{
Route = "console"
};
await PublishMessageAsync(evt, new TopicId("OutputWritten"), null, cancellationToken: CancellationToken.None).ConfigureAwait(false);
}
/// <summary>
/// Receives events of type Input and reads from the console, then runs the ProcessInputAsync method
/// which you should implement in your agent
/// </summary>
/// <param name="item"></param>
/// <param name="messageContext"></param>
/// <returns></returns>
async ValueTask IHandle<Input>.HandleAsync(Input item, MessageContext messageContext)
{
Console.WriteLine("Please enter input:");
string content = Console.ReadLine() ?? string.Empty;
await ProcessInputAsync(content);
var evt = new InputProcessed
{
Route = "console"
};
await PublishMessageAsync(evt, new TopicId("InputProcessed"), null, cancellationToken: CancellationToken.None).ConfigureAwait(false);
}
}

View File

@ -0,0 +1,72 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IHandleFileIO.cs
using Microsoft.AutoGen.Contracts;
using Microsoft.Extensions.Logging;
namespace Microsoft.AutoGen.Agents;
/// <summary>
/// Default interface methods for an event handler for Input and Output that writes or reads from a file
/// Can be used inside your agents by inheriting from this interface
/// public class MyAgent : BaseAgent, IHandleFileIO
/// </summary>
public interface IHandleFileIO : IHandle<Input>, IHandle<Output>, IProcessIO
{
// A Logger instance to log messages
ILogger LogTarget { get; }
// The path to the input file
string InputPath { get; }
// The path to the output file
string OutputPath { get; }
// The route of the agent (used in the post-process events)
const string Route = "Microsoft.AutoGen.Agents.IHandleFileIO";
/// <summary>
/// Prototype for Publish Message Async method
/// </summary>
/// <param name="message"></param>
/// <param name="topic"></param>
/// <param name="messageId"></param>
/// <param name="cancellationToken"></param>
/// <returns>ValueTask</returns>
ValueTask PublishMessageAsync(object message, TopicId topic, string? messageId = null, CancellationToken cancellationToken = default);
async ValueTask IHandle<Input>.HandleAsync(Input item, MessageContext messageContext)
{
// validate that the file exists
if (!File.Exists(InputPath))
{
var errorMessage = $"File not found: {InputPath}";
LogTarget.LogError(errorMessage);
//publish IOError event
var err = new IOError
{
Message = errorMessage
};
await PublishMessageAsync(err, new TopicId("IOError"), null, cancellationToken: CancellationToken.None).ConfigureAwait(false);
return;
}
string content;
using (var reader = new StreamReader(item.Message))
{
content = await reader.ReadToEndAsync(CancellationToken.None);
}
await ProcessInputAsync(content);
var evt = new InputProcessed
{
Route = Route
};
await PublishMessageAsync(evt, new TopicId("InputProcessed"), null, cancellationToken: CancellationToken.None).ConfigureAwait(false);
}
async ValueTask IHandle<Output>.HandleAsync(Output item, MessageContext messageContext)
{
using (var writer = new StreamWriter(OutputPath, append: true))
{
await writer.WriteLineAsync(item.Message);
}
var evt = new OutputWritten
{
Route = Route
};
await PublishMessageAsync(evt, new TopicId("OutputWritten"), null, cancellationToken: CancellationToken.None).ConfigureAwait(false);
}
}

View File

@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// IProcessIO.cs
namespace Microsoft.AutoGen.Agents;
/// <summary>
/// Default Interface methods for processing input and output shared by IOAgents that should be implemented in your agent
/// </summary>
public interface IProcessIO
{
/// <summary>
/// Implement this method in your agent to process the input
/// </summary>
/// <param name="message"></param>
/// <returns>Task</returns>
static Task ProcessOutputAsync(string message) { return Task.CompletedTask; }
/// <summary>
/// Implement this method in your agent to process the output
/// </summary>
/// <param name="message"></param>
/// <returns>Task</returns>
static Task<string> ProcessInputAsync(string message) { return Task.FromResult(message); }
}

View File

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<Import Project="$(RepoRoot)/nuget/nuget-package.props" />
<ItemGroup>
<ProjectReference Include="..\Contracts\Microsoft.AutoGen.Contracts.csproj" />
<ProjectReference Include="..\Core\Microsoft.AutoGen.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" />
<PackageReference Include="Google.Protobuf" />
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="protos\agent_events.proto" GrpcServices="Client;Server" Link="Protos\agent_events.proto" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,43 @@
syntax = "proto3";
package agents;
option csharp_namespace = "Microsoft.AutoGen.Agents";
message TextMessage {
string textMessage = 1;
string source = 2;
}
message Input {
string message = 1;
}
message InputProcessed {
string route = 1;
}
message Output {
string message = 1;
}
message OutputWritten {
string route = 1;
}
message IOError {
string message = 1;
}
message NewMessageReceived {
string message = 1;
}
message ResponseGenerated {
string response = 1;
}
message GoodBye {
string message = 1;
}
message MessageStored {
string message = 1;
}
message ConversationClosed {
string user_id = 1;
string user_message = 2;
}
message Shutdown {
string message = 1;
}

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