-
Couldn't load subscription status.
- Fork 1.6k
feat: add CAMEL abstraction for future support of new API style #3328
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
base: master
Are you sure you want to change the base?
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| def _choice_tool_calls_to_camel( | ||
| choice_msg: Any, | ||
| ) -> Optional[List[CamelToolCall]]: | ||
| tool_calls = getattr(choice_msg, "tool_calls", None) | ||
| if not tool_calls: | ||
| return None | ||
| result: List[CamelToolCall] = [] | ||
| for tc in tool_calls: | ||
| func = getattr(tc, "function", None) | ||
| name = getattr(func, "name", None) if func else None | ||
| args_str = getattr(func, "arguments", "{}") if func else "{}" | ||
| try: | ||
| import json | ||
|
|
||
| args = json.loads(args_str) if isinstance(args_str, str) else {} | ||
| except Exception: | ||
| args = {} | ||
| result.append( | ||
| CamelToolCall(id=getattr(tc, "id", ""), name=name or "", args=args) | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Preserve tool call IDs when adapting dict-based responses
The helper _choice_tool_calls_to_camel only reads tool call fields with getattr, which works for OpenAI SDK objects but silently drops data when the tool_calls list contains plain dicts. Many parts of the codebase synthesize ChatCompletion instances via ChatCompletion.construct(...) and pass dictionaries (see tests and model wrappers), so calling adapt_chat_to_camel_response on those objects yields CamelToolCall(id="", name="", args={}). Downstream consumers cannot route tool calls without the id or name. The adapter should also handle dict inputs (e.g. via tc.get("id")) to retain the tool call metadata.
Useful? React with 👍 / 👎.
|
Hi guys, please have some suggestions or comments on the design of the adapter CAMEL layer for compatible with current ChatCompletion style and future extensions |
|
thanks @MuggleJinx for the RFC, Currently in CAMEL all our messages are standardized and processed as If there are interface alignment challenges with directly adapting the |
also agree with we can get response and directly transfer to |
CAMEL Abstractions for OpenAI Responses API — Phase 0 & 1
Summary
This RFC proposes a model-agnostic messaging and response abstraction that
enables CAMEL to support the OpenAI Responses API while preserving full
backward compatibility with the existing Chat Completions plumbing. (issue #3028)
Phase 0 catalogs the current dependency surface. Phase 1 introduces new
abstractions and a Chat Completions adapter, delivering a pure refactor with
zero functional differences.
Motivation
The codebase directly consumes
ChatCompletionMessageParamas requestmessages and expects
ChatCompletionresponses (e.g., inChatAgent).The OpenAI Responses API uses segmented inputs and a
Responseobject withdifferent streaming and parsing semantics. A direct swap would break agents,
memories, token counting, and tool handling.
We therefore introduce CAMEL-native types that can be adapted both to legacy
Chat Completions and to Responses, enabling a staged migration.
Goals
CamelMessageandCamelModelResponsetypes.Non-Goals (Phase 1)
Design
New Modules
camel/core/messages.pyCamelContentPart— minimal content fragment (type:text|image_url).CamelMessage— model-agnostic message with role, content parts, optional name/tool_call_id.openai_messages_to_camel(List[OpenAIMessage]) -> List[CamelMessage]camel_messages_to_openai(List[CamelMessage]) -> List[OpenAIMessage]camel/responses/model_response.pyCamelToolCall— normalized tool call (id, name, args).CamelUsage— normalized usage withrawattached.CamelModelResponse— id, model, created,output_messages,tool_call_requests,finish_reasons,usage, andraw(provider response).camel/responses/adapters/chat_completions.pyadapt_chat_to_camel_response(ChatCompletion) -> CamelModelResponse.Type Relaxation
camel/agents/_types.py:ModelResponse.responseis relaxed toAnyto decoupleagent plumbing from provider schemas. Existing tests pass
MagicMockhere, andthe change avoids tight coupling when adapters are introduced.
Compatibility
ChatCompletionfrom themodel backend; the adapter is exercised via unit tests and can be opted into
in later phases.
BaseMessageor memory/token APIs in this phase.Testing
test/responses/test_chat_adapter.pybuilds a minimalChatCompletionviaconstruct()and validates:CamelModelResponse.output_messages.CamelToolCall.Alternatives Considered
and risk; the adapter path enables incremental, testable rollout.
Rollout Plan
adjust streaming/tool-calls to operate over
CamelModelResponse, and migratetoken counting to work from abstract messages.
OpenAIResponsesModelimplementingclient.responses.{create,parse,stream}with converters from
CamelMessagesegments and back intoCamelModelResponse.Future Work
CamelContentPartto include audio/video and tool fragments.