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:
parent
56d3051253
commit
e7d9e972d4
131
src/index.ts
131
src/index.ts
|
|
@ -1,20 +1,8 @@
|
||||||
import type { EnvConfig, OutputResult } from './types.js';
|
import type { OutputResult } from './types.js';
|
||||||
import { createEnvConfig as createBaseEnvConfig, getAccessToken } from '@clawd/auth-runtime';
|
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';
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* Main entry point for client-finder skill
|
||||||
*/
|
*/
|
||||||
|
|
@ -23,8 +11,6 @@ export async function runClientFinder(
|
||||||
country: string,
|
country: string,
|
||||||
dryRun: boolean = false,
|
dryRun: boolean = false,
|
||||||
): Promise<OutputResult> {
|
): Promise<OutputResult> {
|
||||||
const config = createEnvConfig();
|
|
||||||
|
|
||||||
// Validate query
|
// Validate query
|
||||||
if (!query) {
|
if (!query) {
|
||||||
return createFailedResult('', 'missing query argument');
|
return createFailedResult('', 'missing query argument');
|
||||||
|
|
@ -36,11 +22,8 @@ export async function runClientFinder(
|
||||||
const countryLower = country.toLowerCase();
|
const countryLower = country.toLowerCase();
|
||||||
|
|
||||||
// Resolve expansion
|
// Resolve expansion
|
||||||
const expansion = resolveExpansion(
|
const queryExpansionJson = process.env.QUERY_EXPANSION_JSON || '';
|
||||||
rawQuery,
|
const expansion = resolveExpansion(rawQuery, countryUpper, queryExpansionJson);
|
||||||
countryUpper,
|
|
||||||
config.queryExpansionJson,
|
|
||||||
);
|
|
||||||
|
|
||||||
let expandedQueries = expansion.expandedQueries;
|
let expandedQueries = expansion.expandedQueries;
|
||||||
let primaryQuery = expansion.primaryQuery;
|
let primaryQuery = expansion.primaryQuery;
|
||||||
|
|
@ -60,14 +43,8 @@ export async function runClientFinder(
|
||||||
} else {
|
} else {
|
||||||
expansionError = expansionError || 'query expansion failed: primary query is empty';
|
expansionError = expansionError || 'query expansion failed: primary query is empty';
|
||||||
return createFailedResult(
|
return createFailedResult(
|
||||||
rawQuery,
|
rawQuery, expansionError, expandedQueries, primaryQuery,
|
||||||
expansionError,
|
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
|
||||||
expandedQueries,
|
|
||||||
primaryQuery,
|
|
||||||
expansionStatus,
|
|
||||||
expansionSource,
|
|
||||||
expansionError,
|
|
||||||
usedFallbackQuery,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -76,104 +53,51 @@ export async function runClientFinder(
|
||||||
if (!primaryQuery) {
|
if (!primaryQuery) {
|
||||||
expansionError = expansionError || 'query expansion failed: primary query is empty';
|
expansionError = expansionError || 'query expansion failed: primary query is empty';
|
||||||
return createFailedResult(
|
return createFailedResult(
|
||||||
rawQuery,
|
rawQuery, expansionError, expandedQueries, primaryQuery,
|
||||||
expansionError,
|
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
|
||||||
expandedQueries,
|
|
||||||
primaryQuery,
|
|
||||||
expansionStatus,
|
|
||||||
expansionSource,
|
|
||||||
expansionError,
|
|
||||||
usedFallbackQuery,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dry run mode
|
// Dry run mode
|
||||||
if (dryRun) {
|
if (dryRun) {
|
||||||
return createSuccessResult(
|
return createSuccessResult(
|
||||||
rawQuery,
|
rawQuery, expandedQueries, primaryQuery,
|
||||||
expandedQueries,
|
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
|
||||||
primaryQuery,
|
'', 'dry_run',
|
||||||
expansionStatus,
|
|
||||||
expansionSource,
|
|
||||||
expansionError,
|
|
||||||
usedFallbackQuery,
|
|
||||||
'',
|
|
||||||
'dry_run',
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate CLIENT_KEY in live mode
|
// Create client (validates CLIENT_KEY)
|
||||||
if (!config.clientKey) {
|
let client;
|
||||||
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 = '';
|
|
||||||
try {
|
try {
|
||||||
accessToken = await getAccessToken(dryRun, config);
|
client = createSkillClient();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMsg = error instanceof Error ? error.message : 'failed to exchange skill session token';
|
|
||||||
return createFailedResult(
|
return createFailedResult(
|
||||||
rawQuery,
|
rawQuery, error instanceof Error ? error.message : 'failed to create client',
|
||||||
errorMsg,
|
expandedQueries, primaryQuery,
|
||||||
expandedQueries,
|
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
|
||||||
primaryQuery,
|
|
||||||
expansionStatus,
|
|
||||||
expansionSource,
|
|
||||||
expansionError,
|
|
||||||
usedFallbackQuery,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Start workflow with runtime access token
|
// Start workflow
|
||||||
const workflowResult = await startWorkflow(
|
const workflowResult = await startWorkflow(client, primaryQuery, countryLower);
|
||||||
config,
|
|
||||||
dryRun,
|
|
||||||
accessToken,
|
|
||||||
primaryQuery,
|
|
||||||
countryLower,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!workflowResult.workflowId) {
|
if (!workflowResult.workflowId) {
|
||||||
return createFailedResult(
|
return createFailedResult(
|
||||||
rawQuery,
|
rawQuery, `start failed: ${workflowResult.error}`,
|
||||||
`start failed: ${workflowResult.error}`,
|
expandedQueries, primaryQuery,
|
||||||
expandedQueries,
|
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
|
||||||
primaryQuery,
|
|
||||||
expansionStatus,
|
|
||||||
expansionSource,
|
|
||||||
expansionError,
|
|
||||||
usedFallbackQuery,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3: Return accepted immediately
|
// Return accepted immediately
|
||||||
return createSuccessResult(
|
return createSuccessResult(
|
||||||
rawQuery,
|
rawQuery, expandedQueries, primaryQuery,
|
||||||
expandedQueries,
|
expansionStatus, expansionSource, expansionError, usedFallbackQuery,
|
||||||
primaryQuery,
|
'', 'accepted', workflowResult.workflowId,
|
||||||
expansionStatus,
|
|
||||||
expansionSource,
|
|
||||||
expansionError,
|
|
||||||
usedFallbackQuery,
|
|
||||||
'',
|
|
||||||
'accepted',
|
|
||||||
workflowResult.workflowId,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a failed result
|
|
||||||
*/
|
|
||||||
function createFailedResult(
|
function createFailedResult(
|
||||||
inputQuery: string,
|
inputQuery: string,
|
||||||
error: string,
|
error: string,
|
||||||
|
|
@ -205,9 +129,6 @@ function createFailedResult(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a success result
|
|
||||||
*/
|
|
||||||
function createSuccessResult(
|
function createSuccessResult(
|
||||||
inputQuery: string,
|
inputQuery: string,
|
||||||
expandedQueries: string[],
|
expandedQueries: string[],
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
import type { EnvConfig as BaseEnvConfig } from '@clawd/auth-runtime';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query expansion result from LLM or rule-based logic
|
* Query expansion result from LLM or rule-based logic
|
||||||
*/
|
*/
|
||||||
|
|
@ -45,10 +43,3 @@ export interface OutputResult {
|
||||||
uniqueContactDomains: number;
|
uniqueContactDomains: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Client-finder specific environment configuration
|
|
||||||
* Extends the shared auth config with skill-specific fields
|
|
||||||
*/
|
|
||||||
export interface EnvConfig extends BaseEnvConfig {
|
|
||||||
queryExpansionJson: string;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { requestApiWithAutoRefresh } from '@clawd/auth-runtime';
|
import type { SkillClient } from '@clawd/auth-runtime';
|
||||||
import type { EnvConfig as AuthEnvConfig } from '@clawd/auth-runtime';
|
|
||||||
import { WorkflowStartResponse } from './types.js';
|
import { WorkflowStartResponse } from './types.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -18,26 +17,15 @@ export function parseWorkflowId(responseBody: string): string {
|
||||||
* Start cold outreach workflow
|
* Start cold outreach workflow
|
||||||
*/
|
*/
|
||||||
export async function startWorkflow(
|
export async function startWorkflow(
|
||||||
config: AuthEnvConfig,
|
client: SkillClient,
|
||||||
dryRun: boolean,
|
|
||||||
accessToken: string,
|
|
||||||
query: string,
|
query: string,
|
||||||
country: string,
|
country: string,
|
||||||
): Promise<{ workflowId: string; error: string }> {
|
): Promise<{ workflowId: string; error: string }> {
|
||||||
const payload = JSON.stringify({
|
const result = await client.post('/ecom/cold-outreach/run-flow', {
|
||||||
query,
|
query,
|
||||||
country,
|
country,
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await requestApiWithAutoRefresh(
|
|
||||||
'POST',
|
|
||||||
`${config.authBase}/ecom/cold-outreach/run-flow`,
|
|
||||||
dryRun,
|
|
||||||
config,
|
|
||||||
payload,
|
|
||||||
accessToken,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.status < 200 || result.status >= 300) {
|
if (result.status < 200 || result.status >= 300) {
|
||||||
const error = parseError(result.body);
|
const error = parseError(result.body);
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue