|
| 1 | +--- |
| 2 | +title: Provider Modes |
| 3 | +description: "Control how tools are exposed to AI agents" |
| 4 | +--- |
| 5 | + |
| 6 | +Concierge wraps your tools through a **provider mode** that controls what the agent sees. Four modes, each a different trade-off between simplicity and structure. |
| 7 | + |
| 8 | +## Plain |
| 9 | + |
| 10 | +Default. All tools exposed directly β no wrapping, no transformation. |
| 11 | + |
| 12 | +```python |
| 13 | +from concierge import Concierge |
| 14 | + |
| 15 | +app = Concierge("my-server") |
| 16 | +``` |
| 17 | + |
| 18 | +The agent sees every tool you register and calls them by name. Use this for small APIs where all tools are relevant at once. |
| 19 | + |
| 20 | +## Search |
| 21 | + |
| 22 | +Two meta-tools: `search_tools(query)` and `call_tool(tool_name, arguments)`. The agent discovers tools via semantic search, then calls them by name. |
| 23 | + |
| 24 | +```python |
| 25 | +from concierge import Concierge, Config, ProviderType |
| 26 | + |
| 27 | +app = Concierge( |
| 28 | + "my-server", |
| 29 | + config=Config(provider_type=ProviderType.SEARCH), |
| 30 | +) |
| 31 | +``` |
| 32 | + |
| 33 | +Uses `sentence-transformers` for embeddings (install separately). Designed for large APIs with 100+ tools where the agent shouldn't see everything at once. |
| 34 | + |
| 35 | +**Config options:** |
| 36 | +- `max_results` β number of search results returned (default: `5`) |
| 37 | +- `model` β custom `SentenceTransformer` instance (default: `BAAI/bge-large-en-v1.5`) |
| 38 | + |
| 39 | +## Plan |
| 40 | + |
| 41 | +One meta-tool: `execute_plan(steps)`. The agent submits a JSON plan β a list of sequential steps that can reference each other's outputs. |
| 42 | + |
| 43 | +```python |
| 44 | +from concierge import Concierge, Config, ProviderType |
| 45 | + |
| 46 | +app = Concierge( |
| 47 | + "my-server", |
| 48 | + config=Config(provider_type=ProviderType.PLAN), |
| 49 | +) |
| 50 | +``` |
| 51 | + |
| 52 | +**What the agent sends:** |
| 53 | + |
| 54 | +```json |
| 55 | +{ |
| 56 | + "steps": [ |
| 57 | + {"id": "backup", "tool": "create_backup", "args": {"database": "prod"}}, |
| 58 | + { |
| 59 | + "id": "validate", |
| 60 | + "tool": "validate_backup", |
| 61 | + "args": { |
| 62 | + "backup_id": {"output_by_reference": {"backup": ["backup_id"]}} |
| 63 | + } |
| 64 | + } |
| 65 | + ] |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +Steps execute sequentially. A step can pass data to later steps using `output_by_reference` β but only into parameters annotated with `Sharable()`: |
| 70 | + |
| 71 | +```python |
| 72 | +from typing import Annotated |
| 73 | +from concierge.core.sharable import Sharable |
| 74 | + |
| 75 | +@app.tool() |
| 76 | +def validate_backup(backup_id: Annotated[str, Sharable()]) -> dict: |
| 77 | + ... |
| 78 | +``` |
| 79 | + |
| 80 | +The reference `{"output_by_reference": {"backup": ["backup_id"]}}` resolves to `results["backup"]["backup_id"]`. Only backward references allowed β no cycles, no self-references. |
| 81 | + |
| 82 | +## Code |
| 83 | + |
| 84 | +One meta-tool: `execute_code(code, timeout)`. The agent writes async Python that calls tools directly. |
| 85 | + |
| 86 | +```python |
| 87 | +from concierge import Concierge, Config, ProviderType |
| 88 | + |
| 89 | +app = Concierge( |
| 90 | + "my-server", |
| 91 | + config=Config(provider_type=ProviderType.CODE), |
| 92 | +) |
| 93 | +``` |
| 94 | + |
| 95 | +**What the agent writes:** |
| 96 | + |
| 97 | +```python |
| 98 | +# Discovery |
| 99 | +print(runtime.list_tools()) |
| 100 | +print(runtime.get_tool_info("create_backup")) |
| 101 | +print(runtime.search_tools("backup")) |
| 102 | + |
| 103 | +# Call tools |
| 104 | +backup = await tools.create_backup(database="prod") |
| 105 | +result = await tools.validate_backup(backup_id=backup["backup_id"]) |
| 106 | +print(result) |
| 107 | +``` |
| 108 | + |
| 109 | +Two modules are injected into the sandbox: |
| 110 | +- `tools` β every registered tool as an async callable |
| 111 | +- `runtime` β discovery helpers: `list_tools()`, `get_tool_info(name)`, `search_tools(query)` |
| 112 | + |
| 113 | +The sandbox restricts imports, `eval`, `exec`, `open`, and other unsafe builtins. Default timeout is 30 seconds. |
| 114 | + |
| 115 | +## Comparison |
| 116 | + |
| 117 | +| Mode | Agent sees | Best for | |
| 118 | +|------|-----------|----------| |
| 119 | +| Plain | All tools directly | Small APIs (<20 tools) | |
| 120 | +| Search | `search_tools` + `call_tool` | Large APIs (100+ tools) | |
| 121 | +| Plan | `execute_plan` | Multi-step workflows with data dependencies | |
| 122 | +| Code | `execute_code` | Complex logic, iteration, conditionals | |
0 commit comments