|
19 | 19 | _get_tool_registry, |
20 | 20 | _set_client_defaults, |
21 | 21 | _set_otel_exporter, |
| 22 | + _tool_registry, |
22 | 23 | ) |
23 | 24 | from .utils import generate_id, json_serializable |
24 | 25 |
|
@@ -164,6 +165,57 @@ def _do_register() -> None: |
164 | 165 |
|
165 | 166 | threading.Thread(target=_do_register, daemon=True, name="lightrace-register").start() |
166 | 167 |
|
| 168 | + def register_tools(self, *tools: Any) -> None: |
| 169 | + """Register tools for invocation from the dashboard. |
| 170 | +
|
| 171 | + Accepts LangChain BaseTool objects or plain callables. |
| 172 | + After registration, re-syncs with the backend via HTTP. |
| 173 | + """ |
| 174 | + from .utils import build_json_schema |
| 175 | + |
| 176 | + for t in tools: |
| 177 | + if hasattr(t, "name") and hasattr(t, "args_schema"): |
| 178 | + name = t.name |
| 179 | + func = getattr(t, "coroutine", None) or getattr(t, "func", None) |
| 180 | + if func is None: |
| 181 | + func = getattr(t, "_arun", None) or getattr(t, "_run", None) |
| 182 | + if func is None: |
| 183 | + logger.warning("Cannot extract callable from tool %r — skipping", name) |
| 184 | + continue |
| 185 | + |
| 186 | + input_schema = None |
| 187 | + args_schema = getattr(t, "args_schema", None) |
| 188 | + if args_schema is not None: |
| 189 | + try: |
| 190 | + input_schema = args_schema.model_json_schema() |
| 191 | + except Exception: |
| 192 | + try: |
| 193 | + input_schema = args_schema.schema() |
| 194 | + except Exception: |
| 195 | + pass |
| 196 | + |
| 197 | + description = getattr(t, "description", None) |
| 198 | + _tool_registry[name] = { |
| 199 | + "func": func, |
| 200 | + "input_schema": input_schema, |
| 201 | + "description": description, |
| 202 | + } |
| 203 | + logger.debug("Registered LangChain tool: %s", name) |
| 204 | + |
| 205 | + elif callable(t): |
| 206 | + name = getattr(t, "__name__", str(t)) |
| 207 | + _tool_registry[name] = { |
| 208 | + "func": t, |
| 209 | + "input_schema": build_json_schema(t), |
| 210 | + "description": None, |
| 211 | + } |
| 212 | + logger.debug("Registered callable tool: %s", name) |
| 213 | + else: |
| 214 | + logger.warning("Cannot register tool %r — not a callable or BaseTool", t) |
| 215 | + |
| 216 | + if _tool_registry and self._enabled: |
| 217 | + self._register_tools_http() |
| 218 | + |
167 | 219 | # ── Flush / shutdown ────────────────────────────────────────────── |
168 | 220 |
|
169 | 221 | def flush(self) -> None: |
|
0 commit comments