@flowapt/flowiq-cli 0.6.5 → 0.6.6

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.
package/README.md CHANGED
@@ -187,8 +187,8 @@ flowiq ct list
187
187
 
188
188
  - **Always `--dry-run` first** on a production agent — it prints added/removed/changed tool names before you commit.
189
189
  - **Destructive pushes are blocked by default**: a push that removes a tool, disables one, or sends an empty `tools[]` (wiping everything) writes nothing and shows you exactly what it would strip — re-run with `--confirm` if intentional. Additive/no-op pushes are unaffected.
190
- - Server-side validation is strict: tool `name` (`^[a-zA-Z0-9_-]{1,64}$`, no duplicates), non-empty `description`, `http(s)` `endpoint`, method `GET/POST/PUT/PATCH/DELETE`, object-typed `parameters`/`headers`/`injected_parameters`, valid `auth_type`/`channels`. Recursive JSON schemas are supported, including arrays of objects and integer/min/max constraints. Bad payloads are rejected before anything writes.
191
- - **Warnings (non-blocking):** unknown keys (likely typos the runtime would silently ignore) and unknown `{{placeholders}}` (they will NOT be substituted at runtime; known values include `organization_id`, `contact_id`, `agent_id`, `contact_whatsapp_id`, `contact_full_name`, `whatsapp_message_id`, `supabase_anon_key`, `openai_api_key`).
190
+ - Server-side validation is strict: tool `name` (`^[a-zA-Z0-9_-]{1,64}$`, no duplicates or built-in collisions), non-empty `description`, `http(s)` `endpoint`, method `GET/POST/PUT/PATCH/DELETE`, scalar headers, object-typed `parameters`/`injected_parameters`, valid auth/channels, timeout and response caps. Recursive schemas support strict nested objects, typed arrays, enums and numeric/string/item limits. Unknown tool/schema keys are rejected before anything writes.
191
+ - **Warnings (non-blocking):** an object with properties but no required fields. Unknown `{{placeholder}}` values are hard errors; injected parameters may additionally reference a declared top-level model parameter. Known runtime values include `organization_id`, `contact_id`, `agent_id`, `contact_whatsapp_id`, `contact_full_name`, `whatsapp_message_id`, `text`, `unique_message_id`, `unix_timestamp`, `operation_idempotency_key`, `supabase_anon_key`, and `openai_api_key`.
192
192
  - **Retailer gateway credential:** `{{retailer_tools_internal_key}}` is super-admin-only and resolves only as the `x-api-key` value for `https://express.chatcart.io/retailer-tools/*` (or loopback in local tests). Validation and runtime both reject putting it in a body or sending it to any other host.
193
193
  - `--agent` + filenames behave like `prompts`/`knowledge`; the file carries `agent_id`, so `push` targets the agent it was pulled from.
194
194
 
@@ -1227,6 +1227,8 @@ flowiq agent config <organization_id> --use-settings-prompt --model gpt-5.6-luna
1227
1227
  --rename Zara --tool woo_order_build=true --tool view_cart_tool=true --discount true
1228
1228
  flowiq agent config <organization_id> --test-contact-number 27000000001 --test-contact-name "QA Bot"
1229
1229
  flowiq agent config <organization_id> --model gpt-5.6-luna --reasoning-effort high
1230
+ flowiq agent config <organization_id> --disable-base-tool get_product_info
1231
+ flowiq agent config <organization_id> --enable-base-tool get_product_info
1230
1232
  ```
1231
1233
 
1232
1234
  Settable: `settings.use_settings_prompt`, `settings.model`,
@@ -1240,6 +1242,10 @@ the tool-flag columns (`woo_order_build`, `woo_tip_field`, `woo_order_note_field
1240
1242
  (`settings.test_contact_number` / `settings.test_contact_name`). Anything else is
1241
1243
  rejected; every change is reported before → after.
1242
1244
 
1245
+ `--disable-base-tool` / `--enable-base-tool` can be repeated. They manage only the
1246
+ allowlisted discovery/commerce built-ins; opt-out, human handover and channel-send
1247
+ tools cannot be disabled.
1248
+
1243
1249
  **`--tool product_lookup=true` (added 11 Aug 2026).** Turns on the `product_lookup`
1244
1250
  tool: a typo-tolerant **pg_trgm fuzzy match on `product_title`** (plus badge/tag
1245
1251
  search), as opposed to `get_product_info`, which is **semantic**. This matters far
@@ -1378,3 +1384,8 @@ interactive terminal. Silence it with `FLOWIQ_NO_UPDATE_CHECK=1`.
1378
1384
 
1379
1385
  UNLICENSED. Internal staff tool — install requires a valid `fiq_staff_…`
1380
1386
  key issued by a FlowIQ super-admin.
1387
+
1388
+ ChatCart rollout: Pick n Pay uses retailer `pnp` and the private connection link.
1389
+ Enable its gateway before adding it to the agent tools. Cart retries use
1390
+ `{{operation_idempotency_key}}`; configure `timeout_ms` up to 30000 and
1391
+ `max_response_bytes` up to 1048576 for bounded batch results.
package/TEAM-GUIDE.md CHANGED
@@ -98,6 +98,7 @@ When you see it, run `npm i -g @flowapt/flowiq-cli` — a stale version also mea
98
98
  | See an org's agents / create one | `flowiq agent list <org_id>` / `flowiq agent create <org_id> --name "…"` — a new agent arrives ready to work (gpt-5.6-luna, high reasoning, prompt switched ON); no follow-up `agent config` needed |
99
99
  | Change agent model / tool flags | `flowiq agent config <org_id> --model … --tool view_cart_tool=true` |
100
100
  | Set the house model + reasoning tier | `flowiq agent config <org_id> --model gpt-5.6-luna --reasoning-effort high` |
101
+ | Remove a conflicting built-in tool from one agent | `flowiq agent config <org_id> --disable-base-tool get_product_info` (repeatable; safety/delivery tools cannot be disabled) |
101
102
  | Agent says an in-stock product "isn't showing" | `flowiq agent config <org_id> --tool collapse_product_variants=true` — the search cap counts VARIANT rows until this is on |
102
103
  | Agent can't quote ANY price / "I can't pull the live menu" | `flowiq agent config <org_id> --tool product_lookup=true` — name-based fuzzy lookup that works without embeddings or a live OpenAI key (semantic `get_product_info` needs both) |
103
104
  | Talk to the live agent safely (no real WhatsApp ever sent) | `flowiq test send <org_id> "hi, do you sell X?"` |
@@ -179,12 +180,15 @@ flowiq ct push <slug>
179
180
  ```
180
181
 
181
182
  Custom tools define real HTTP calls the agent can execute, so the server
182
- validates hard (names, URLs, methods, parameter shapes) and warns about typo'd
183
- keys or `{{placeholders}}` it doesn't recognise. Take the warnings seriously.
184
- Nested object/array schemas are supported. For ChatCart retailer tools, use
183
+ validates names, URLs, methods and parameter shapes. Unknown keys and unresolved
184
+ `{{placeholders}}` block the write; an
185
+ object with no required fields remains a warning because it can be intentional.
186
+ Nested object/array schemas are strict and supported. For ChatCart retailer tools, use
185
187
  `{{retailer_tools_internal_key}}` only as the `x-api-key` auth value on the
186
188
  trusted `express.chatcart.io/retailer-tools/*` gateway; org/contact identity is
187
- injected server-side and mutations use `{{whatsapp_message_id}}` for idempotency.
189
+ injected server-side and mutations use `{{operation_idempotency_key}}` for stable,
190
+ operation-scoped idempotency. Batch independent product requests in one
191
+ `search_retailer_products.queries` array (1–12) instead of repeated search calls.
188
192
 
189
193
  ### Example: tag a segment of contacts (Advanced Tagging)
190
194
 
@@ -325,3 +329,8 @@ Three things worth knowing:
325
329
  | "Organization has no active_whatsapp_agent" | Target the agent directly: `--agent <id>` (ids from `flowiq agent list <org_id>`) |
326
330
  | Login browser page says the code expired | Codes live 10 minutes — just re-run `flowiq auth login` |
327
331
  | Pushed the wrong thing | Everything is pull→push, so re-pull an older copy if you have one, or check with Matt — server logs record every push with who/what/when |
332
+
333
+ ChatCart rollout: Pick n Pay uses retailer `pnp` and the private connection link.
334
+ Enable its gateway before adding it to the agent tools. Cart retries use
335
+ `{{operation_idempotency_key}}`; configure `timeout_ms` up to 30000 and
336
+ `max_response_bytes` up to 1048576 for bounded batch results.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowapt/flowiq-cli",
3
- "version": "0.6.5",
3
+ "version": "0.6.6",
4
4
  "description": "Command-line tool for FlowIQ staff: round-trip agent prompts, questionnaires, fine-tuning, pin-board tasks, webhooks, templates, agent-updates, chat exports, and live agent testing without ever touching service-role credentials.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,6 +23,12 @@ export function collectTool(val, acc) {
23
23
  return acc;
24
24
  }
25
25
 
26
+ export function collectToolName(val, acc) {
27
+ acc = acc || [];
28
+ acc.push(val);
29
+ return acc;
30
+ }
31
+
26
32
  function printSnapshot(title, snap) {
27
33
  console.log(` ${title}:`);
28
34
  for (const [k, v] of Object.entries(snap)) {
@@ -47,6 +53,12 @@ export async function config(orgId, opts = {}) {
47
53
  if (Object.keys(settings).length) body.settings = settings;
48
54
  if (opts.rename !== undefined) body.name = opts.rename;
49
55
  if (opts.discount !== undefined) body.discount_enabled = parseBool(opts.discount, "--discount");
56
+ if (opts.disableBaseTool?.length || opts.enableBaseTool?.length) {
57
+ body.base_tool_changes = {
58
+ disable: opts.disableBaseTool || [],
59
+ enable: opts.enableBaseTool || [],
60
+ };
61
+ }
50
62
 
51
63
  if (opts.tool && opts.tool.length) {
52
64
  const flags = {};
@@ -63,7 +75,7 @@ export async function config(orgId, opts = {}) {
63
75
  }
64
76
 
65
77
  const hasWrite =
66
- body.settings || body.name !== undefined || body.tool_flags || body.discount_enabled !== undefined;
78
+ body.settings || body.name !== undefined || body.tool_flags || body.base_tool_changes || body.discount_enabled !== undefined;
67
79
 
68
80
  // No write flags → just show current config.
69
81
  if (!hasWrite) {
@@ -76,7 +88,7 @@ export async function config(orgId, opts = {}) {
76
88
  }
77
89
  console.log(`${resp.organization_name} → agent ${resp.agent_id}${resp.is_active === false ? " [NON-active]" : ""}`);
78
90
  printSnapshot("current", resp.current);
79
- console.log("\n(pass --use-settings-prompt / --model / --reasoning-effort / --rename / --tool / --discount / --test-contact-number / --test-contact-name to change)");
91
+ console.log("\n(pass --use-settings-prompt / --model / --reasoning-effort / --rename / --tool / --disable-base-tool / --enable-base-tool / --discount / --test-contact-number / --test-contact-name to change)");
80
92
  return;
81
93
  }
82
94
 
package/src/index.js CHANGED
@@ -328,6 +328,8 @@ export function run(argv) {
328
328
  .option("--discount [bool]", "agent.discount.enabled (true if bare)")
329
329
  .option("--test-contact-number <number>", "settings.test_contact_number — the contact `flowiq test` uses (use a FAKE number; \"\" clears it → synthetic fallback)")
330
330
  .option("--test-contact-name <name>", "settings.test_contact_name — display name for the test contact (\"\" clears it)")
331
+ .option("--disable-base-tool <name>", "hide a disableable built-in tool from this agent (repeatable)", agentConfigCmd.collectToolName, [])
332
+ .option("--enable-base-tool <name>", "restore a previously disabled built-in tool (repeatable)", agentConfigCmd.collectToolName, [])
331
333
  .action((orgId, opts) => agentConfigCmd.config(orgId, opts));
332
334
 
333
335
  // agent-updates (pending client change-requests + chat context; pull + resolve)