refactor: use SkillClient, remove manual auth handling

Replace createEnvConfig/getAccessToken/requestApiWithAutoRefresh
with createSkillClient(). workflow.ts now takes a SkillClient
instead of config+token. Remove EnvConfig extension from types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ywkj 2026-03-18 08:25:09 +08:00
parent 56d3051253
commit e7d9e972d4
3 changed files with 29 additions and 129 deletions

View File

@ -1,20 +1,8 @@
import type { EnvConfig, OutputResult } from './types.js';
import { createEnvConfig as createBaseEnvConfig, getAccessToken } from '@clawd/auth-runtime';
import type { OutputResult } from './types.js';
import { createSkillClient } from '@clawd/auth-runtime';
import { normalizeQuery, resolveExpansion } from './expansion.js';
import { startWorkflow } from './workflow.js';
/**
* Create client-finder specific environment configuration
* Extends the shared auth config with skill-specific fields
*/
function createEnvConfig(): EnvConfig {
const baseConfig = createBaseEnvConfig();
return {
...baseConfig,
queryExpansionJson: process.env.QUERY_EXPANSION_JSON || '',
};
}
/**
* Main entry point for client-finder skill
*/
@ -23,8 +11,6 @@ export async function runClientFinder(
country: string,
dryRun: boolean = false,
): Promise<OutputResult> {
const config = createEnvConfig();
// Validate query
if (!query) {
return createFailedResult('', 'missing query argument');
@ -36,11 +22,8 @@ export async function runClientFinder(
const countryLower = country.toLowerCase();
// Resolve expansion
const expansion = resolveExpansion(
rawQuery,
countryUpper,
config.queryExpansionJson,
);
const queryExpansionJson = process.env.QUERY_EXPANSION_JSON || '';
const expansion = resolveExpansion(rawQuery, countryUpper, queryExpansionJson);
let expandedQueries = expansion.expandedQueries;
let primaryQuery = expansion.primaryQuery;
@ -60,14 +43,8 @@ export async function runClientFinder(
} else {
expansionError = expansionError || 'query expansion failed: primary query is empty';
return createFailedResult(
rawQuery,
expansionError,
expandedQueries,
primaryQuery,
expansionStatus,
expansionSource,
expansionError,
usedFallbackQuery,
rawQuery, expansionError, expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
);
}
}
@ -76,104 +53,51 @@ export async function runClientFinder(
if (!primaryQuery) {
expansionError = expansionError || 'query expansion failed: primary query is empty';
return createFailedResult(
rawQuery,
expansionError,
expandedQueries,
primaryQuery,
expansionStatus,
expansionSource,
expansionError,
usedFallbackQuery,
rawQuery, expansionError, expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
);
}
// Dry run mode
if (dryRun) {
return createSuccessResult(
rawQuery,
expandedQueries,
primaryQuery,
expansionStatus,
expansionSource,
expansionError,
usedFallbackQuery,
'',
'dry_run',
rawQuery, expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
'', 'dry_run',
);
}
// Validate CLIENT_KEY in live mode
if (!config.clientKey) {
return createFailedResult(
rawQuery,
'missing required env: CLIENT_KEY',
expandedQueries,
primaryQuery,
expansionStatus,
expansionSource,
expansionError,
usedFallbackQuery,
);
}
// Step 1: Exchange CLIENT_KEY for runtime access token
let accessToken = '';
// Create client (validates CLIENT_KEY)
let client;
try {
accessToken = await getAccessToken(dryRun, config);
client = createSkillClient();
} catch (error) {
const errorMsg = error instanceof Error ? error.message : 'failed to exchange skill session token';
return createFailedResult(
rawQuery,
errorMsg,
expandedQueries,
primaryQuery,
expansionStatus,
expansionSource,
expansionError,
usedFallbackQuery,
rawQuery, error instanceof Error ? error.message : 'failed to create client',
expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
);
}
// Step 2: Start workflow with runtime access token
const workflowResult = await startWorkflow(
config,
dryRun,
accessToken,
primaryQuery,
countryLower,
);
// Start workflow
const workflowResult = await startWorkflow(client, primaryQuery, countryLower);
if (!workflowResult.workflowId) {
return createFailedResult(
rawQuery,
`start failed: ${workflowResult.error}`,
expandedQueries,
primaryQuery,
expansionStatus,
expansionSource,
expansionError,
usedFallbackQuery,
rawQuery, `start failed: ${workflowResult.error}`,
expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
);
}
// Step 3: Return accepted immediately
// Return accepted immediately
return createSuccessResult(
rawQuery,
expandedQueries,
primaryQuery,
expansionStatus,
expansionSource,
expansionError,
usedFallbackQuery,
'',
'accepted',
workflowResult.workflowId,
rawQuery, expandedQueries, primaryQuery,
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
'', 'accepted', workflowResult.workflowId,
);
}
/**
* Create a failed result
*/
function createFailedResult(
inputQuery: string,
error: string,
@ -205,9 +129,6 @@ function createFailedResult(
};
}
/**
* Create a success result
*/
function createSuccessResult(
inputQuery: string,
expandedQueries: string[],

View File

@ -1,5 +1,3 @@
import type { EnvConfig as BaseEnvConfig } from '@clawd/auth-runtime';
/**
* Query expansion result from LLM or rule-based logic
*/
@ -45,10 +43,3 @@ export interface OutputResult {
uniqueContactDomains: number;
}
/**
* Client-finder specific environment configuration
* Extends the shared auth config with skill-specific fields
*/
export interface EnvConfig extends BaseEnvConfig {
queryExpansionJson: string;
}

View File

@ -1,5 +1,4 @@
import { requestApiWithAutoRefresh } from '@clawd/auth-runtime';
import type { EnvConfig as AuthEnvConfig } from '@clawd/auth-runtime';
import type { SkillClient } from '@clawd/auth-runtime';
import { WorkflowStartResponse } from './types.js';
/**
@ -18,26 +17,15 @@ export function parseWorkflowId(responseBody: string): string {
* Start cold outreach workflow
*/
export async function startWorkflow(
config: AuthEnvConfig,
dryRun: boolean,
accessToken: string,
client: SkillClient,
query: string,
country: string,
): Promise<{ workflowId: string; error: string }> {
const payload = JSON.stringify({
const result = await client.post('/ecom/cold-outreach/run-flow', {
query,
country,
});
const result = await requestApiWithAutoRefresh(
'POST',
`${config.authBase}/ecom/cold-outreach/run-flow`,
dryRun,
config,
payload,
accessToken,
);
if (result.status < 200 || result.status >= 300) {
const error = parseError(result.body);
return {