File size: 5,950 Bytes
46d5e00
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Jev evidence battery (docs/ARCHITECTURE.md §3.3). State is the transcript alone; call metadata stays in code.

export const JEV_CHAMPION = 'typesafe/jev-1.13';
export const JEV_CHALLENGER = 'typesafe/jev-1.14';
const ENDPOINT = 'https://openrouter.ai/api/v1/systemone';

const PROTECTED = ['financial', 'healthcare', 'education'] as const;

export const QUESTIONS = {
  claims_sector: {
    type: 'choice',
    instructions:
      'What kind of organization does the caller claim to be from, and what relationship does the message imply with the listener?',
    criteria: {
      financial: 'A bank, card issuer or credit union contacting the listener about an account or card they already have',
      healthcare: 'A pharmacy, doctor, hospital or health insurer contacting the listener about their own care or prescription',
      education: 'A school or school district contacting families',
      solicitation: 'A lender, dealer or seller offering a new loan, credit, rate, warranty, insurance or other deal',
      government: 'Government agency such as IRS, Social Security, police',
      utility_telecom: 'Utility, phone or internet provider',
      retail_delivery: 'Retailer or delivery company such as Amazon, UPS',
      other: 'Some other organization',
      none: 'No organization is identified',
    },
  },
  specific_detail: {
    type: 'noul',
    instructions:
      "Does the message contain concrete specifics a genuine organization would know, such as card or account last 4 digits, an exact amount, a merchant, a date, or the recipient's name?",
  },
  official_channel: {
    type: 'noul',
    instructions:
      'Does the message tell the listener to use an official channel they already have, such as the number on the back of their card, the official app, or the website?',
  },
  pressure: {
    type: 'noul',
    instructions: 'Does the message use threats or urgency, such as arrest, lawsuit, account suspension, or a deadline?',
  },
  agent_or_credentials: {
    type: 'noul',
    instructions:
      'Does the message push the listener to press a key to reach a live agent, or to give or verify personal, account or payment details?',
  },
  sales_pitch: {
    type: 'noul',
    instructions: 'Is the message offering a product, loan, rate, warranty, insurance or other deal?',
  },
  self_assertion: {
    type: 'noul',
    instructions: "The message itself claims to be legitimate, verified, official, or 'not a scam'.",
  },
  category: {
    type: 'choice',
    instructions: 'What kind of automated voicemail is this?',
    criteria: {
      legit_alert:
        'Genuine service alert from an organization the recipient does business with (fraud alert, prescription, appointment, school notice)',
      scam: 'Fraud, impersonation or pretext to extract money or credentials',
      marketing_robocall: 'Unsolicited sales, loan, warranty or other marketing pitch',
      unsure: 'Too short or unclear to tell',
    },
  },
} as const;

export interface Evidence {
  /** "Which known script?" answer: the matched campaign id and its probability, or null for none / no question asked. */
  knownScript?: { id: number; p: number } | null;
  sector: string;
  protected: number;
  specific: number;
  official: number;
  pressure: number;
  agent: number;
  sales: number;
  selfAssert: number;
  catLegit: number;
  catScam: number;
  catMkt: number;
}

export interface JevResult {
  evidence: Evidence;
  model: string;
  raw: unknown;
}

type Answers = Record<string, { choice?: string; probabilities?: Record<string, number>; noul?: number }>;

export interface KnownScript {
  id: number;
  sample: string;
}

const NONE = 'none';

/** The live battery plus, when junk scripts are known, one choice question listing them (docs/ARCHITECTURE.md §3.2). */
export function buildQuestions(known: KnownScript[]) {
  if (!known.length) return QUESTIONS;
  const criteria: Record<string, string> = Object.fromEntries(known.map((k) => [`s${k.id}`, `Same campaign as: "${k.sample.slice(0, 300)}"`]));
  criteria[NONE] = 'A different message that is not one of the scripts above';
  return {
    ...QUESTIONS,
    known_script: {
      type: 'choice',
      instructions:
        'Is this voicemail a new recording of one of these known robocall scripts (same caller campaign, same offer or pretext, possibly reworded), or something different?',
      criteria,
    },
  };
}

export function toEvidence(answers: Answers): Evidence {
  const sector = answers.claims_sector.probabilities!;
  const cat = answers.category.probabilities!;
  const ks = answers.known_script;
  const knownScript =
    ks && ks.choice && ks.choice !== NONE ? { id: Number(ks.choice.slice(1)), p: ks.probabilities![ks.choice] ?? 0 } : null;
  return {
    knownScript,
    sector: answers.claims_sector.choice!,
    protected: PROTECTED.reduce((sum, k) => sum + (sector[k] ?? 0), 0),
    specific: answers.specific_detail.noul!,
    official: answers.official_channel.noul!,
    pressure: answers.pressure.noul!,
    agent: answers.agent_or_credentials.noul!,
    sales: answers.sales_pitch.noul!,
    selfAssert: answers.self_assertion.noul!,
    catLegit: cat.legit_alert ?? 0,
    catScam: cat.scam ?? 0,
    catMkt: cat.marketing_robocall ?? 0,
  };
}

export async function askJev(transcript: string, apiKey: string, model = JEV_CHAMPION, known: KnownScript[] = []): Promise<JevResult> {
  const res = await fetch(ENDPOINT, {
    method: 'POST',
    headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ model, state: transcript, questions: buildQuestions(known) }),
    signal: AbortSignal.timeout(15_000),
  });
  if (!res.ok) throw new Error(`jev ${model} ${res.status}: ${(await res.text()).slice(0, 200)}`);
  const body = (await res.json()) as { model: string; answers: Answers };
  return { evidence: toEvidence(body.answers), model: body.model, raw: body.answers };
}