@f-o-h/cli 0.1.63 → 0.1.65
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 +10 -0
- package/dist/foh.js +77 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -159,6 +159,16 @@ create ephemeral orgs only for explicit lifecycle tests; do not create paid
|
|
|
159
159
|
phone resources unless a BYON/customer-owned or operator-approved paid lane is
|
|
160
160
|
selected.
|
|
161
161
|
|
|
162
|
+
For no-spend evals, inspect reusable state before creating anything:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
foh org status --json
|
|
166
|
+
foh agent list --json
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
If a reusable eval agent already exists, configure and prove that agent rather
|
|
170
|
+
than creating a second bronze-tier agent.
|
|
171
|
+
|
|
162
172
|
## Common Missions
|
|
163
173
|
|
|
164
174
|
| Mission | Command |
|
package/dist/foh.js
CHANGED
|
@@ -32877,7 +32877,7 @@ var StdioServerTransport = class {
|
|
|
32877
32877
|
};
|
|
32878
32878
|
|
|
32879
32879
|
// src/lib/cli-version.ts
|
|
32880
|
-
var CLI_VERSION = "0.1.
|
|
32880
|
+
var CLI_VERSION = "0.1.65";
|
|
32881
32881
|
|
|
32882
32882
|
// src/commands/mcp-serve.ts
|
|
32883
32883
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
@@ -34548,6 +34548,51 @@ function isMissingAgentTestsError(error2) {
|
|
|
34548
34548
|
].filter((value) => value !== void 0 && value !== null).join(" ").toLowerCase();
|
|
34549
34549
|
return text.includes("no tests found") || text.includes("tests_not_found") || text.includes("agent_tests_not_configured");
|
|
34550
34550
|
}
|
|
34551
|
+
function errorReasonCode(error2) {
|
|
34552
|
+
const detail = error2.detail;
|
|
34553
|
+
const code = detail && typeof detail.code === "string" ? detail.code : void 0;
|
|
34554
|
+
const reasonCode = detail && typeof detail.reason_code === "string" ? detail.reason_code : void 0;
|
|
34555
|
+
return error2.reasonCode ?? reasonCode ?? code;
|
|
34556
|
+
}
|
|
34557
|
+
function isAgentLimitReachedError(error2) {
|
|
34558
|
+
const reasonCode = errorReasonCode(error2);
|
|
34559
|
+
const text = [
|
|
34560
|
+
reasonCode,
|
|
34561
|
+
error2.error,
|
|
34562
|
+
error2.detail?.error,
|
|
34563
|
+
error2.detail?.message
|
|
34564
|
+
].filter((value) => value !== void 0 && value !== null).join(" ").toLowerCase();
|
|
34565
|
+
return text.includes("agent_limit_reached") || text.includes("agent limit reached");
|
|
34566
|
+
}
|
|
34567
|
+
function shouldReuseSingleAgentForEval() {
|
|
34568
|
+
return Boolean(process.env.FOH_EXTERNAL_AGENT_RUN_DIR) && isNoSpendPolicy();
|
|
34569
|
+
}
|
|
34570
|
+
async function rebaseEvalAgentDraftFromTemplate(params) {
|
|
34571
|
+
const preview = await apiFetch(`/v1/console/templates/${params.templateId}`, {
|
|
34572
|
+
orgId: params.orgId,
|
|
34573
|
+
apiUrlOverride: params.apiUrlOverride
|
|
34574
|
+
});
|
|
34575
|
+
const draft = preview.template?.draft_config;
|
|
34576
|
+
if (!draft || typeof draft !== "object" || Array.isArray(draft)) {
|
|
34577
|
+
throw new FohError({
|
|
34578
|
+
step: "create_agent",
|
|
34579
|
+
error: "Template preview did not return a draft_config for eval reuse.",
|
|
34580
|
+
remediation: `Run: foh templates show --template ${params.templateId} --json, then retry setup.`,
|
|
34581
|
+
reasonCode: "eval_agent_template_rebase_failed"
|
|
34582
|
+
});
|
|
34583
|
+
}
|
|
34584
|
+
await apiFetch(`/v1/console/agents/${params.agentId}/draft`, {
|
|
34585
|
+
method: "PATCH",
|
|
34586
|
+
body: JSON.stringify({ ...draft, name: params.agentName }),
|
|
34587
|
+
orgId: params.orgId,
|
|
34588
|
+
apiUrlOverride: params.apiUrlOverride
|
|
34589
|
+
});
|
|
34590
|
+
return {
|
|
34591
|
+
template_rebased: true,
|
|
34592
|
+
template_id: params.templateId,
|
|
34593
|
+
draft_keys: Object.keys(draft).sort()
|
|
34594
|
+
};
|
|
34595
|
+
}
|
|
34551
34596
|
function buildMissingOptionsPlan(missing, opts) {
|
|
34552
34597
|
const missingFlags = missing.map(optionNameToFlag);
|
|
34553
34598
|
const signInUrl = buildConsoleSignInUrl(resolveConsoleBaseUrl(opts.consoleUrl));
|
|
@@ -34903,7 +34948,8 @@ function registerSetup(program3) {
|
|
|
34903
34948
|
orgId: opts.org,
|
|
34904
34949
|
apiUrlOverride: opts.apiUrl
|
|
34905
34950
|
});
|
|
34906
|
-
const
|
|
34951
|
+
const existingAgents = Array.isArray(agents.agents) ? agents.agents : [];
|
|
34952
|
+
const existing = existingAgents.find((agent) => agent.name === opts.agentName);
|
|
34907
34953
|
if (existing) {
|
|
34908
34954
|
agentId = existing.id;
|
|
34909
34955
|
return { step: "create_agent", status: "skipped", detail: "name already exists" };
|
|
@@ -34926,12 +34972,39 @@ function registerSetup(program3) {
|
|
|
34926
34972
|
return { step: "create_agent", status: "done", detail: { agent_id: agentId, path: "template_apply" } };
|
|
34927
34973
|
} catch (error2) {
|
|
34928
34974
|
if (!(error2 instanceof FohError)) throw error2;
|
|
34975
|
+
if (isAgentLimitReachedError(error2) && shouldReuseSingleAgentForEval() && existingAgents.length === 1) {
|
|
34976
|
+
const reusable = existingAgents[0];
|
|
34977
|
+
const rebase = await rebaseEvalAgentDraftFromTemplate({
|
|
34978
|
+
agentId: reusable.id,
|
|
34979
|
+
agentName: opts.agentName,
|
|
34980
|
+
templateId: opts.agentTemplate,
|
|
34981
|
+
orgId: opts.org,
|
|
34982
|
+
apiUrlOverride: opts.apiUrl
|
|
34983
|
+
});
|
|
34984
|
+
agentId = reusable.id;
|
|
34985
|
+
return {
|
|
34986
|
+
step: "create_agent",
|
|
34987
|
+
status: "skipped",
|
|
34988
|
+
detail: {
|
|
34989
|
+
reason_code: "eval_agent_limit_reuse_existing_agent",
|
|
34990
|
+
original_reason_code: errorReasonCode(error2) ?? "agent_limit_reached",
|
|
34991
|
+
lifecycle_strategy: "reuse_existing_eval_state",
|
|
34992
|
+
desired_agent_name: opts.agentName,
|
|
34993
|
+
reused_agent_id: reusable.id,
|
|
34994
|
+
reused_agent_name: reusable.name,
|
|
34995
|
+
...rebase,
|
|
34996
|
+
operator_note: "External-agent no-spend eval reused the single existing agent and rebased its draft onto the requested template instead of creating a second bronze-tier agent."
|
|
34997
|
+
}
|
|
34998
|
+
};
|
|
34999
|
+
}
|
|
34929
35000
|
throw new FohError({
|
|
34930
35001
|
step: "create_agent",
|
|
34931
35002
|
error: `Template apply failed: ${error2.error}`,
|
|
34932
35003
|
remediation: error2.remediation,
|
|
34933
35004
|
statusCode: error2.statusCode,
|
|
34934
|
-
detail: error2.detail
|
|
35005
|
+
detail: error2.detail,
|
|
35006
|
+
reasonCode: errorReasonCode(error2),
|
|
35007
|
+
nextCommands: error2.nextCommands
|
|
34935
35008
|
});
|
|
34936
35009
|
}
|
|
34937
35010
|
});
|
|
@@ -40328,7 +40401,7 @@ async function executeExternalAgentExecutorPlan(plan, options = {}) {
|
|
|
40328
40401
|
var DEFAULT_PROMPT_VERSION = "blank-setup.v1";
|
|
40329
40402
|
var DEFAULT_BATCH_MODELS = "openai/codex,anthropic/claude,cursor/agent";
|
|
40330
40403
|
var PROMPTS = {
|
|
40331
|
-
"blank-setup.v1": "Go to https://frontofhouse.okii.uk. Use only public docs, public API docs, and the public npm CLI package. Always invoke the CLI with `npx --yes @f-o-h/cli@latest ...`; do not use unpinned `npx @f-o-h/cli ...`, because cached older packages can produce invalid evidence. Install or verify the FOH CLI, authenticate or reach a deterministic auth blocker, then create or configure a Front Of House voice agent and website widget. Prefer the certification-oriented buyer templates: run `npx --yes @f-o-h/cli@latest templates list --category buyer --json` and use `UK Buyer Qualification` or `Viewing Booking` when available; do not use a greeting-only template for proof/certification. Prefer `npx --yes @f-o-h/cli@latest setup --phone-mode observe` for the free scaffold path: agent, widget, voice config, smoke test, certification, and publish readiness together. Treat phone-number purchasing as an explicit paid/scarce contact-path step, not part of high-volume eval setup. If `FOH_CLI_SPEND_POLICY=no_spend` is active and a command returns `paid_resource_blocked_by_spend_policy`, do not try to bypass it; continue widget/setup proof and report that exact reason code for the phone path. If the customer/operator explicitly owns a number and asks for real PSTN proof, use `npx --yes @f-o-h/cli@latest provision byon attach --phone-number <e164> --confirm-owned --json`; do not invent ownership or buy a FOH-owned number. Run proof/smoke/certification where available, including widget proof and voice proof. When running more than one `foh prove` mission for the same agent, pass `--proof-cache-dir .foh/proof-cache` so simulation certification can be shared instead of recomputed. If voice proof returns `contact_phone_missing` or `voice_contact_expected_no_spend_hold`, report that exact reason code unless a BYON/customer-approved phone path already exists. If `FOH_EXTERNAL_AGENT_RUN_DIR` is set, write `${FOH_EXTERNAL_AGENT_RUN_DIR}/external-agent-metadata.json` with `schema_version`, `docs_pages_used`, key decisions, and blocker reason codes before finishing. Produce a final evidence summary with commands run, docs used, artifacts created, and any blocker reason codes. Do not assume access to the private source repository.",
|
|
40404
|
+
"blank-setup.v1": "Go to https://frontofhouse.okii.uk. Use only public docs, public API docs, and the public npm CLI package. Always invoke the CLI with `npx --yes @f-o-h/cli@latest ...`; do not use unpinned `npx @f-o-h/cli ...`, because cached older packages can produce invalid evidence. Install or verify the FOH CLI, authenticate or reach a deterministic auth blocker, then create or configure a Front Of House voice agent and website widget. Mass evals reuse existing eval state: run `npx --yes @f-o-h/cli@latest org status --json` and `npx --yes @f-o-h/cli@latest agent list --json` before trying to create a fresh agent; if an existing eval agent is present, configure and prove that agent instead of creating a second bronze-tier agent. Prefer the certification-oriented buyer templates: run `npx --yes @f-o-h/cli@latest templates list --category buyer --json` and use `UK Buyer Qualification` or `Viewing Booking` when available; do not use a greeting-only template for proof/certification. Prefer `npx --yes @f-o-h/cli@latest setup --phone-mode observe` for the free scaffold path: agent, widget, voice config, smoke test, certification, and publish readiness together. Treat phone-number purchasing as an explicit paid/scarce contact-path step, not part of high-volume eval setup. If `FOH_CLI_SPEND_POLICY=no_spend` is active and a command returns `paid_resource_blocked_by_spend_policy`, do not try to bypass it; continue widget/setup proof and report that exact reason code for the phone path. If the customer/operator explicitly owns a number and asks for real PSTN proof, use `npx --yes @f-o-h/cli@latest provision byon attach --phone-number <e164> --confirm-owned --json`; do not invent ownership or buy a FOH-owned number. Run proof/smoke/certification where available, including widget proof and voice proof. When running more than one `foh prove` mission for the same agent, pass `--proof-cache-dir .foh/proof-cache` so simulation certification can be shared instead of recomputed. If voice proof returns `contact_phone_missing` or `voice_contact_expected_no_spend_hold`, report that exact reason code unless a BYON/customer-approved phone path already exists. If `FOH_EXTERNAL_AGENT_RUN_DIR` is set, write `${FOH_EXTERNAL_AGENT_RUN_DIR}/external-agent-metadata.json` with `schema_version`, `docs_pages_used`, key decisions, and blocker reason codes before finishing. Produce a final evidence summary with commands run, docs used, artifacts created, and any blocker reason codes. Do not assume access to the private source repository.",
|
|
40332
40405
|
"debug-proof-failure.v1": "You are given a FOH proof or debug artifact. Use public docs and FOH CLI/API behavior to classify whether the blocker is docs, auth, org setup, agent config, widget, channel, runtime, or product bug. Produce a redacted improvement packet or the exact command needed to produce one. Do not ask the human to interpret logs manually unless no machine-readable artifact exists.",
|
|
40333
40406
|
"knowledge-miss.v1": "A FOH agent failed to answer a business question. Use CLI/API/docs to determine whether this is a knowledge-ingestion issue, retrieval issue, config issue, prompt/behavior issue, or runtime issue. Prefer foh knowledge query, transcript export, replay, and foh bug improve artifacts over screenshots.",
|
|
40334
40407
|
"replay-failure.v1": "You are given a FOH transcript or replay artifact. Use CLI/API/docs to replay or inspect the failed interaction, identify expected vs actual behavior, and produce a scenario-test or improvement-packet candidate."
|