/** * src/brain-client.ts — Thin HTTPS wrapper for /v1/beacon/* endpoints. * * Phase 0 contract: * - Every method returns a `BrainResult` envelope. Network/5xx/contract * drift never throws — callers always see ok=false and can fall back to * local cache without try/catch noise. * - 3-attempt exponential backoff (1s / 2s / 4s); 5s per-attempt timeout. * - All Phase 0 method bodies return mock fixtures matching * ACCEPTANCE-SCENARIO §1.1 numbers ($487 spend, $312 savings, etc.) so * the MCP server can demo the call sequence end-to-end without a live * brain. * * BYOK red line: this file MUST NOT read or transmit any LLM API key / * cookie / vault secret. The only credential it sends is the * `Authorization: Bearer ` header (an opaque SkillFM-issued token). * * TODO Week 5: * - Real fetch() against api.skillfm.ai (endpoints listed below). * - HTTP-level error → SkillFmError code mapping (429 → BRAIN_RATE_LIMITED, * 5xx → BRAIN_INTERNAL, network ECONN → NETWORK_UNREACHABLE). * - Idempotency-key on POSTs (record-acceptance / record-rejection) so retry * storms don't double-count feedback. * - ETag / If-None-Match on GET /rules to take advantage of brain side * stale-while-revalidate. * - structured tracing (correlation-id) so a brain log line can be linked * back to a specific MCP tool invocation. * * Endpoint inventory (canonical list lives in beacon-rule-protocol-v1.ts, * which subagent A will write later — keep names in sync when that arrives): * GET /v1/beacon/rules * POST /v1/beacon/feedback * GET /v1/beacon/preferences * PUT /v1/beacon/preferences * GET /v1/beacon/monthly-picks * GET /v1/beacon/assets * POST /v1/beacon/usage-snapshots */ import { type SkillFmCheckUsageOutput, type SkillFmCheckExpiryOutput, type SkillFmAvatarMarketOutput, type SkillFmGetMonthlyPicksOutput, type SkillFmRecordFeedbackOutput, type UserPreferences, type SkillFmRecordAcceptanceInput, type SkillFmRecordRejectionInput } from './_vendored-contracts/beacon-mcp-tools-v1.js'; export interface BrainClientOpts { agentToken: string | null; baseUrl: string; /** override default 5000ms */ timeoutMs?: number; } export type BrainResult = { ok: true; data: T; } | { ok: false; code: string; message: string; retryable: boolean; }; export declare class BrainClient { private readonly agentToken; private readonly baseUrl; private readonly timeoutMs; constructor(opts: BrainClientOpts); /** True if no token configured — caller should serve cache / mock fixtures. */ isDegraded(): boolean; /** GET /v1/beacon/rules — Phase 0 mock; Week 5 real fetch. */ fetchRule(triggerType: string, _triggerContext: Record, _userProfile: Record): Promise; }>>; /** POST /v1/beacon/feedback — record acceptance OR rejection. */ postFeedback(kind: 'acceptance' | 'rejection', _input: SkillFmRecordAcceptanceInput | SkillFmRecordRejectionInput): Promise>; /** GET /v1/beacon/preferences */ getPreferences(): Promise>; /** PUT /v1/beacon/preferences */ putPreferences(_prefs: UserPreferences): Promise>; /** GET /v1/beacon/monthly-picks?personalized=... */ getMonthlyPicks(_personalized: boolean): Promise>; /** GET /v1/beacon/assets?withinDays=&category= */ getAssets(_withinDays?: number, _category?: string): Promise>; /** GET /v1/beacon/usage */ getUsage(): Promise>; /** GET /v1/beacon/avatar-market */ getAvatarMarket(_intent: string): Promise>; /** POST /v1/beacon/usage-snapshots — agents push their own daily usage. */ postUsageSnapshot(_snapshots: Array>): Promise>; /** * For tests that need to assert headers / URL. Not exported via index.ts. */ _describe(): { baseUrl: string; hasToken: boolean; timeoutMs: number; }; } //# sourceMappingURL=brain-client.d.ts.map