Skip to content

feat: Integrations core classes - #24

Merged
akihikokuroda merged 6 commits into
generative-computing:mainfrom
akihikokuroda:refactor
Mar 13, 2026
Merged

akihikokuroda merged 6 commits into
generative-computing:mainfrom
akihikokuroda:refactor

Conversation

@akihikokuroda

Copy link
Copy Markdown
Contributor

@akihikokuroda
akihikokuroda marked this pull request as draft February 17, 2026 18:48
@mergify

mergify Bot commented Feb 17, 2026

Copy link
Copy Markdown

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert|release)(?:\(.+\))?:

@akihikokuroda
akihikokuroda marked this pull request as ready for review February 27, 2026 18:18

@psschwei psschwei left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Couple of comments here:

  • We should confirm with @nrfulton where we should put the integrations. My understanding is that mellea-contribs is going to be a single package, but let's confirm. (if that is the case, we'll need to combine the pyproject.tomls)

  • 10 of the tests failed when I tried running them. Here's how I ran them:

cd integrations/mellea-integration-core
uv sync
uv add pytest
uv run pytest

and the failing tests:

FAILED tests/test_base.py::test_prepare_generation_no_messages - Failed: DID NOT RAISE <class 'ValueError'>
FAILED tests/test_base.py::test_agenerate_with_mellea_chat - Failed: async def functions are not natively supported.
FAILED tests/test_base.py::test_agenerate_with_mellea_instruct - Failed: async def functions are not natively supported.
FAILED tests/test_base.py::test_full_agenerate_flow - Failed: async def functions are not natively supported.
FAILED tests/test_message_converter.py::test_extract_content_from_response_fallback - AttributeError: Mock object has no attribute '__str__'
FAILED tests/test_tool_converter.py::test_extract_tool_schema_basic - AssertionError: assert <Mock name='test_tool.name' id='4418542224'> == 'test_tool'
FAILED tests/test_tool_converter.py::test_get_tool_callable_not_found - Failed: DID NOT RAISE <class 'ValueError'>
FAILED tests/test_tool_converter.py::test_extract_tool_calls_from_response_tool_calls_attr - AssertionError: assert <Mock name='test_tool.name' id='4418765072'> == 'test_tool'
FAILED tests/test_tool_converter.py::test_extract_tool_calls_from_response_private_attr - AssertionError: assert <Mock name='test_tool.name' id='4418769968'> == 'test_tool'
FAILED tests/test_tool_converter.py::test_parse_tool_calls_default_implementation - AssertionError: assert <Mock name='test_tool.name' id='4418772944'> == 'test_tool'
  • related point, we should add these tests to the CI

@akihikokuroda

Copy link
Copy Markdown
Contributor Author

I might forget check these tests. Thanks for checking.

@akihikokuroda

Copy link
Copy Markdown
Contributor Author

Tests can be added once we can confirm home of these integrations.

Comment thread integrations/mellea-integration-core/README.md Outdated
- ✅ **Tool Conversion**: Utilities for handling tool calling across frameworks
- ✅ **Requirements Support**: Built-in support for Mellea's validation features
- ✅ **Async Support**: Both sync and async generation patterns
- ✅ **Type Safety**: Protocol-based design with type hints

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

While we use type hints, a lot of them are Any which isn't exactly type safe

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Adding some clarification here.

Comment on lines +49 to +51
valid_roles = ["system", "user", "assistant", "tool"]
if role not in valid_roles:
role = "user" # Default fallback

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should we instead log an error, since if the role isn't valid that may mean we have a bug in the conversion logic ?

ValueError: If validation failed and no samples were generated
"""
# Check if this is a SamplingResult object
if hasattr(response, "success") and hasattr(response, "result"):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would it be better to explicitly check, something like

Suggested change
if hasattr(response, "success") and hasattr(response, "result"):
if SamplingResult is not None and isinstance(response, SamplingResult):

?

Comment on lines +126 to +129
else:
# If response has no content or value attribute, return empty string
# rather than string representation of the object
return ""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

would it be worth logging this (assuming an empty response could be a sign of something having gone wrong)?


# Pattern to match ToolCall objects in the string
# Matches: ToolCall(function=Function(name='tool_name', arguments={...}))
pattern = r"ToolCall\(function=Function\(name='([^']+)',\s*arguments=(\{[^}]+\})\)\)"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is there any chance that arguments could be a nested dict? e.g. {'a': {'b': 1}} if so, I think the regex may fail on that case

@akihikokuroda akihikokuroda Mar 6, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated to accept the nested case. Comments are added for clarification.

Comment on lines +225 to +231
## Existing Integrations

This core package is used by:

- **[mellea-langchain](../langchain/)**: LangChain integration
- **[mellea-crewai](../crewai/)**: CrewAI integration
- **[mellea-dspy](../dspy/)**: DSPy integration

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we may want to hold off adding these until we land those integrations

@akihikokuroda
akihikokuroda requested a review from psschwei March 6, 2026 22:16
Comment on lines +95 to +97
# Note: This pattern uses a greedy match to handle nested dictionaries
# It will match from the first { to the last } in the arguments section
pattern = r"ToolCall\(function=Function\(name='([^']+)',\s*arguments=(\{.+?\})\)\)"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

technically, .+? is lazy not greedy. for greedy, you'd need just.+
it might be worth doing something like regex-extracting just the tool name, finding the arguments prefix, and then using a brace-counting scan (a small helper to match closing and opening braces) to grab the full dict string ? wdyt?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for suggestion. I implemented it.

Signed-off-by: Akihiko Kuroda <akihikokuroda2020@gmail.com>
Signed-off-by: Akihiko Kuroda <akihikokuroda2020@gmail.com>
Signed-off-by: Akihiko Kuroda <akihikokuroda2020@gmail.com>
Signed-off-by: Akihiko Kuroda <akihikokuroda2020@gmail.com>
Signed-off-by: Akihiko Kuroda <akihikokuroda2020@gmail.com>

@psschwei psschwei left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm generally ok with this, pending resolution of the location question.
@AngeloDanducci can you also give a review?

try:
schema["function"]["parameters"] = tool.args_schema.schema()
except Exception:
# If schema extraction fails, use empty dict

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

May be worth logging the exception, doesn't seem like a big deal though.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Had a couple of failures in here

FAILED tests/test_base.py::test_handle_sampling_results_success - AssertionError: assert <Mock id='4426200416'> == <Mock name='mock.result' id='4426200128'>
FAILED tests/test_base.py::test_handle_sampling_results_failure_with_samples - AssertionError: assert <Mock id='4426102064'> == <Mock id='4426097168'>
FAILED tests/test_base.py::test_handle_sampling_results_failure_no_samples - Failed: DID NOT RAISE <class 'ValueError'>

@AngeloDanducci

Copy link
Copy Markdown

Couple of test failures but otherwise LGTM.

Re location - I think it makes sense that each "sub project" could have its own toml but it's not a huge deal to me either way.

Signed-off-by: Akihiko Kuroda <akihikokuroda2020@gmail.com>
@akihikokuroda

Copy link
Copy Markdown
Contributor Author

Thanks for review. I made fixes and suggested changes.

@AngeloDanducci AngeloDanducci left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Per offline discussion, we should likely move to uv workspaces for the approach of multi interconnected packages in the same repo.

If you want to set that up in this PR great if not feel free to merge and I'll open an issue to follow up after we get the integrations core PRs in.

@akihikokuroda
akihikokuroda merged commit 50d2dd8 into generative-computing:main Mar 13, 2026
4 checks passed
@akihikokuroda
akihikokuroda deleted the refactor branch March 13, 2026 17:54
Sign up for free to 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.

Define core adapter interface for framework integrations

3 participants