client-finder/references/query-expansion-spec.md

105 lines
3.0 KiB
Markdown
Raw Normal View History

2026-03-11 23:36:43 +00:00
# Client-Finder Query Expansion Spec (MVP)
## Goal
Implement query expansion inside `client-finder` before calling `/ecom/cold-outreach/run-flow`.
## Scope
- Only changes inside `agent-sandbox/agent_app/skills/client-finder`.
- No new backend API.
- Expansion failure should fallback to original raw query A.
## Input
- `client_key` (required, from workflow input_data)
- `query` (required)
- `country` (optional, default `us`)
- `QUERY_EXPANSION_JSON` (optional, must be valid JSON if provided)
## Expansion Flow
1. Normalize raw query.
- trim spaces
- remove optional prefix `cold-outreach:`
2. Resolve expansion source.
- If `QUERY_EXPANSION_JSON` is provided:
- accept object or array
- must produce non-empty `expandedQueries` + non-empty `primaryQuery`
- source = `llm`
- Else use built-in rule expansion
- source = `rule`
3. Validate expansion.
- `expandedQueries.length >= 1`
- `primaryQuery` non-empty
- dedupe candidates case-insensitively
4. Execute workflow with `primaryQuery`.
- exchange `client_key` first via `POST /auth/skill-credit/session`
- `POST /auth/skill-credit/session`
- `POST /ecom/cold-outreach/run-flow`
- return accepted immediately after `workflowId` is received
## Fallback Policy
- If expansion parsing/validation fails, use normalized raw query A as `primaryQuery`.
- Set:
- `expansionStatus = "failed"`
- `expansionSource = "raw_query"`
- `usedFallbackQuery = true`
- `expansionError` with failure reason
- Continue to run cold-outreach.
## Output Contract
Always output strict JSON following `../output_schema.json`.
Success example:
```json
{
"status": "success",
"error": null,
"inputQuery": "coffee",
"expandedQueries": ["coffee shop US", "coffee roastery US"],
"primaryQuery": "coffee shop US",
"expansionStatus": "success",
"expansionSource": "llm",
"expansionError": null,
"usedFallbackQuery": false,
"runId": "",
"workflowId": "outreach_xxx",
"workflowStatus": "accepted",
"businessesCount": 0,
"contactsCount": 0,
"uniqueContactDomains": 0,
"billingReserveStatus": "SKIPPED",
"billingFinalizeStatus": "SKIPPED"
}
```
Expansion fallback example:
```json
{
"status": "success",
"error": null,
"inputQuery": "coffee",
"expandedQueries": ["coffee"],
"primaryQuery": "coffee",
"expansionStatus": "failed",
"expansionSource": "raw_query",
"expansionError": "query expansion failed: expandedQueries is empty; fallback to raw query",
"usedFallbackQuery": true,
"runId": "",
"workflowId": "outreach_xxx",
"workflowStatus": "accepted",
"businessesCount": 0,
"contactsCount": 0,
"uniqueContactDomains": 0,
"billingReserveStatus": "SKIPPED",
"billingFinalizeStatus": "SKIPPED"
}
```
## Acceptance
1. Expansion success -> call cold-outreach using `primaryQuery` (webhook is key-bound).
2. Expansion failure -> fallback to raw query and continue run when raw query is available.
3. If normalized raw query is empty, return failed JSON and exit non-zero.
4. On start success, return immediate `workflowStatus = "accepted"` (no local polling).
5. No prose output mixed with JSON.