feat: 接入 Hook 遥测回调
与 template-skill 保持一致,每次执行后自动 POST hookUrl 上报执行结果。 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
985e822ff2
commit
fd018ccd6a
|
|
@ -2,6 +2,9 @@
|
|||
import { resolve } from 'path';
|
||||
import type { Command } from '../src/types.ts';
|
||||
import { run } from '../src/index.ts';
|
||||
import { createSkillClient } from '../src/auth-cli.ts';
|
||||
|
||||
const SKILL_NAME = 'video-product-snapshot';
|
||||
|
||||
// Load .env from skill root (does not override existing env vars)
|
||||
loadDotenv(resolve(import.meta.dir, '../.env'));
|
||||
|
|
@ -31,29 +34,34 @@ Commands:
|
|||
detect <video-path> [options]
|
||||
Extract frames and detect ecommerce product snapshots
|
||||
Options:
|
||||
--interval=<seconds> Frame sampling interval (default: 3)
|
||||
--max-frames=<n> Max frames to analyze (default: 30)
|
||||
--interval=<seconds> Frame sampling interval (default: 1)
|
||||
--max-frames=<n> Max frames to analyze (default: 60)
|
||||
--output-dir=<dir> Where to save snapshots (default: next to video)
|
||||
--min-confidence=<0-1> Minimum detection confidence (default: 0.7)
|
||||
--concurrency=<n> Parallel Vision API calls per chunk (default: 5)
|
||||
|
||||
search <image-path>
|
||||
Search for products using an image via the ecom image-search API
|
||||
|
||||
detect-and-search <video-path> [options]
|
||||
Detect best product snapshot from video then run image search
|
||||
Detect best product snapshot from video then run image search + rerank
|
||||
|
||||
Examples:
|
||||
bun scripts/run.ts detect ./demo.mp4
|
||||
bun scripts/run.ts detect ./demo.mp4 --interval=5 --max-frames=20
|
||||
bun scripts/run.ts search ./snapshot.jpg
|
||||
bun scripts/run.ts detect-and-search ./demo.mp4 --min-confidence=0.8
|
||||
rerank --image-results=<json> [--description=<text>] [--keyword=<text>] [--top=<n>]
|
||||
Filter image search results using keyword intersection
|
||||
|
||||
Config: ANTHROPIC_API_KEY env var required for detection.
|
||||
auth-rt in PATH required for search commands.
|
||||
Config: ~/.openclaw/.env (CLIENT_KEY), skill .env (VISION_API_KEY)
|
||||
`);
|
||||
}
|
||||
|
||||
async function reportHook(
|
||||
hookUrl: string,
|
||||
hookToken: string | undefined,
|
||||
payload: object,
|
||||
): Promise<void> {
|
||||
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
|
||||
if (hookToken) headers['Authorization'] = `Bearer ${hookToken}`;
|
||||
await fetch(hookUrl, { method: 'POST', headers, body: JSON.stringify(payload) });
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const positionals: string[] = [];
|
||||
let dryRun = false;
|
||||
|
|
@ -72,8 +80,50 @@ async function main(): Promise<void> {
|
|||
|
||||
if (positionals.length < 1) { printUsage(); process.exit(1); }
|
||||
|
||||
const result = await run(positionals[0] as Command, positionals.slice(1), dryRun);
|
||||
const command = positionals[0] as Command;
|
||||
|
||||
// Exchange CLIENT_KEY for session — gives us hookUrl for telemetry
|
||||
let hookUrl: string | undefined;
|
||||
let hookToken: string | undefined;
|
||||
try {
|
||||
const client = createSkillClient({ dryRun });
|
||||
const session = await client.session();
|
||||
hookUrl = session.hookUrl;
|
||||
hookToken = session.hookToken;
|
||||
} catch {
|
||||
// Auth failure is non-fatal for telemetry; skill still runs
|
||||
}
|
||||
|
||||
const startMs = Date.now();
|
||||
let result: Awaited<ReturnType<typeof run>>;
|
||||
|
||||
try {
|
||||
result = await run(command, positionals.slice(1), dryRun);
|
||||
} catch (err) {
|
||||
const error = err instanceof Error ? err.message : String(err);
|
||||
const failed = { status: 'failed' as const, command, dryRun, error };
|
||||
console.log(JSON.stringify(failed, null, 2));
|
||||
|
||||
if (hookUrl && !dryRun) {
|
||||
reportHook(hookUrl, hookToken, {
|
||||
skill: SKILL_NAME, command, status: 'failed',
|
||||
durationMs: Date.now() - startMs, error,
|
||||
}).catch(() => {});
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
|
||||
if (hookUrl && !dryRun) {
|
||||
reportHook(hookUrl, hookToken, {
|
||||
skill: SKILL_NAME,
|
||||
command,
|
||||
status: result.status,
|
||||
durationMs: Date.now() - startMs,
|
||||
error: (result as any).error,
|
||||
}).catch(() => {});
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
|
|
|
|||
Loading…
Reference in New Issue