Skip to content

feat: implement inference-time persona construction system (6 techniques from literature)#35

Open
jeremykamber wants to merge 58 commits into
devfrom
feat/persona-inference-time-techniques
Open

feat: implement inference-time persona construction system (6 techniques from literature)#35
jeremykamber wants to merge 58 commits into
devfrom
feat/persona-inference-time-techniques

Conversation

@jeremykamber

Copy link
Copy Markdown
Owner

Summary

Implements all 6 techniques from the Literature Review Section 9 (Applications of the Literature) for high-fidelity inference-time persona construction.

Techniques Implemented

T1: Compartmentalized Persona Prompts (Wang et al. 2024b)

  • Four-section compartmentalized prompt architecture with clear delimiters
  • Sections: PERSONA IDENTITY, PSYCHOGRAPHIC PROFILE, EPISTEMIC BOUNDARIES, BEHAVIORAL GUARDRAILS
  • Prevents attention dilution between identity and task instructions

T2: PB&J Psychological Scaffolds (Joshi et al. 2025)

  • Three parallel psychological scaffolds generating post-hoc rationales
  • Big Five Personality Roots, Cognitive-Reflex Decision Style, Core Values & Risk Worldview
  • Graceful degradation if individual scaffold calls fail

T3: Persona Anchors / SyTTA (Xu et al. 2026, Atri et al. 2026)

  • 4-16 token persona anchors injected before every agent turn
  • Archetype detection based on Big Five scores (9 archetypes)
  • Combats attention decay in multi-turn interactions

T4: ID-RAG Factual Grounding (Tan et al. 2025)

  • Two-tier hybrid architecture: full backstory + retrieved chunks
  • In-memory vector store with trigram-based semantic similarity
  • Backstory chunking with metadata (topic, emotional tone, relationship type)

T5: InCharacter Interview Evaluation (Wang et al. 2024a)

  • 10 open-ended questions mapped to Big Five dimensions
  • Expert LLM evaluates transcript for trait evidence (blinded)
  • Avoids self-report alignment conflict

T6: PICon Consistency Interrogation (Kim et al. 2026)

  • 8-turn logically-chained multi-turn questioning
  • Three dimensions: internal, external, and retest consistency
  • Expert LLM judges with structured JSON scoring

Files Changed

  • 8 new source files (adapters, services, evaluators)
  • 8 new test files (unit, integration, E2E)
  • 2 modified files (Persona entity, ChatAdapter)
  • 1 documentation file

Test Results

  • 44 new tests, all passing
  • Pre-existing failures (Zod v4 compatibility) unchanged
  • E2E tests verify the full pipeline without LLM dependencies

Documentation

See docs/PERSONA_INFERENCE_SYSTEM.md for detailed overview of all techniques.

Jeremy Kamber added 7 commits May 20, 2026 00:03
…2024b)

- Adds PersonaPromptCompiler with four-section architecture:
  - <<PERSONA IDENTITY>> (demographic anchoring)
  - <<PSYCHOGRAPHIC PROFILE>> (Big Five with behavior mappings)
  - <<EPISTEMIC BOUNDARIES>> (knowledge domain constraints)
  - <<BEHAVIORAL GUARDRAILS>> (response format + refusal patterns)
- Adds persona anchor generation (SyTTA-style 4-16 token descriptors)
- Adds compileInteractionPrompt for hybrid backstory + anchor + RAG assembly
- Adds persona anchor injection before each chat turn for multi-turn consistency
- Extends Persona entity with domainExpertise, epistemicBoundaries,
  responseConstraints, and refusalPatterns fields
- Updates ChatAdapter to use the compiled prompt architecture
- 7 tests passing for prompt compiler, anchors, sections, metadata
…ization (Joshi et al. 2025)

Implements the PB&J (Psychology of Behavior and Judgments) framework:
- Three parallel psychological scaffolds:
  - Big Five Personality Roots (trait-level cause-and-effect explanations)
  - Cognitive-Reflex Decision Style (System 1 vs System 2 manifestations)
  - Core Values & Risk Worldview (money, risk, efficiency, trust)
- Generates post-hoc rationales explaining WHY a persona holds traits
- Formats rationales as backstory appendix with <<PSYCHOLOGICAL RATIONALES>> section
- Graceful degradation: partial results survive individual scaffold failures
- Reference: Joshi et al. (2025) Findings of EMNLP 2025
…l. 2025)

Two-tier identity retrieval-augmented generation:
- IdRagStore: in-memory vector store with trigram-based semantic similarity
- Backstory chunking with metadata (topic, emotional tone, relationship type)
- Automatic topic tagging and tone detection per chunk
- Related chunk linking (adjacency + same-topic cross-linking)
- Top-K retrieval with relevance scoring
- Formatted context string for prompt injection
- 8 tests passing for chunking, retrieval, ranking, formatting, edge cases
…nterrogation

InCharacter-style evaluator (Wang et al. 2024a):
- Open-ended conversational interview across all Big Five dimensions
- Expert LLM evaluates transcript for trait evidence (blinded)
- Score parsing from expert analysis text
- 5 tests for interview protocol, expert analysis, score parsing

PICon-style evaluator (Kim et al. 2026):
- 8-turn logically-chained multi-turn interrogation
- Three consistency dimensions: internal, external, retest
- Expert LLM judges for each dimension with JSON scoring
- Structured result with total score and detailed breakdown
- 4 tests for interrogation, retest, internal consistency, full evaluation
Integration test covering the complete pipeline:
- T1+T3: Compartmentalized prompts with persona anchors
- T4: ID-RAG chunking, indexing, retrieval, and formatting
- T1+T3+T4: Full hybrid prompt assembly (compartmentalized + anchor + RAG)
- Realistic persona with detailed 5-part backstory
- Verifies all components compose correctly into a unified interaction prompt
- 6 integration tests passing
10 E2E tests covering the complete pipeline without LLM dependencies:
- Compartmentalized 4-section prompt generation
- Persona anchor injection per turn
- ID-RAG chunking, retrieval, and formatting
- Full hybrid prompt assembly (compartmentalized + RAG + anchor)
- Multi-turn conversation simulation
- Edge cases: empty backstory, unknown persona, different profiles
All 10 tests passing.
Documents all 6 implemented techniques with research citations:
- T1: Compartmentalized prompts (Wang et al. 2024b)
- T2: PB&J psychological scaffolds (Joshi et al. 2025)
- T3: Persona anchors / SyTTA (Xu et al. 2026, Atri et al. 2026)
- T4: ID-RAG factual grounding (Tan et al. 2025)
- T5: InCharacter interview evaluation (Wang et al. 2024a)
- T6: PICon consistency interrogation (Kim et al. 2026)
Covers architecture, files changed, test verification, and run instructions.
Copilot AI review requested due to automatic review settings May 20, 2026 07:12
@vercel

vercel Bot commented May 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ai-pricing-wedge Ready Ready Preview, Comment Jun 7, 2026 6:53am

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an inference-time persona construction pipeline (prompt compartmentalization, anchors, ID‑RAG grounding, and evaluation utilities) and wires it into the chat adapter, with comprehensive unit/integration/E2E tests and supporting documentation.

Changes:

  • Introduces PersonaPromptCompiler for 4‑section compartmentalized system prompts + per-turn persona anchors.
  • Implements ID‑RAG via an in-memory chunk store (IdRagStore) and retrieval service (IdRagService).
  • Adds PB&J rationale scaffolding + offline evaluators (InCharacter, PICon), plus extensive tests and a design doc.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
test/persona-system-e2e.test.ts E2E pipeline verification without LLM dependencies
src/infrastructure/adapters/PiconEvaluator.ts PICon multi-turn interrogation + scoring logic
src/infrastructure/adapters/PersonaPromptCompiler.ts Compartmentalized prompt builder + persona anchors
src/infrastructure/adapters/PbjScaffoldEnhancer.ts PB&J scaffold rationale generation
src/infrastructure/adapters/InCharacterEvaluator.ts Interview-based evaluation + expert scoring parse
src/infrastructure/adapters/IdRagStore.ts In-memory chunking + trigram similarity retrieval
src/infrastructure/adapters/IdRagService.ts Indexing/retrieval wrapper + hybrid prompt builder
src/infrastructure/adapters/ChatAdapter.ts Uses prompt compiler + anchor-injected user message
src/infrastructure/adapters/__tests__/PiconEvaluator.test.ts Unit tests for PICon evaluator
src/infrastructure/adapters/__tests__/PersonaSystemIntegration.test.ts Integration tests across prompt + ID‑RAG
src/infrastructure/adapters/__tests__/PersonaPromptCompiler.test.ts Unit tests for prompt compiler + anchors
src/infrastructure/adapters/__tests__/PbjScaffoldEnhancer.test.ts Unit tests for PB&J scaffolds
src/infrastructure/adapters/__tests__/InCharacterEvaluator.test.ts Unit tests for InCharacter evaluator
src/infrastructure/adapters/__tests__/IdRagStore.test.ts Unit tests for chunking/retrieval/formatting
src/domain/entities/Persona.ts Extends Persona with expertise/boundaries/guardrails fields
docs/PERSONA_INFERENCE_SYSTEM.md System overview, technique mapping, and test commands

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +145 to +152
/** Generate a short persona anchor (4-16 tokens) based on persona traits. */
generateAnchor(persona: Persona): string {
const archetype = this.detectArchetype(persona);
const anchors: Record<string, string> = {
"skeptical-veteran": `As a skeptical, veteran ${persona.occupation.toLowerCase()}:`,
"passionate-founder": `As a passionate first-time founder:`,
"curious-student": `As a curious ${this.simplifyEducation(persona.educationLevel)} student:`,
"jaded-journalist": `As a jaded, veteran journalist:`,

/** Reset the persona anchor counter for a fresh interaction. */
resetAnchorIndex(): void {
this.anchorIndex = 0;
@@ -0,0 +1,64 @@
import { Persona } from "@/domain/entities/Persona";
import { IdRagStore, RetrievalResult } from "./IdRagStore";
Comment on lines +29 to +37
retrieveContext(persona: Persona, query: string, k = 3): RagContext {
if (!persona.backstory) {
return { contextString: "", chunkCount: 0 };
}

const results = this.store.retrieve(persona.id, query, k);
const contextString = this.store.formatRetrievedContext(results);

return { contextString, chunkCount: results.length };
parts.push(options.ragContext);
}

parts.push(`User says: "${query}"`);
Comment on lines +122 to +129
const chunks = store.chunkBackstory("test-1", [
"I grew up in a family that valued money carefully. My parents were frugal and taught me to save.",
"My career in finance taught me to analyze every purchase carefully.",
"I now live in a minimalist apartment that reflects my organized approach to life.",
].join("\n\n"));

// Related should at minimum include adjacent chunks
expect(chunks.length).toBeGreaterThanOrEqual(2);
const anchor = c.generateAnchor(jordan);
const tokens = anchor.split(/\s+/);

expect(tokens.length).toBeGreaterThanOrEqual(2);
const anchor = compiler.generateAnchor(basePersona);
expect(anchor).toContain(":");
expect(anchor.split(" ").length).toBeLessThanOrEqual(16);
expect(anchor.split(" ").length).toBeGreaterThanOrEqual(2);
Comment on lines +98 to +104

const response = await this.llmService.createChatCompletion(
[
{
role: "system",
content: `You are ${persona.name}, a ${persona.occupation}. Answer naturally and consistently.${context}`,
},
Comment on lines +132 to +141
const response = await this.llmService.createChatCompletion(
[
{
role: "system",
content: `You are ${persona.name}, a ${persona.occupation}. Answer naturally.`,
},
{ role: "user", content: retestQuestions[i] },
],
{ temperature: 0.5, purpose: `PICon Retest ${i + 1}` },
);
Removes non-research fields (cognitiveReflex, technicalFluency, economicSensitivity, designStyle, livingEnvironment). Adds psychographic specification from Wang et al. (2024b): values, fears, communicationStyle, decisionStyle. Keeps Big Five (OCEAN) as primary psychometric framework per Joshi et al. (2025). Updates prompts, mapper, UI cards, detail modal, and tests. 44/44 tests passing.
… spec

Root cause: analysis prompt had three problems causing uniform scoring:
1. Referenced cognitiveReflex which was removed from Persona entity
2. Only guided on 2 of 5 Big Five traits (Conscientiousness, Neuroticism)
3. Ignored values, fears, communicationStyle, decisionStyle entirely
4. No prompt/result logging to inspect LLM behavior

Fix:
- Adds behavioral guidance for ALL Big Five: Conscientiousness,
  Neuroticism, Openness, Extraversion, Agreeableness
- Adds VALUES + FEARS DRIVE YOUR MOTIVATION section that injects
  the persona's actual values and fears directly into the prompt
- Adds decisionStyle + communicationStyle guidance
- Tells LLM explicitly: 'Different personas MUST give DIFFERENT
  scores based on their unique Big Five, values, and fears'
- Logs full analysis prompt + results for each persona
Previously analysis used flat stringifyPersona() while chat used the
4-compartment PersonaPromptCompiler. Now both use the same Wang et al.
(2024b) architecture with <<ANALYSIS TASK>> appended.
…eline

Fixes PbjScaffoldEnhancer to use current Persona fields (removed stale
cognitiveReflex, economicSensitivity, technicalFluency refs). Scaffolds
now use Big Five + values + fears + decisionStyle + communicationStyle.
Integrated into GeneratePersonasUseCase as new ENHANCING_WITH_PBJ phase
between backstory generation and insight generation. Per Joshi et al.
(2025), this adds post-hoc rationales that causally connect Big Five
to psychographics, improving alignment by 6-9%.
ChatAdapter: ingests persona backstory into IdRagStore on first
interaction, retrieves top-3 relevant chunks per user message, injects
as <<RETRIEVED MEMORY>> in system prompt.

VisionAnalysisAdapter: ingests persona backstory, retrieves chunks
relevant to the pricing page context, injects as <<RETRIEVED MEMORY>>
in both streaming and audit analysis prompts. Also adds persona anchor
before the task instruction. Per Tan et al. (2025) ID-RAG framework.
Adds periodic re-grounding (Atri et al., 2026b) to ChatAdapter: every 4th turn, a <<REGROUND>> instruction forces the model to re-access its persona definition (values, fears, goals) before responding. This counters the 30-40% persona drift documented in ChronoScope between turns 1-20.
The streaming generateInitialPersonasStream consistently fails at runtime. Replaced with direct non-streaming generateInitialPersonas call. Can re-add streaming later when the AI SDK streamObject issue is resolved.
P0 fixes addressing Linear PM feedback:

1. Domain calibration: generation prompt now tells LLM that -16/user is standard B2B SaaS pricing, Enterprise custom pricing is normal, beta features on paid tiers are common. Prevents personas from penalizing standard industry mechanics.

2. Scoring-sentiment alignment: analysis prompt now enforces that scores must match qualitative sentiment (positive gut = 6+, critical = 4 or below).

3. Actionable recommendations: added recommendations field to PricingAnalysis entity, schema, and validation. Analysis prompt asks for 2-3 specific actionable recommendations per persona.
Jeremy Kamber added 19 commits May 24, 2026 16:52
…code quality

- Replace hardcoded white/black color references with theme tokens across all components (badge, card, tabs, dialog, results, upload)

- Fix dialog overlay opacity to match spec: bg-black/80 -> bg-black/40

- Fix button radius: rounded-lg -> rounded-md (design spec: 6px)

- Fix input border width: border-2 -> border (design spec: 1px)

- Remove decorative shadows from FlowDialog and ResultsView (no-shadow rule)

- Fix sidebar nav radius to match design system (rounded-md)

- Fix dropzone radius for card consistency (rounded-xl -> rounded-lg)

- Remove debug console.logs and unused framer-motion import

- Fix as any type assertions with proper as const

- Add DESIGN.md and PRODUCT.md design system documentation

- Remove superseded DESIGN_SYSTEM.md and DESIGNER_PROMPT.md
…used download, chat offset

- Remove unused FileDown download button (no onClick handler)
- Move close button into header action row to prevent overlay with tabs
- Switch DialogContent from grid to flex-col for proper height propagation
- Wrap chat tab in flex-1 container so header is flush with top
- Add min-h-0 to both tab containers for correct overflow handling
Strip full-height side-sheet positioning (fixed right-0 top-0 h-dvh) and
revert to base dialog centering. Cap height at 85vh so content isn't
full-screen. Override width to 600px/680px for comfortable reading.
- Add .DS_Store and logs/ to .gitignore
- Remove .DS_Store, bun.lockb, next-env.d.ts from tracking (already gitignored or auto-generated)
…okens, sonner toasts, button hierarchy

- Change accent from indigo-violet to cerulean blue across all CSS tokens
- Update DESIGN.md to reflect new color palette and design decisions
- Add button hierarchy documentation (primary/secondary/ghost) with ring-1 definition
- Add selection state guidelines using tonal hierarchy instead of accent color
- Integrate sonner toast system with dark theme tokens
- Add sim-ring-fade animation for simulation notifications
- Refine button component variants with ring-1 on primary, updated border styles on outline
- Update CSS variable lightness values for better contrast in both light and dark modes
- Replace hardcoded chat bubble colors with color-mix on primary token
- Align accent and sidebar-accent with primary token via var() reference
…chat streams

- Extract duplicate parseMessageContent function from PersonaChat and PersonaChatInline into shared module
- Add error handling for non-string stream updates (step: ERROR objects)
- Fix chatWithPersonaAction to use stream.done instead of stream.error for graceful error delivery
- Change streamable value type from string to any to support structured error payloads
…logging, scouting improvements, and result persistence

- Add AnalysisLogger — per-run JSONL logging to logs/analysis/ with auto-flush and structured metadata
- Add SimulationResultStore — in-memory server-side store with 30-min TTL for simulation results surviving page reloads
- Add screenshot and progress side-channel stores to bypass RSC stream size limits on base64 payloads
- Add getSimulationResult, getProgress, getScreenshot server actions for client polling/reconnection
- Overhaul ParsePricingPageUseCase with adaptive scouting: targeted strike via HTML locator, guided scroll, lazy-load triggering
- Add parallel HTML analysis (isPricingVisibleInHtml + summarizeHtml) for faster pricing detection
- Add structured logging throughout the entire pipeline — entry/exit, latency tracking, persona summaries
- Add runId passthrough for per-request tracing across all pipeline components
- Upgrade report API route with request timing, validation logging, and AnalysisLogger integration
- Save error states to SimulationResultStore for robust failure recovery
- Add unit tests for the pricing pipeline use case with mock browser and LLM services
…-load handling, and vision analysis overhaul

- Simplify RemotePlaywrightAdapter: remove redundant wait methods, streamline screenshot capture
- Add DOM stability detection during page load for reliable screenshot timing
- Add lazy image loading trigger via progressive scroll-down
- Add framework rendering detection (React/Angular/Vue) for SPA compatibility
- Overhaul VisionAnalysisAdapter with structured pricing detection via HTML locator + vision LLM
- Add multi-strategy pricing location: targeted element strike (via selector/anchor text) vs full scroll scout
- Add scouting state machine with viewport captures at each stage for progress UI
- Add compact HTML summarization for LLM-based pricing element detection
- Pass runId through all LLM calls for consistent tracing
… retry, reasoning extraction, persona backstory generation

- Refactor LlmServiceImpl with configurable OpenRouter/Ollama provider selection via createFromEnv factory
- Add p-limit concurrency limiter (max 20 parallel requests) to prevent API throttling
- Add exponential backoff retry logic (5 retries, 429/5xx only) with jitter
- Add reasoning token extraction from DeepSeek V4 Flash responses (both streaming and non-streaming)
- Add per-request logging with request IDs, duration tracking, and response previews
- Implement OpenRouterCriticAdapter for validation/critique of analysis quality
- Implement OpenRouterChatAdapter for persona chat conversations
- Add LlmMemoryAdapter for memory-enhanced chat interactions
- Add structured persona backstory generation adapter with progress callbacks
- Add PersonaPromptCompiler — centralized prompt templates for persona generation, backstories, and insights
- Add batch backstory and insight generation for efficient persona processing
- Extend LlmServicePort interface with new methods: isPricingVisibleInHtml, summarizeHtml, generateBackstory, etc.
- Add variantOf field to Persona entity for tracking persona variation lineage
- Add aiSuggestion field to PricingAnalysis entity
…liders, inline streaming, and management

- Add generateSimilarPersonasAction — server action for streaming variation generation from reference persona
- Add variationMapping utility — maps continuous Big Five values to 1-5 discrete scale for slider UI
- Add PersonaDetailSheet variant tab with Big Five sliders (1-5), creative freedom slider, count selector (1/3/5)
- Add randomize button for quick trait exploration
- Add PersonaSkeletonCard — shimmer placeholder shown while variations are generating
- Add DashboardClient variation flow: placeholder injection, streaming replacement, toast notifications
- Add person deletion with confirmation dialog on PersonaProfilePanel
- Add variantOf display indicator on PersonaProfilePanel
- Extend personaStore with insertPersonasAfter (inline insertion after reference), updatePersona, removePersona
- Add unit tests for variationMapping and personaStore
- Add E2E tests for persona variation generation flow
…s polling and sidebar navigation

- Add simulations list page (/dashboard/simulations) showing all completed/in-progress simulation runs
- Add simulation detail page (/dashboard/simulations/[id]) with persona analyses, progress polling, and reconnection support
- Add simulationStore (Zustand) — manages simulation state with localStorage persistence
- Add SimulationToaster component for real-time simulation completion notifications
- Add Simulation and PersonaProfile domain entities
- Add Simulations link to sidebar navigation with active state
- Support reconnection to in-progress simulations via polling getProgress/getScreenshot/getSimulationResult actions
…ove results-to-persona matching

- Add AnalysisProvider context component for managing analysis state across dashboard views
- Improve ResultsView persona matching — match by personaProfile.name or personaId instead of index
- Update SetupView layout with refactored persona flow integration
- Overhaul useAnalysisFlow hook with improved state machine for simulation lifecycle
- Add computeBenchmarks utility for persona analysis comparison metrics
- Add benchmark unit tests
…ntity graph retrieval

- Generalize IdRagStore to support both backstory and interview signal chunks
- Add chunkBackstory with topic detection (early-life, career, finance, setback, etc.) and emotional tone analysis
- Add linkRelated — cross-chunk adjacency and same-topic linking for identity graph traversal
- Add interview signal chunking pipeline (chunkInterviewSignals)
- Add n-gram fingerprinting and cosine similarity for in-memory semantic retrieval
- Add InterviewSignalExtractor — extracts structured signals from interview transcripts
- Add PsychographicRationalizer (PB&J) — enhances persona backstories with psychological rationales
- Add generatePersonasFromInterviews server action — end-to-end pipeline from transcripts to personas
- Add pooling and sampling utilities for transcript processing
- Add GazePredictionAdapter and InCharacterEvaluator for behavioral analysis
- Refactor IdRagService to use the generalized store for all persona context retrieval
…ona adapter, and pipeline

- Add PersonaAdapter unit tests for backstory generation and persona creation
- Add pricing-analysis-e2e test — end-to-end persona analysis of a live pricing page
- Add pricing-analysis-comprehensive test — multi-persona analysis with full scoring
- Add pricing-analysis-full-flow test — complete simulation lifecycle including streaming
- Add pricing-analysis-real-flow test — real-world flow with browser automation
- Add vitest setup file with global test configuration and mocks
- Add sonner dependency for toast notifications
- Update tsconfig with .next type includes and consistent formatting
- Add vitest setup file configuration for jsdom test environment
- Add opencode.yml workflow triggered by /oc and /opencode commands on issues and PRs
- Uses anomalyco/opencode/github action with deepseek-v4-flash model
…timeout during LLM batches

Adds a 4-second setInterval heartbeat that sends keep-alive stream updates when no real progress has been received for 3+ seconds. During Promise.allSettled extraction and batch generation, the function goes silent while waiting for parallel LLM calls — this silence triggers the Netlify serverless function timeout (10s default on legacy plans, 10s for streaming functions). The heartbeat keeps the RSC stream active by sending periodic '{ step, heartbeat: true }' updates, preventing the connection drop.
…pipelines (up to 15 min)

- Add netlify/functions/process-pipeline.ts — background function with config.background = true for 15-minute execution limit
- Add PipelineStore — durable pipeline state persistence via Netlify Blobs (cross-instance, cross-invocation)
- Add startPipeline server action — stores input data in Blobs, triggers background function via HTTP fetch, returns jobId
- Add getPipelineStatusAction — polling endpoint for background pipeline progress/results
- Rewrite useInterviewPipeline from streaming to polling pattern — submits job, polls every 2s
- Add @netlify/blobs dependency for shared state storage
- Configure netlify.toml with background function settings
…nstead of raw Blobs fetch

The background function was using raw fetch to Netlify Blobs which required NETLIFY_ACCESS_TOKEN — not automatically set in the function env. PipelineStore uses @netlify/blobs which auto-configures auth inside Netlify Functions. PipelineStore.ts has zero @/ imports so the relative import resolves correctly through the function bundler.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants