refactor: simplify index.ts — use ctx object instead of 8-param helpers

Replace createFailedResult/createSuccessResult (8+ params each) with
a single result() builder + ctx spread. Default country to 'US'.
-117 lines, same output_schema.json contract.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ywkj 2026-03-19 07:16:46 +08:00
parent e7d9e972d4
commit 06c5c302e9
2 changed files with 42 additions and 117 deletions

View File

@ -87,7 +87,7 @@ async function main(): Promise<void> {
if (parsed.clientKey) process.env.CLIENT_KEY = parsed.clientKey; if (parsed.clientKey) process.env.CLIENT_KEY = parsed.clientKey;
if (parsed.authBase) process.env.AUTH_BASE = parsed.authBase; if (parsed.authBase) process.env.AUTH_BASE = parsed.authBase;
const result = await runClientFinder(parsed.query, parsed.country, parsed.dryRun); const result = await runClientFinder(parsed.query, parsed.country || 'US', parsed.dryRun);
console.log(JSON.stringify(result, null, 2)); console.log(JSON.stringify(result, null, 2));
} }

View File

@ -3,121 +3,78 @@ import { createSkillClient } from '@clawd/auth-runtime';
import { normalizeQuery, resolveExpansion } from './expansion.js'; import { normalizeQuery, resolveExpansion } from './expansion.js';
import { startWorkflow } from './workflow.js'; import { startWorkflow } from './workflow.js';
/**
* Main entry point for client-finder skill
*/
export async function runClientFinder( export async function runClientFinder(
query: string, query: string,
country: string, country: string = 'US',
dryRun: boolean = false, dryRun: boolean = false,
): Promise<OutputResult> { ): Promise<OutputResult> {
// Validate query
if (!query) { if (!query) {
return createFailedResult('', 'missing query argument'); return result('failed', { error: 'missing query argument' });
} }
// Normalize query
const rawQuery = normalizeQuery(query); const rawQuery = normalizeQuery(query);
const countryUpper = country.toUpperCase(); const countryUpper = country.toUpperCase();
const countryLower = country.toLowerCase(); const llmExpansion = process.env.QUERY_EXPANSION_JSON || '';
const expansion = resolveExpansion(rawQuery, countryUpper, llmExpansion);
// Resolve expansion // Build expansion context
const queryExpansionJson = process.env.QUERY_EXPANSION_JSON || ''; const ctx: Partial<OutputResult> = {
const expansion = resolveExpansion(rawQuery, countryUpper, queryExpansionJson); inputQuery: rawQuery,
expandedQueries: expansion.expandedQueries,
primaryQuery: expansion.primaryQuery,
expansionStatus: expansion.ok ? 'success' : 'failed',
expansionSource: expansion.expansionSource,
expansionError: expansion.error || null,
usedFallbackQuery: false,
};
let expandedQueries = expansion.expandedQueries; // Handle expansion failure — fallback to raw query
let primaryQuery = expansion.primaryQuery;
let expansionStatus = expansion.ok ? 'success' : ('failed' as const);
let expansionSource = expansion.expansionSource;
let expansionError = expansion.error || '';
let usedFallbackQuery = false;
// Handle expansion failure
if (!expansion.ok) { if (!expansion.ok) {
if (rawQuery) { if (!rawQuery) {
primaryQuery = rawQuery; return result('failed', { ...ctx, error: expansion.error || 'query is empty' });
expandedQueries = [rawQuery];
expansionSource = 'raw_query';
expansionError = `query expansion failed: ${expansion.error}; fallback to raw query`;
usedFallbackQuery = true;
} else {
expansionError = expansionError || 'query expansion failed: primary query is empty';
return createFailedResult(
rawQuery, expansionError, expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
);
} }
ctx.primaryQuery = rawQuery;
ctx.expandedQueries = [rawQuery];
ctx.expansionSource = 'raw_query';
ctx.expansionError = `query expansion failed: ${expansion.error}; fallback to raw query`;
ctx.usedFallbackQuery = true;
} }
// Validate primary query if (!ctx.primaryQuery) {
if (!primaryQuery) { return result('failed', { ...ctx, error: 'primary query is empty after expansion' });
expansionError = expansionError || 'query expansion failed: primary query is empty';
return createFailedResult(
rawQuery, expansionError, expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
);
} }
// Dry run mode
if (dryRun) { if (dryRun) {
return createSuccessResult( return result('success', { ...ctx, workflowStatus: 'dry_run' });
rawQuery, expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
'', 'dry_run',
);
} }
// Create client (validates CLIENT_KEY)
let client; let client;
try { try {
client = createSkillClient(); client = createSkillClient();
} catch (error) { } catch (error) {
return createFailedResult( return result('failed', { ...ctx, error: error instanceof Error ? error.message : String(error) });
rawQuery, error instanceof Error ? error.message : 'failed to create client',
expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
);
} }
// Start workflow const wf = await startWorkflow(client, ctx.primaryQuery, country.toLowerCase());
const workflowResult = await startWorkflow(client, primaryQuery, countryLower);
if (!workflowResult.workflowId) { if (!wf.workflowId) {
return createFailedResult( return result('failed', { ...ctx, error: `start failed: ${wf.error}` });
rawQuery, `start failed: ${workflowResult.error}`,
expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
);
} }
// Return accepted immediately return result('success', { ...ctx, workflowId: wf.workflowId, workflowStatus: 'accepted' });
return createSuccessResult(
rawQuery, expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
'', 'accepted', workflowResult.workflowId,
);
} }
function createFailedResult( function result(status: 'success' | 'failed', overrides: Partial<OutputResult> = {}): OutputResult {
inputQuery: string,
error: string,
expandedQueries: string[] = [],
primaryQuery: string = '',
expansionStatus: 'success' | 'failed' = 'failed',
expansionSource: 'llm' | 'rule' | 'raw_query' | '' = '',
expansionError: string | null = null,
usedFallbackQuery: boolean = false,
): OutputResult {
return { return {
status: 'failed', status,
error: error || null, error: null,
inputQuery, inputQuery: '',
expandedQueries, expandedQueries: [],
primaryQuery, primaryQuery: '',
expansionStatus, expansionStatus: 'failed',
expansionSource, expansionSource: '',
expansionError: expansionError || null, expansionError: null,
usedFallbackQuery, usedFallbackQuery: false,
runId: '', runId: '',
workflowId: '', workflowId: '',
workflowStatus: '', workflowStatus: '',
@ -126,38 +83,6 @@ function createFailedResult(
businessesCount: 0, businessesCount: 0,
contactsCount: 0, contactsCount: 0,
uniqueContactDomains: 0, uniqueContactDomains: 0,
}; ...overrides,
}
function createSuccessResult(
inputQuery: string,
expandedQueries: string[],
primaryQuery: string,
expansionStatus: 'success' | 'failed',
expansionSource: 'llm' | 'rule' | 'raw_query' | '',
expansionError: string | null,
usedFallbackQuery: boolean,
runId: string,
workflowStatus: string,
workflowId: string = '',
): OutputResult {
return {
status: 'success',
error: null,
inputQuery,
expandedQueries,
primaryQuery,
expansionStatus,
expansionSource,
expansionError,
usedFallbackQuery,
runId,
workflowId,
workflowStatus,
billingReserveStatus: 'SKIPPED',
billingFinalizeStatus: 'SKIPPED',
businessesCount: 0,
contactsCount: 0,
uniqueContactDomains: 0,
}; };
} }