From 8d272a9c76f2d42c60c57f9cb7c998b7fcbfb798 Mon Sep 17 00:00:00 2001 From: SkateSpots Date: Sun, 27 Sep 2026 14:27:02 +0700 Subject: [PATCH] feat(sasquatch-pro): crew agent sends Pro credentials too useCrewAgentChat now signs the same NIP-98 auth + attaches the viewer's Pro receipt (when they have one), so the proxy's Pro gate lets Pro users through the gateway models; everyone else still falls back to the keyless provider. --- src/hooks/useCrewAgentChat.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/hooks/useCrewAgentChat.ts b/src/hooks/useCrewAgentChat.ts index 46f9f39..bb2f8f0 100644 --- a/src/hooks/useCrewAgentChat.ts +++ b/src/hooks/useCrewAgentChat.ts @@ -1,6 +1,9 @@ import { useState, useCallback } from 'react'; import { useCVMClient } from '@/hooks/useCVMClient'; import { callSasquatchAI, parseToolCall, type ChatTurn } from '@/lib/sasquatchBrain'; +import { useCurrentUser } from '@/hooks/useCurrentUser'; +import { useSasquatchPro } from '@/hooks/useSasquatchPro'; +import { buildProAuthHeaders } from '@/lib/proAuth'; export interface CrewAgentMessage { id: string; @@ -166,6 +169,8 @@ Rules: */ export function useCrewAgentChat(ctx: CrewContext) { const cvm = useCVMClient(); + const { user } = useCurrentUser(); + const { isPro, receiptEvent } = useSasquatchPro(); const [messages, setMessages] = useState([]); const [isThinking, setIsThinking] = useState(false); @@ -206,12 +211,21 @@ export function useCrewAgentChat(ctx: CrewContext) { append({ role: 'user', text: q }); try { + // Pass the viewer's identity + Pro pass so the proxy's gate (when on) + // lets Pro users through; others fall back to the keyless provider. + const authHeaders = isPro + ? await buildProAuthHeaders({ + pubkey: user?.pubkey, + signEvent: user ? (e) => user.signer.signEvent(e) : undefined, + receiptEvent, + }) + : {}; const system = buildCrewSystemPrompt(ctx); // First pass — AI answers directly from crew memory or emits a tool call. const firstPass: ChatTurn[] = [ { role: 'user', content: `${system}\n\n---\n\nMember: ${q}` }, ]; - const aiText = await callSasquatchAI(firstPass); + const aiText = await callSasquatchAI(firstPass, 400, undefined, authHeaders); const toolCall = parseToolCall(aiText); if (!toolCall) { @@ -246,7 +260,7 @@ ${JSON.stringify(toolResult, null, 2)} - If count > 0: a short intro line — the app shows the results as cards below your message - Keep it short and skater-friendly. Never invent data.`, }, - ]); + ], 400, undefined, authHeaders); append({ role: 'agent', @@ -263,7 +277,7 @@ ${JSON.stringify(toolResult, null, 2)} setIsThinking(false); } }, - [ctx, isThinking, append, runTool], + [ctx, isThinking, append, runTool, isPro, receiptEvent, user], ); return { messages, isThinking, send };