Skip to content

Python: Relax Agent Invocation Methods to Allow Positional or Keyword Arguments for messages #12248

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

Merged
merged 1 commit into from
May 23, 2025

Conversation

moonbox3
Copy link
Contributor

@moonbox3 moonbox3 commented May 23, 2025

Motivation and Context

This PR relaxes the API signatures of all agent invocation methods (get_response, invoke, invoke_stream) by changing the messages parameter from keyword-only to positional-or-keyword. This enhances ergonomics and Pythonic usability by allowing callers to pass messages either positionally or as a keyword argument:

agent.get_response("Why is the sky blue?")
agent.get_response(messages="Why is the sky blue?")

With our current use of **kwargs, it is possible to explicitly pass None for messages (like agent.get_response(messages=None)). However, this does not feel idiomatic in Python. If a caller wishes to invoke the agent on an existing thread (which already contains all relevant context), it is more natural and Pythonic to simply write:

response = await agent.get_response()

This change makes the API more user-friendly, and removes unnecessary verbosity when no new messages need to be provided.

Impact

  • Backward compatible for all previous usage.
  • Enables concise and intuitive API calls for primary message arguments.
  • Subclasses overriding the prior keyword-only signature will continue to work at runtime, but static type-checkers may require updating their signatures to match the new base definition.
  • No runtime breaking changes are expected.
Scenario Breaks at runtime? Breaks at type-check? Notes
Subclass w/keyword-only No Yes Type checker error, but runtime OK
Subclass matching base No No Fine
Calls expecting keyword-only No No Fine
Calls expecting positional No (now allowed) No Improved ergonomics
Decorators relying on kw-only No No (unless strict sig) Only if decorator is brittle, rare
Code generation/docs No No Needs updating docs, not an actual code break
Reflection-based invocation No No Slight difference in behavior, but not breaking

Documentation and usage examples will be updated to reflect the improved invocation style.

Description

Relaxes the API signatures of all agent invocation methods.

Contribution Checklist

@moonbox3 moonbox3 self-assigned this May 23, 2025
@moonbox3 moonbox3 requested a review from a team as a code owner May 23, 2025 04:06
@markwallace-microsoft markwallace-microsoft added the python Pull requests for the Python Semantic Kernel label May 23, 2025
@markwallace-microsoft
Copy link
Member

Python Unit Test Overview

Tests Skipped Failures Errors Time
3595 18 💤 0 ❌ 0 🔥 1m 46s ⏱️

@eavanvalkenburg eavanvalkenburg added this pull request to the merge queue May 23, 2025
Merged via the queue into microsoft:main with commit afb1e15 May 23, 2025
32 checks passed
@github-project-automation github-project-automation bot moved this to Sprint: Done in Semantic Kernel May 23, 2025
eavanvalkenburg pushed a commit that referenced this pull request May 26, 2025
… Arguments for `messages` (#12248)

### Motivation and Context

This PR relaxes the API signatures of all agent invocation methods
(`get_response`, `invoke`, `invoke_stream`) by changing the `messages`
parameter from keyword-only to positional-or-keyword. This enhances
ergonomics and Pythonic usability by allowing callers to pass messages
either positionally or as a keyword argument:

```python
agent.get_response("Why is the sky blue?")
agent.get_response(messages="Why is the sky blue?")
```

With our current use of **kwargs, it is possible to explicitly pass None
for messages (like `agent.get_response(messages=None)`). However, this
does not feel idiomatic in Python. If a caller wishes to invoke the
agent on an existing thread (which already contains all relevant
context), it is more natural and Pythonic to simply write:

```python
response = await agent.get_response()
```

This change makes the API more user-friendly, and removes unnecessary
verbosity when no new messages need to be provided.

Impact
- Backward compatible for all previous usage.
- Enables concise and intuitive API calls for primary message arguments.
- Subclasses overriding the prior keyword-only signature will continue
to work at runtime, but static type-checkers may require updating their
signatures to match the new base definition.
- No runtime breaking changes are expected.

| Scenario | Breaks at runtime? | Breaks at type-check? | Notes |

|----------------------------------|----------------------|-------------------------|--------------------------------------------------|
| Subclass w/keyword-only | No | Yes | Type checker error, but runtime
OK |
| Subclass matching base | No | No | Fine |
| Calls expecting keyword-only | No | No | Fine |
| Calls expecting positional | No (now allowed) | No | Improved
ergonomics |
| Decorators relying on kw-only | No | No (unless strict sig) | Only if
decorator is brittle, rare |
| Code generation/docs | No | No | Needs updating docs, not an actual
code break |
| Reflection-based invocation | No | No | Slight difference in behavior,
but not breaking |


Documentation and usage examples will be updated to reflect the improved
invocation style.

<!-- Thank you for your contribution to the semantic-kernel repo!
Please help reviewers and future users, providing the following
information:
  1. Why is this change required?
  2. What problem does it solve?
  3. What scenario does it contribute to?
  4. If it fixes an open issue, please link to the issue here.
-->

### Description

Relaxes the API signatures of all agent invocation methods.

<!-- Describe your changes, the overall approach, the underlying design.
These notes will help understanding how your code works. Thanks! -->

### Contribution Checklist

<!-- Before submitting this PR, please make sure: -->

- [X] The code builds clean without any errors or warnings
- [X] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [X] All unit tests pass, and I have added new tests where possible
- [X] I didn't break anyone 😄
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
agents python Pull requests for the Python Semantic Kernel
Projects
Status: Sprint: Done
Development

Successfully merging this pull request may close these issues.

4 participants