Skip to content

feat(clients): add GenericOpenAIAgent for any OpenAI Chat Completions API endpoint - #145

Merged
Gagan Somashekar (gaganso) merged 9 commits into
microsoft:mainfrom
srmanda-cs:feature/generic-openai-client
Feb 25, 2026
Merged

feat(clients): add GenericOpenAIAgent for any OpenAI Chat Completions API endpoint#145
Gagan Somashekar (gaganso) merged 9 commits into
microsoft:mainfrom
srmanda-cs:feature/generic-openai-client

Conversation

@srmanda-cs

@srmanda-csAsh Manda (srmanda-cs) commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes#144

Adds a GenericOpenAIClient and GenericOpenAIAgent that work with any provider
implementing the OpenAI Chat Completions API (/v1/chat/completions), with both base_url and
model configurable at runtime. My motivating use case is the
Poe API,
but this should work with any OpenAI Chat Completions-compatible endpoint.


Changes

FileChange
clients/utils/llm.pyAdded GenericOpenAIClient — uses client.chat.completions.create, accepts base_url, model, and api_key
clients/generic_openai.pyNew GenericOpenAIAgent following the same pattern as existing agents
clients/registry.pyRegistered GenericOpenAIAgent as "generic" in AgentRegistry
clients/README.mdAdded client to the list and documented the three env vars
.env.exampleAdded OPENAI_COMPATIBLE_API_KEY, OPENAI_COMPATIBLE_BASE_URL, OPENAI_COMPATIBLE_MODEL

Breaking Changes

None. All changes are purely additive — no existing classes, agents, or configurations
were modified.


Notes for Reviewers

This is a draft PR and I'm very open to feedback! Specifically, I'd appreciate input on:

  • Naming: GenericOpenAIAgent / GenericOpenAIClient vs. something else (e.g. OpenAICompatible*)
  • Whether "generic" is a good registry key, or if there's a preferred convention
  • Whether the env var prefix OPENAI_COMPATIBLE_ is appropriate
  • Any patterns from the existing clients I should be mirroring more closely

Happy to revise anything before this is considered ready for review.

@HacksonClark

Copy link
Copy Markdown
Contributor

For testing, could you run the agent on the AIOpsLab benchmark and attach some logs here? Should be good to merge after that :)

@srmanda-cs

Copy link
Copy Markdown
ContributorAuthor

@microsoft-github-policy-service agree

@srmanda-cs

Copy link
Copy Markdown
ContributorAuthor

Will do ASAP!

…tions API links
- Update Poe doc URL from /responses-api to /openai-compatible-api in:
- clients/generic_openai.py (module docstring)
- clients/README.md (two occurrences)
- .env.example (section heading and comment)
@srmanda-cs

Copy link
Copy Markdown
ContributorAuthor

generic_openai_run.log

Here is the attached log file. It isn't a full run. Just a partial run, enough to say that the agent is working.

@HacksonClark

Copy link
Copy Markdown
Contributor

Logs look great!

@srmanda-cs
Ash Manda (srmanda-cs) marked this pull request as ready for review February 25, 2026 00:03
CopilotAI review requested due to automatic review settings February 25, 2026 00:03

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new “generic” OpenAI-compatible client/agent so AIOpsLab can talk to any provider exposing an OpenAI-style Chat Completions endpoint, with base_url and model configurable via env vars or constructor args.

Changes:

  • Added GenericOpenAIClient to clients/utils/llm.py with configurable base_url, model, and api_key.
  • Introduced GenericOpenAIAgent (clients/generic_openai.py) and registered it under "generic" in AgentRegistry.
  • Documented configuration in clients/README.md and added sample env vars to .env.example.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
FileDescription
clients/utils/llm.pyAdds GenericOpenAIClient using OpenAI(..., base_url=...) and Chat Completions calls.
clients/generic_openai.pyNew agent wiring GenericOpenAIClient into the orchestrator flow.
clients/registry.pyRegisters the new agent under the "generic" key.
clients/README.mdDocuments the new generic agent and required env vars.
.env.exampleAdds OPENAI_COMPATIBLE_* example configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadclients/utils/llm.py Outdated
Comment threadclients/utils/llm.py
Comment on lines +354 to +358
max_tokens: int = 16000,
):
self.cache = Cache()
self.model = model or os.getenv("OPENAI_COMPATIBLE_MODEL", "gpt-4o")
self.max_tokens = max_tokens

CopilotAIFeb 25, 2026

Copy link

Choose a reason for hiding this comment

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

max_tokens defaults to 16000 here, while the other Chat Completions clients in this module default to 1024. A high default is likely to exceed many providers’ limits and cause requests to fail unless callers override it; consider using a more conservative default (or reading an env var) to improve out-of-the-box compatibility.

Suggested change
max_tokens: int=16000,
):
self.cache=Cache()
self.model=modeloros.getenv("OPENAI_COMPATIBLE_MODEL", "gpt-4o")
self.max_tokens=max_tokens
max_tokens: Optional[int] =None,
):
self.cache=Cache()
self.model=modeloros.getenv("OPENAI_COMPATIBLE_MODEL", "gpt-4o")
ifmax_tokensisnotNone:
self.max_tokens=max_tokens
else:
env_max_tokens=os.getenv("OPENAI_COMPATIBLE_MAX_TOKENS")
self.max_tokens=int(env_max_tokens) ifenv_max_tokensisnotNoneelse1024

Copilot uses AI. Check for mistakes.

@srmanda-csAsh Manda (srmanda-cs)Feb 25, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

If the max tokens isn't set that high, a lot of api endpoints (like Poe) that support thinking will not be able to initialize, as the minimum token requirement is 4096. And just because max token requirement is high does not imply that the full token context will be used. It is a good idea to take in an environment variable, but then we would have to update the implementation for every client. I think, there is enough flexibility offered here.

Comment threadclients/utils/llm.py
Comment on lines +392 to +394
except Exception as e:
print(f"Exception: {repr(e)}")
raise e

CopilotAIFeb 25, 2026

Copy link

Choose a reason for hiding this comment

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

In the exception handler, raise e resets the traceback context in Python. Use a bare raise to preserve the original stack trace (and consider using the project’s logging approach instead of print for errors).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This is standard implementation for every client, for consistency used the same block of code

Comment on lines +1 to +6
"""Generic OpenAI-compatible chat client (with shell access) for AIOpsLab.

This agent works with any provider that implements the OpenAI Chat Completions
API endpoint (/v1/chat/completions), such as Poe
(https://creator.poe.com/docs/external-applications/openai-compatible-api),
standard OpenAI deployments, vLLM, LocalAI, or other compatible services.

CopilotAIFeb 25, 2026

Copy link

Choose a reason for hiding this comment

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

The PR title/description references the OpenAI “Responses API”, but this agent (and GenericOpenAIClient) is implemented against the Chat Completions endpoint (/v1/chat/completions). Please align the PR wording/docs with what’s actually supported (either update the PR description/title to Chat Completions, or implement the Responses API).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Updated

Comment on lines +41 to +46
def init_context(self, problem_desc: str, instructions: str, apis: str):
"""Initialize the context for the agent."""

self.shell_api = self._filter_dict(apis, lambda k, _: "exec_shell" in k)
self.submit_api = self._filter_dict(apis, lambda k, _: "submit" in k)
stringify_apis = lambda apis: "\n\n".join(

CopilotAIFeb 25, 2026

Copy link

Choose a reason for hiding this comment

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

init_context types apis as str, but the implementation treats it as a mapping (calls .items() and filters by key). Updating the annotation to a Mapping[str, Any] (or similar) would make the contract clearer and avoid misleading type hints.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Standard implementation for every agent. Reused similar code block in generic OpenAI agent as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yeah, this is a nit but making the change I feel.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

I agree the type hint should be updated, but since this apis: str pattern is currently standard across multiple agent files, changing it just here would create inconsistency. To keep this PR focused on its original scope, how about I open a separate issue and a dedicated PR to update this type hint universally across all agents?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Makes sense

@srmanda-csAsh Manda (srmanda-cs) changed the title feat(clients): add GenericOpenAIAgent for any OpenAI Responses API endpointfeat(clients): add GenericOpenAIAgent for any OpenAI Chat Completions API endpointFeb 25, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@gaganso
Gagan Somashekar (gaganso) merged commit daa7961 into microsoft:mainFeb 25, 2026
1 check passed
@srmanda-cs
Ash Manda (srmanda-cs) deleted the feature/generic-openai-client branch February 25, 2026 22:03
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Add generic OpenAI-compatible client to support any OpenAI Responses API endpoint

4 participants

@srmanda-cs@HacksonClark@gaganso