@melaya/runner 1.0.86 → 1.0.88

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -162,10 +162,30 @@ def _build_agent():
162
162
  # mobile only. These POST to /api/v1/private/assistant-tool + /phone/command
163
163
  # with MELAYA_API_KEY; tenant scope is enforced server-side.
164
164
  categories = ["melaya_agent"] + (["phone"] if phone_enabled else [])
165
+ # Connector tool sets the user enabled for THIS chat (any service — odoo,
166
+ # stripe, shopify, …). When present, use a LAZY toolkit: base tools stay
167
+ # active+pinned, and the connectors' tools are deferred + discoverable via
168
+ # search_tools/activate_tool (≤25 active) so even a 178-tool connector never
169
+ # explodes context. Bounded to the selected services so the model can't reach
170
+ # a connector the user didn't enable / has no creds for.
171
+ connector_services = [s.strip().lower() for s in os.environ.get("MEL_ASSISTANT_CONNECTORS", "").split(",") if s.strip()]
172
+ # Self-arm the write-approval gate whenever connectors are active, so it can't
173
+ # be silently OFF on an older runner build that didn't set this env. Writes
174
+ # then ALWAYS require the in-chat approval card (fail-safe).
175
+ if connector_services and not os.environ.get("MEL_ASSISTANT_CONNECTOR_HITL"):
176
+ os.environ["MEL_ASSISTANT_CONNECTOR_HITL"] = "1"
165
177
  try:
166
- toolkit = build_toolkit(categories=categories)
178
+ if connector_services:
179
+ from shared.orchestration.lazy_registry import build_lazy_toolkit
180
+ toolkit = build_lazy_toolkit(
181
+ active_categories=categories,
182
+ include_categories=categories + connector_services,
183
+ budget=int(os.environ.get("MEL_LAZY_BUDGET", "25")),
184
+ )
185
+ else:
186
+ toolkit = build_toolkit(categories=categories)
167
187
  except Exception as exc:
168
- _log(f"build_toolkit({categories}) failed: {exc}; retrying melaya_agent only")
188
+ _log(f"toolkit build failed (connectors={connector_services}): {exc}; retrying melaya_agent only")
169
189
  try:
170
190
  toolkit = build_toolkit(categories=["melaya_agent"])
171
191
  except Exception:
@@ -194,6 +214,14 @@ def _build_agent():
194
214
  "blocked; only then report what you did and what (if anything) is blocked.\n"
195
215
  if phone_enabled else ""
196
216
  )
217
+ connector_rule = (
218
+ "- You also have CONNECTOR tools the user enabled (" + ", ".join(connector_services) + "). "
219
+ "Their tools are not all loaded upfront — call search_tools(query=...) to find the "
220
+ "right one for the user's question, then activate_tool(name=...) to load it, then call "
221
+ "it. Prefer specific tools (e.g. odoo_sale_order_list) over generic ones. Never invent "
222
+ "data — read it from the connector.\n"
223
+ if connector_services else ""
224
+ )
197
225
  sys_prompt = (
198
226
  "You are the Melaya Assistant, the in-app copilot of the Melaya "
199
227
  "agent-orchestration platform. You have READ-ONLY tools over the data "
@@ -205,6 +233,7 @@ def _build_agent():
205
233
  "templates or evals — never invent numbers. For cost, melaya_cost_summary "
206
234
  "supports dimension='pipeline' to find which pipeline cost the most.\n"
207
235
  + phone_rule
236
+ + connector_rule
208
237
  + "- Be concise and concrete; format small tables or bullet lists when comparing items.\n"
209
238
  "- If a question is outside the platform, answer normally without tools.\n"
210
239
  + (f"- Answer in the user's language: {language}.\n" if language and language != "en" else "")
@@ -893,7 +893,13 @@ export async function connect(opts) {
893
893
  MEL_ASSISTANT_MODEL: String(payload.model || ""),
894
894
  MEL_ASSISTANT_LANGUAGE: String(payload.language || "en"),
895
895
  MEL_ASSISTANT_SURFACE: String(payload.surface || ""),
896
- // Per-user creds (incl. MELAYA_API_KEY for the tenant-gated tool bridge).
896
+ // Connector tool sets the user enabled for this chat (comma-joined service
897
+ // ids). The host seeds a lazy toolkit from these so ANY connector's tools
898
+ // are reachable without exploding context.
899
+ MEL_ASSISTANT_CONNECTORS: Array.isArray(payload.connectors) ? payload.connectors.join(",") : "",
900
+ // Gate write connector-tools behind the in-chat approval card (fail-safe).
901
+ MEL_ASSISTANT_CONNECTOR_HITL: Array.isArray(payload.connectors) && payload.connectors.length ? "1" : "",
902
+ // Per-user creds (incl. MELAYA_API_KEY + the selected connectors' env).
897
903
  ...(payload.credentials || {}),
898
904
  };
899
905
  const proc = spawn(envResult.pythonPath, ["-u", stagedHost], { cwd: workDir, env, stdio: ["pipe", "pipe", "pipe"] });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melaya/runner",
3
- "version": "1.0.86",
3
+ "version": "1.0.88",
4
4
  "description": "Run Melaya AI pipelines locally with your own LM Studio or Ollama models",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,