diff --git a/docs/examples/agents/react.py b/docs/examples/agents/react.py index 9cb594f8..27099592 100644 --- a/docs/examples/agents/react.py +++ b/docs/examples/agents/react.py @@ -13,8 +13,12 @@ import mellea.stdlib import mellea.stdlib.base import mellea.stdlib.chat +from mellea.backends import model_ids +from mellea.helpers.fancy_logger import FancyLogger from mellea.stdlib.base import ChatContext +FancyLogger.get_logger().setLevel("ERROR") + react_system_template: Template = Template( """Answer the user's question as best you can. diff --git a/docs/examples/mcp/README.md b/docs/examples/mcp/README.md new file mode 100644 index 00000000..8202f789 --- /dev/null +++ b/docs/examples/mcp/README.md @@ -0,0 +1,46 @@ +# Write a poem MCP +This is a simple example to show how to write a MCP tool +with Mellea and instruct-validate-repair. Being able to +speak the tool language allows you to integrate with +Claude Desktop, Langflow, ... + +See code in [mcp_example.py](mcp_example.py) + +## Run the example +You need to install the mcp package: +```bash +uv pip install "mcp[cli]" +``` + +and run the example in MCP debug UI: +```bash +uv run mcp dev docs/examples/tutorial/mcp_example.py +``` + + +## Use in Langflow +Follow this path (JSON) to use it in Langflow: [https://docs.langflow.org/mcp-client#mcp-stdio-mode](https://docs.langflow.org/mcp-client#mcp-stdio-mode) + +The JSON to register your MCP tool is the following. Be sure to insert the absolute path to the directory containing the mcp_example.py file: + +```json +{ + "mcpServers": { + "mellea_mcp_server": { + "command": "uv", + "args": [ + "--directory", + "/mellea/docs/examples/mcp", + "run", + "mcp", + "run", + "mcp_example.py" + ] + } + } +} +``` + + + + diff --git a/docs/examples/mcp/mcp_example.py b/docs/examples/mcp/mcp_example.py new file mode 100644 index 00000000..48c042b5 --- /dev/null +++ b/docs/examples/mcp/mcp_example.py @@ -0,0 +1,54 @@ +"""Example of an MCP server. + +You need to install the mcp package: +uv pip install "mcp[cli]" + +and run the example in MCP debug UI: +uv run mcp dev docs/examples/tutorial/mcp_example.py +""" + +from mcp.server.fastmcp import FastMCP + +from mellea import MelleaSession +from mellea.backends import ModelOption, model_ids +from mellea.backends.ollama import OllamaModelBackend +from mellea.stdlib.base import ModelOutputThunk +from mellea.stdlib.requirement import Requirement, simple_validate +from mellea.stdlib.sampling import RejectionSamplingStrategy + +# ################# +# run MCP debug UI with: uv run mcp dev docs/examples/tutorial/mcp_example.py +# ################## + + +# Create an MCP server +mcp = FastMCP("Demo") + + +@mcp.tool() +def write_a_poem(word_limit: int) -> str: + """Write a poem with a word limit.""" + m = MelleaSession( + OllamaModelBackend( + model_ids.HF_SMOLLM2_2B, + model_options={ModelOption.MAX_NEW_TOKENS: word_limit + 10}, + ) + ) + wl_req = Requirement( + f"Use only {word_limit} words.", + validation_fn=simple_validate(lambda x: len(x.split(" ")) < word_limit), + ) + + res = m.instruct( + "Write a poem", + requirements=[wl_req], + strategy=RejectionSamplingStrategy(loop_budget=2), + ) + assert isinstance(res, ModelOutputThunk) + return str(res.value) + + +@mcp.resource("greeting://{name}") +def get_greeting(name: str) -> str: + """Get a personalized greeting.""" + return f"Hello, {name}!" diff --git a/docs/examples/mcp/mcp_server.json b/docs/examples/mcp/mcp_server.json new file mode 100644 index 00000000..60bd5205 --- /dev/null +++ b/docs/examples/mcp/mcp_server.json @@ -0,0 +1,15 @@ +{ + "mcpServers": { + "mellea_mcp_server": { + "command": "uv", + "args": [ + "--directory", + "/mellea/docs/examples/mcp", + "run", + "mcp", + "run", + "mcp_example.py" + ] + } + } +} diff --git a/docs/examples/mify/rich_table_execute_basic.py b/docs/examples/mify/rich_table_execute_basic.py index a9dbcad8..40be7cd4 100644 --- a/docs/examples/mify/rich_table_execute_basic.py +++ b/docs/examples/mify/rich_table_execute_basic.py @@ -4,8 +4,11 @@ from mellea import start_session from mellea.backends import model_ids from mellea.backends.types import ModelOption +from mellea.helpers.fancy_logger import FancyLogger from mellea.stdlib.docs.richdocument import RichDocument, Table +FancyLogger.get_logger().setLevel("ERROR") + """ Here we demonstrate the use of the (internally m-ified) class RichDocument and Table that are wrappers around Docling documents. @@ -42,7 +45,7 @@ def cached_doc(): model_id=model_ids.META_LLAMA_3_2_3B, model_options={ModelOption.MAX_NEW_TOKENS: 500}, ) - +print("==> Outputs:") # apply transform on the Table and make sure that the returned object is a Table. Try up to 5 times. for seed in [x * 12 for x in range(5)]: table_transformed = m.transform(