Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: ChatAgent #1424

Merged
merged 39 commits into from
Feb 17, 2025
Merged

refactor: ChatAgent #1424

merged 39 commits into from
Feb 17, 2025

Conversation

WHALEEYE
Copy link
Contributor

@WHALEEYE WHALEEYE commented Jan 10, 2025

Description

Thoroughly refactored ChatAgent.

Motivation and Context

  • Move function calling into model backends - OpenAI Supported
  • Move structured output into model backends - OpenAI Supported
  • Code quality improvement inside ChatAgent
  • Support true asynchronous model calling
  • Support tool calling for stream output

This will close #1334.

Important Changes

For the convenience of the reviewers, the important changes to the code are listed here:

  1. rename functions: async functions are prefixed with a instead of being postfixed with async, for example, step_async -> astep, to make it more concise.
  2. moved some of the internal function and types into _utils.py and _types.py.
  3. added async version of stream handling.
  4. added an internal type ModelResponse to represent the responsefrom models, which will only be used in internal ChatAgent.
  5. removed all keys with None value in configs after as_dict().

@WHALEEYE WHALEEYE self-assigned this Jan 10, 2025
@WHALEEYE WHALEEYE linked an issue Jan 10, 2025 that may be closed by this pull request
2 tasks
Co-authored-by: Xiaotian Jin <jinxiaotian_sal@outlook.com>
Copy link
Collaborator

@MuggleJinx MuggleJinx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Zhaoxuan! it's a lot of wrok! I left some small comments. It looks good to me, we can merge it soon if all test has been passed.

Copy link
Collaborator

@liuxukun2000 liuxukun2000 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks zhaoxuan!

Copy link
Member

@Wendong-Fan Wendong-Fan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @WHALEEYE 's great work!

  1. Seems the prompt based tool calling is not support in this PR
  2. Some test need to be fixed.
  3. Currently external tools are also executed?

Other comments are minor issues, let's fix all these in this PR, we also need to update the doc and cookbook to align with our change in another PR

logger = logging.getLogger(__name__)


def generate_tool_prompt(tool_schema_list: List[Dict[str, Any]]) -> str:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this function used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet used, they are supposed to be used by models that does not natively support tool callings, but we havent added support for them yet

# Empty -> use no tools
elif not tools:
tools = None
return self._run(messages, response_format, tools)
Copy link
Member

@Wendong-Fan Wendong-Fan Feb 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for models doesn't support native tool calling or structured output, these 2 parameters would still be passed to _run, causing error, we need to check and add logic to handle this in model level further

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are going to implement _run() for every model backend so we will handle these inside each model backend. For now if our model backend doesn't support these two options, they will be simply ignored.

@Wendong-Fan Wendong-Fan self-requested a review February 14, 2025 05:03
@Wendong-Fan Wendong-Fan changed the title Refactor: ChatAgent refactor: ChatAgent Feb 14, 2025
@Wendong-Fan Wendong-Fan merged commit 0e84957 into master Feb 17, 2025
4 of 6 checks passed
@Wendong-Fan Wendong-Fan deleted the refactor/chatagent branch February 17, 2025 11:42
return None


def extract_tool_call(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the argument is self and do we use it anywhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not used, refer to: #1621

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this from inside ChatAgent and forgot to remove this. I will update this one in the follow up PRs

@lightaime
Copy link
Member

Thanks @WHALEEYE! It is a bit cofusing for me when is _prepare_request supposed to be used and when not. Could you elaborate that?

`ChatCompletion` in the non-stream mode, or
`AsyncStream[ChatCompletionChunk]` in the stream mode.
"""
response = await self._async_client.chat.completions.create(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need here?

request_config = self._prepare_request(
            messages, response_format, tools
        )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: No status
Development

Successfully merging this pull request may close these issues.

[Feature Request] ChatAgent further refactor
5 participants