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.
This commit is contained in:
parent
ccc04cc172
commit
8d272a9c76
1 changed files with 17 additions and 3 deletions
|
|
@ -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<CrewAgentMessage[]>([]);
|
||||
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 };
|
||||
|
|
|
|||
Loading…
Reference in a new issue