outreach: voice by-purpose (larger sample) + Tier-B Gmail draft creation (v0.1.0:71)
(1) Voice: _voice_examples now picks the sender's prior sent emails OF THE SAME PURPOSE (PURPOSE_PATTERNS keyword cues per outreach type), larger sample (8) weighted by purpose then recency — not just recent. meta carries on_topic for transparency. (2) Tier-B sending (gmail.compose now authorized in Workspace DWD). New email_integration/compose.py create_outreach_draft: mints a compose-scoped DWD token for the sender (credentials._mint/access_token_for parameterized by scope; GMAIL_COMPOSE_SCOPE), builds an RFC822 message, and POSTs gmail.drafts.create into the SENDER's mailbox — as an in-thread reply (threadId + In-Reply-To/References, recipient = matched LP address) when there's an active thread, else a fresh email. NEVER sends — the human sends from Gmail (guardrails #4, #6). Route POST /api/outreach/gmail-draft; UI "Create Gmail draft" button + "Open Gmail Drafts" link. Tests: test_compose.py (parse/reply-target/RFC822+threading). Message construction unit-verified; the live drafts.create runs on the box. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -35,8 +35,9 @@ export const PACKAGE_TITLE = 'Ten31 Database'
|
||||
// * 0.1.0:67 (remove LP Objections page — generic/unverifiable; pivot to proactive outreach)
|
||||
// * 0.1.0:68 (Outreach Draft Assistant — tailored LP drafts via thesis + redaction boundary)
|
||||
// * 0.1.0:69 (follow-up radar — deterministic "needs attention" list + one-click draft)
|
||||
// * Current: 0.1.0:70 (outreach voice upgrade — per-user voice from own emails + transparency; active-thread context)
|
||||
export const PACKAGE_VERSION = '0.1.0:70'
|
||||
// * 0.1.0:70 (outreach voice upgrade — per-user voice from own emails + transparency; active-thread context)
|
||||
// * Current: 0.1.0:71 (voice by-purpose larger sample + Tier-B: create Gmail draft w/ in-thread reply)
|
||||
export const PACKAGE_VERSION = '0.1.0:71'
|
||||
|
||||
export const DATA_MOUNT_PATH = '/data'
|
||||
export const WEB_PORT = 8080
|
||||
|
||||
@@ -31,8 +31,9 @@ import { v_0_1_0_67 } from './v0.1.0.67'
|
||||
import { v_0_1_0_68 } from './v0.1.0.68'
|
||||
import { v_0_1_0_69 } from './v0.1.0.69'
|
||||
import { v_0_1_0_70 } from './v0.1.0.70'
|
||||
import { v_0_1_0_71 } from './v0.1.0.71'
|
||||
|
||||
export const versionGraph = VersionGraph.of({
|
||||
current: v_0_1_0_70,
|
||||
other: [v_0_1_0_39, v_0_1_0_40, v_0_1_0_41, v_0_1_0_42, v_0_1_0_43, v_0_1_0_44, v_0_1_0_45, v_0_1_0_46, v_0_1_0_47, v_0_1_0_48, v_0_1_0_49, v_0_1_0_50, v_0_1_0_51, v_0_1_0_52, v_0_1_0_53, v_0_1_0_54, v_0_1_0_55, v_0_1_0_56, v_0_1_0_57, v_0_1_0_58, v_0_1_0_59, v_0_1_0_60, v_0_1_0_61, v_0_1_0_62, v_0_1_0_63, v_0_1_0_64, v_0_1_0_65, v_0_1_0_66, v_0_1_0_67, v_0_1_0_68, v_0_1_0_69],
|
||||
current: v_0_1_0_71,
|
||||
other: [v_0_1_0_39, v_0_1_0_40, v_0_1_0_41, v_0_1_0_42, v_0_1_0_43, v_0_1_0_44, v_0_1_0_45, v_0_1_0_46, v_0_1_0_47, v_0_1_0_48, v_0_1_0_49, v_0_1_0_50, v_0_1_0_51, v_0_1_0_52, v_0_1_0_53, v_0_1_0_54, v_0_1_0_55, v_0_1_0_56, v_0_1_0_57, v_0_1_0_58, v_0_1_0_59, v_0_1_0_60, v_0_1_0_61, v_0_1_0_62, v_0_1_0_63, v_0_1_0_64, v_0_1_0_65, v_0_1_0_66, v_0_1_0_67, v_0_1_0_68, v_0_1_0_69, v_0_1_0_70],
|
||||
})
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { VersionInfo } from '@start9labs/start-sdk'
|
||||
|
||||
// Two outreach upgrades. (1) Voice now learns from the sender's prior emails OF THE SAME
|
||||
// PURPOSE (larger, purpose-weighted sample, not just recent). (2) Tier-B sending: with the
|
||||
// gmail.compose scope authorized, an approved draft can be created straight into the
|
||||
// sender's Gmail (and therefore Superhuman) Drafts — as an in-thread reply when there's an
|
||||
// active thread, or a fresh email otherwise. Our code only ever CREATES a draft; the human
|
||||
// sends from Gmail (guardrails #4, #6). No schema change.
|
||||
export const v_0_1_0_71 = VersionInfo.of({
|
||||
version: '0.1.0:71',
|
||||
releaseNotes: {
|
||||
en_US: [
|
||||
'Outreach: drafts now learn your voice from your prior emails of the same purpose (a',
|
||||
'bigger, more relevant sample), and a new "Create Gmail draft" button drops the approved',
|
||||
'draft into your Gmail Drafts — as an in-thread reply for follow-ups — for you to review',
|
||||
'and send. Nothing is sent automatically.',
|
||||
].join(' '),
|
||||
},
|
||||
migrations: { up: async () => {}, down: async () => {} },
|
||||
})
|
||||
Reference in New Issue
Block a user