@indexnetwork/protocol 3.6.3-rc.269.1 → 3.6.3-rc.272.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -26
- package/dist/agent/tests/fakes.d.ts.map +1 -1
- package/dist/agent/tests/fakes.js.map +1 -1
- package/dist/chat/chat.agent.d.ts.map +1 -1
- package/dist/chat/chat.agent.js +3 -3
- package/dist/chat/chat.agent.js.map +1 -1
- package/dist/chat/chat.streamer.d.ts.map +1 -1
- package/dist/chat/chat.streamer.js +1 -1
- package/dist/chat/chat.streamer.js.map +1 -1
- package/dist/chat/chat.summarizer.d.ts.map +1 -1
- package/dist/chat/chat.summarizer.js +1 -1
- package/dist/chat/chat.summarizer.js.map +1 -1
- package/dist/chat/tests/chat.graph.mocks.d.ts.map +1 -1
- package/dist/chat/tests/chat.graph.mocks.js +0 -1
- package/dist/chat/tests/chat.graph.mocks.js.map +1 -1
- package/dist/index.d.ts +21 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -10
- package/dist/index.js.map +1 -1
- package/dist/intent/intent.graph.js +1 -1
- package/dist/intent/intent.graph.js.map +1 -1
- package/dist/maintenance/maintenance.graph.d.ts.map +1 -1
- package/dist/maintenance/maintenance.graph.js +1 -1
- package/dist/maintenance/maintenance.graph.js.map +1 -1
- package/dist/negotiation/negotiation.agent.d.ts.map +1 -1
- package/dist/negotiation/negotiation.agent.js +1 -1
- package/dist/negotiation/negotiation.agent.js.map +1 -1
- package/dist/negotiation/negotiation.summarizer.d.ts.map +1 -1
- package/dist/negotiation/negotiation.summarizer.js +1 -1
- package/dist/negotiation/negotiation.summarizer.js.map +1 -1
- package/dist/network/indexer/indexer.graph.d.ts.map +1 -1
- package/dist/network/indexer/indexer.graph.js +2 -2
- package/dist/network/indexer/indexer.graph.js.map +1 -1
- package/dist/opportunity/discovery-question.helper.d.ts.map +1 -1
- package/dist/opportunity/discovery-question.helper.js.map +1 -1
- package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.graph.js +1 -1
- package/dist/opportunity/feed/feed.graph.js.map +1 -1
- package/dist/opportunity/negotiation-summary.builder.d.ts.map +1 -1
- package/dist/opportunity/negotiation-summary.builder.js.map +1 -1
- package/dist/opportunity/opportunity.discover.d.ts.map +1 -1
- package/dist/opportunity/opportunity.discover.js +1 -1
- package/dist/opportunity/opportunity.discover.js.map +1 -1
- package/dist/opportunity/opportunity.enricher.d.ts.map +1 -1
- package/dist/opportunity/opportunity.enricher.js.map +1 -1
- package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
- package/dist/opportunity/opportunity.graph.js +5 -5
- package/dist/opportunity/opportunity.graph.js.map +1 -1
- package/dist/opportunity/opportunity.persist.d.ts.map +1 -1
- package/dist/opportunity/opportunity.persist.js.map +1 -1
- package/dist/opportunity/question.generator.d.ts.map +1 -1
- package/dist/opportunity/question.generator.js +2 -2
- package/dist/opportunity/question.generator.js.map +1 -1
- package/dist/premise/premise.graph.d.ts.map +1 -1
- package/dist/premise/premise.graph.js +1 -1
- package/dist/premise/premise.graph.js.map +1 -1
- package/dist/profile/profile.graph.js +1 -1
- package/dist/profile/profile.graph.js.map +1 -1
- package/dist/questioner/questioner.agent.d.ts.map +1 -1
- package/dist/questioner/questioner.agent.js +1 -1
- package/dist/questioner/questioner.agent.js.map +1 -1
- package/dist/questioner/questioner.presets.d.ts.map +1 -1
- package/dist/questioner/questioner.presets.js +1 -1
- package/dist/questioner/questioner.presets.js.map +1 -1
- package/dist/shared/agent/response.streamer.d.ts.map +1 -1
- package/dist/shared/agent/response.streamer.js +1 -1
- package/dist/shared/agent/response.streamer.js.map +1 -1
- package/dist/shared/agent/tool.factory.d.ts.map +1 -1
- package/dist/shared/agent/tool.factory.js +1 -1
- package/dist/shared/agent/tool.factory.js.map +1 -1
- package/dist/shared/agent/tool.helpers.d.ts.map +1 -1
- package/dist/shared/agent/tool.helpers.js.map +1 -1
- package/dist/shared/assignment/network-assignment.policy.d.ts.map +1 -1
- package/dist/shared/assignment/network-assignment.policy.js.map +1 -1
- package/dist/shared/interfaces/questioner.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/questioner.interface.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile.graph.js","sourceRoot":"/","sources":["profile/profile.graph.ts"],"names":[],"mappings":"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","sourcesContent":["import { StateGraph, START, END } from \"@langchain/langgraph\";\nimport { ProfileGraphState } from \"./profile.state.js\";\nimport { ProfileGenerator, ProfileDocument } from \"./profile.generator.js\";\nimport { ProfileGraphDatabase, PremiseRecord, PremiseProvenance } from \"../shared/interfaces/database.interface.js\";\nimport { Scraper } from \"../shared/interfaces/scraper.interface.js\";\nimport type { ProfileEnricher } from \"../shared/interfaces/enrichment.interface.js\";\nimport { shouldEnrichGhostDisplayNameFromParallel, isEnrichedNameMeaningful } from \"./profile.enricher.js\";\nimport { socialsToEnrichmentRequest } from \"../shared/utils/social-label.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport type { QuestionerEnqueueFn } from \"../questioner/questioner.types.js\";\nimport { timed } from \"../shared/observability/performance.js\";\nimport { requestContext } from \"../shared/observability/request-context.js\";\nimport type { DebugMetaAgent } from \"../chat/chat-streaming.types.js\";\nimport { PremiseDecomposer } from \"../premise/premise.decomposer.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\n\n/**\n * Compiled premise graph interface. Matches the invoke signature of a compiled LangGraph.\n * Accepted as an optional dependency so write-mode input can be decomposed into premises.\n */\nexport interface CompiledPremiseGraph {\n invoke(input: {\n userId: string;\n assertionText: string;\n tier: 'assertive' | 'contextual';\n operationMode: 'create';\n provenanceSource?: PremiseProvenance['source'];\n provenanceSourceId?: string;\n }): Promise<{\n premise?: { id: string } | undefined;\n error?: string | undefined;\n }>;\n}\n\nconst logger = protocolLogger(\"ProfileGraphFactory\");\n\n/** Minimum length for input to be considered meaningful (e.g. not just \"Yes\") */\nconst MIN_MEANINGFUL_INPUT_LENGTH = 20;\n\n/** Phrases that are confirmations only and must not be used as profile content */\nconst CONFIRMATION_PHRASES = new Set([\n \"yes\", \"yeah\", \"yep\", \"sure\", \"ok\", \"okay\", \"go ahead\", \"do it\", \"please\",\n \"correct\", \"right\", \"exactly\", \"absolutely\", \"of course\", \"sounds good\",\n \"create one\", \"create it\", \"set one up\", \"set it up\", \"create my profile\",\n \"create profile\", \"set up profile\", \"create a profile\"\n]);\n\n/**\n * Returns true only if the input contains real profile information.\n * Confirmation-only replies (e.g. \"Yes\" to \"Would you like to create a profile?\")\n * must not be treated as input so we ask for user info / use scraper instead of inventing a profile.\n */\nfunction isMeaningfulProfileInput(input: string | undefined): boolean {\n if (!input || typeof input !== \"string\") return false;\n const trimmed = input.trim();\n if (trimmed.length < MIN_MEANINGFUL_INPUT_LENGTH) return false;\n const lower = trimmed.toLowerCase();\n if (CONFIRMATION_PHRASES.has(lower)) return false;\n if (CONFIRMATION_PHRASES.has(lower.replace(/[.!?]+$/, \"\"))) return false;\n return true;\n}\n\n\n/**\n * Factory class to build and compile the Profile Generation Graph.\n *\n * Flow:\n * 1. check_state - Detect whether profile needs generation\n * 2. Conditional routing based on operation mode and missing components:\n * - Query mode: Return immediately (fast path)\n * - Write mode: Generate only what's needed\n * 3. Profile generation (if needed)\n * 4. Save profile to DB\n *\n * Key Features:\n * - Read/Write separation (query vs write)\n * - Conditional generation (skip generation if profile already exists)\n */\nexport class ProfileGraphFactory {\n constructor(\n private database: ProfileGraphDatabase,\n private scraper: Scraper,\n private enricher?: ProfileEnricher,\n private questionerEnqueue?: QuestionerEnqueueFn,\n private premiseGraph?: CompiledPremiseGraph,\n ) { }\n\n public createGraph() {\n const profileGenerator = new ProfileGenerator();\n const premiseDecomposer = new PremiseDecomposer();\n\n // ─────────────────────────────────────────────────────────\n // NODE: Check State\n // Loads existing profile from DB and detects what needs generation:\n // - Profile missing\n // - User information insufficient for scraping\n // ─────────────────────────────────────────────────────────\n const checkStateNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.checkState\", async () => {\n if (!state.userId) {\n logger.error(\"Missing userId\");\n return {\n error: \"userId is required\"\n };\n }\n\n logger.verbose(\"Checking profile state...\", {\n userId: state.userId,\n operationMode: state.operationMode,\n forceUpdate: state.forceUpdate\n });\n\n try {\n const profile = await this.database.getProfile(state.userId) as any;\n\n // Query mode: Just return the profile (fast path)\n if (state.operationMode === 'query') {\n logger.verbose(\"🚀 Query mode - returning existing profile (fast path)\", {\n hasProfile: !!profile\n });\n const profileWithId = profile ? await this.database.getProfileByUserId(state.userId) : null;\n return {\n profile: profile || undefined,\n readResult: profile\n ? {\n hasProfile: true,\n profile: {\n id: profileWithId?.id,\n name: profile.identity?.name,\n bio: profile.identity?.bio,\n location: profile.identity?.location,\n skills: profile.attributes?.skills,\n interests: profile.attributes?.interests,\n },\n }\n : {\n hasProfile: false,\n message:\n \"You don't have a profile yet. Would you like to create one? You can share your LinkedIn, GitHub, or X/Twitter profile, or just tell me about yourself.\",\n },\n };\n }\n\n // Write mode: Detect what needs generation\n // Treat confirmation-only input (e.g. \"Yes\") as no input so we ask for info / use scraper\n const hasMeaningfulInput = !!state.input && isMeaningfulProfileInput(state.input);\n const needsProfileGeneration = !profile || (state.forceUpdate && hasMeaningfulInput);\n\n // Check if we need to scrape (profile generation needed but no meaningful input provided)\n const willNeedScraping = needsProfileGeneration && !hasMeaningfulInput;\n\n // If we need to scrape, check if we have sufficient user information\n let needsUserInfo = false;\n let missingUserInfo: string[] = [];\n\n if (willNeedScraping) {\n logger.verbose(\"Will need scraping - checking user information...\");\n\n const user = await this.database.getUser(state.userId);\n\n if (!user) {\n logger.error(\"User not found\", { userId: state.userId });\n return {\n error: `User not found: ${state.userId}`\n };\n }\n\n // Check what information we have from the user table (schema: users)\n // Required fields: email, name (always present)\n // Optional fields: intro, avatar, location, socials\n\n const socials = await this.database.getUserSocials(state.userId);\n const hasSocials = socials.length > 0;\n\n // Check if name is a full name (not just email username)\n // For scraping to work well, we need first + last name\n const hasMeaningfulName = user.name &&\n user.name.trim() !== '' &&\n !user.name.includes('@') &&\n user.name.split(/\\s+/).filter(Boolean).length >= 2;\n\n const hasLocation = !!(user.location && user.location.trim() !== '');\n\n // Minimum requirement for accurate scraping:\n // - At least ONE social link (preferred - most reliable for finding the right person)\n // - OR a full name (first + last) - less reliable but workable\n // Location helps disambiguate but is not required\n\n const hasMinimumInfo = hasSocials || hasMeaningfulName;\n\n if (!hasMinimumInfo) {\n needsUserInfo = true;\n\n // Build precise list of what's missing and would help\n if (!hasSocials) {\n missingUserInfo.push('social_urls');\n }\n if (!hasMeaningfulName) {\n missingUserInfo.push('full_name');\n }\n if (!hasLocation) {\n missingUserInfo.push('location'); // Nice to have\n }\n\n logger.verbose(\"⚠️ Insufficient user information for scraping\", {\n hasSocials,\n hasMeaningfulName,\n hasLocation,\n currentName: user.name,\n missingUserInfo\n });\n } else {\n logger.verbose(\"✅ Sufficient user information for scraping\", {\n hasSocials,\n hasMeaningfulName,\n hasLocation,\n willProceedWith: hasSocials ? 'social links' : 'full name'\n });\n }\n }\n\n logger.verbose(\"📊 State detection complete\", {\n hasProfile: !!profile,\n needsProfileGeneration,\n needsUserInfo,\n missingUserInfo,\n forceUpdate: state.forceUpdate,\n hasInput: !!state.input,\n hasMeaningfulInput,\n });\n\n return {\n profile: profile || undefined,\n needsProfileGeneration,\n needsUserInfo,\n missingUserInfo\n };\n } catch (error) {\n logger.error(\"Failed to load profile\", {\n error: error instanceof Error ? error.message : String(error)\n });\n return {\n profile: undefined,\n error: `Failed to load profile from database: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Scrape\n // Scrapes data from web if input is not provided\n // ─────────────────────────────────────────────────────────\n const scrapeNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.scrape\", async () => {\n if (state.input && isMeaningfulProfileInput(state.input)) {\n logger.verbose(\"Meaningful input already provided - skipping scrape\");\n return {};\n }\n\n logger.verbose(\"Starting web scrape...\", {\n userId: state.userId\n });\n\n try {\n // Fetch user details to construct objective for web scraping\n const user = await this.database.getUser(state.userId);\n\n if (!user) {\n logger.error(\"User not found\", { userId: state.userId });\n return {\n error: `User not found: ${state.userId}`\n };\n }\n\n // Build scraping objective from available user information\n // Priority: social links (most reliable) > name + location > email\n const socialParts: string[] = [];\n const socials = await this.database.getUserSocials(state.userId);\n for (const s of socials) {\n switch (s.label) {\n case 'twitter': socialParts.push(`X/Twitter: ${s.value}`); break;\n case 'linkedin': socialParts.push(`LinkedIn: ${s.value}`); break;\n case 'github': socialParts.push(`GitHub: ${s.value}`); break;\n case 'telegram': socialParts.push(`Telegram: ${s.value}`); break;\n default: socialParts.push(`Website: ${s.value}`); break;\n }\n }\n\n // Construct objective based on what we have\n let objective = `Find information about ${user.name || 'this person'}`;\n\n if (user.location) {\n objective += ` located in ${user.location}`;\n }\n\n objective += '.\\n\\n';\n\n if (socialParts.length > 0) {\n objective += `Their social profiles:\\n${socialParts.join('\\n')}\\n\\n`;\n objective += 'Use these links to find accurate information about their professional background, skills, and interests.';\n } else if (user.email) {\n objective += `Their email: ${user.email}\\n\\n`;\n objective += 'Search for professional information, skills, and background about this person.';\n } else {\n objective += 'Search for professional information and background about this person.';\n }\n\n logger.verbose(\"Constructed scraping objective\", {\n hasSocials: socialParts.length > 0,\n hasLocation: !!user.location,\n objectivePreview: objective.substring(0, 100)\n });\n\n const scrapedData = await this.scraper.scrape(objective);\n\n logger.verbose(\"✅ Scrape complete\", {\n dataLength: scrapedData?.length || 0\n });\n\n return {\n objective,\n input: scrapedData,\n activeSocialIds: socials.map(s => s.id),\n operationsPerformed: { scraped: true }\n };\n } catch (error) {\n logger.error(\"Scrape failed\", {\n error: error instanceof Error ? error.message : String(error)\n });\n return {\n error: `Web scrape failed: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Auto-Generate (Parallel Chat API enrichment)\n // Calls enrichUserProfile to get structured data, then builds a\n // text blob as input for the decompose → aggregate → generate\n // pipeline. This ensures enriched users get premises with\n // embeddings, making them discoverable via premise-to-premise\n // matching.\n // On failure, falls back to basic user info for LLM generation.\n // Used in 'generate' mode only.\n // ─────────────────────────────────────────────────────────\n const autoGenerateNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.autoGenerate\", async () => {\n logger.verbose(\"Starting auto-generate via Chat API enrichment\", {\n userId: state.userId,\n });\n\n try {\n const user = await this.database.getUser(state.userId);\n if (!user) {\n logger.error(\"User not found for auto-generate\", { userId: state.userId });\n return { error: `User not found: ${state.userId}` };\n }\n\n const socials = await this.database.getUserSocials(state.userId);\n const enrichmentSocials = socialsToEnrichmentRequest(socials);\n const request = {\n name: user.name || undefined,\n email: user.email || undefined,\n linkedin: enrichmentSocials.linkedin || undefined,\n twitter: enrichmentSocials.twitter || undefined,\n github: enrichmentSocials.github || undefined,\n telegram: enrichmentSocials.telegram || undefined,\n websites: enrichmentSocials.websites?.length ? enrichmentSocials.websites : undefined,\n };\n\n const buildBasicInfo = () => {\n const parts = [\n user.name ? `Name: ${user.name}` : '',\n user.email ? `Email: ${user.email}` : '',\n user.location ? `Location: ${user.location}` : '',\n user.intro ? `Bio: ${user.intro}` : '',\n ].filter(Boolean).join('\\n');\n return parts || \"No information available\";\n };\n\n if (!this.enricher) {\n logger.warn(\"No enricher configured — falling back to basic info\", { userId: state.userId });\n return {\n input: buildBasicInfo(),\n needsUserInfo: false,\n needsProfileGeneration: true,\n operationsPerformed: { scraped: true },\n };\n }\n\n try {\n const enrichment = await this.enricher.enrichUserProfile(request);\n\n if (enrichment && !enrichment.isHuman) {\n logger.info(\"Enrichment detected non-human entity, soft-deleting ghost\", { userId: state.userId });\n await this.database.softDeleteGhost(state.userId);\n return { error: \"Non-human entity detected\" };\n }\n\n const hasMeaningfulEnrichment = !!enrichment &&\n enrichment.confidentMatch &&\n (\n enrichment.identity.bio.trim().length > 0 ||\n enrichment.narrative.context.trim().length > 0 ||\n enrichment.attributes.skills.length > 0 ||\n enrichment.attributes.interests.length > 0\n );\n\n if (hasMeaningfulEnrichment) {\n if (user.isGhost && !isEnrichedNameMeaningful(user.email || '', enrichment!.identity.name || '')) {\n logger.info(\"Enrichment has content but no real name for ghost, soft-deleting\", { userId: state.userId });\n await this.database.softDeleteGhost(state.userId);\n return { error: \"No real name found for ghost user\" };\n }\n\n logger.verbose(\"Chat API enrichment succeeded\", {\n userId: state.userId,\n skillsCount: enrichment!.attributes.skills.length,\n interestsCount: enrichment!.attributes.interests.length,\n });\n\n // Update user record with enriched data\n const updatePayload: {\n name?: string;\n intro?: string;\n location?: string;\n } = {};\n const enrichedName = enrichment!.identity.name?.trim();\n if (\n enrichedName &&\n shouldEnrichGhostDisplayNameFromParallel(\n { isGhost: !!user.isGhost, name: user.name ?? '', email: user.email ?? '' },\n enrichedName,\n )\n ) {\n updatePayload.name = enrichedName;\n }\n if (enrichment!.identity.bio?.trim()) updatePayload.intro = enrichment!.identity.bio.trim();\n if (enrichment!.identity.location?.trim()) updatePayload.location = enrichment!.identity.location.trim();\n\n const enrichedSocials: { label: string; value: string }[] = [];\n if (enrichment!.socials.twitter) enrichedSocials.push({ label: 'twitter', value: enrichment!.socials.twitter });\n if (enrichment!.socials.linkedin) enrichedSocials.push({ label: 'linkedin', value: enrichment!.socials.linkedin });\n if (enrichment!.socials.github) enrichedSocials.push({ label: 'github', value: enrichment!.socials.github });\n if (enrichment!.socials.telegram) enrichedSocials.push({ label: 'telegram', value: enrichment!.socials.telegram });\n if (enrichment!.socials.websites?.length) {\n for (const w of enrichment!.socials.websites) enrichedSocials.push({ label: 'custom', value: w });\n }\n if (enrichedSocials.length > 0) {\n const existingSocials = await this.database.getUserSocials(state.userId);\n const enrichedLabels = new Set(enrichedSocials.map(s => s.label));\n const kept = existingSocials\n .filter(s => !enrichedLabels.has(s.label) || s.label === 'custom')\n .map(s => ({ label: s.label, value: s.value }));\n const merged = enrichedLabels.has('custom')\n ? [...kept.filter(s => s.label !== 'custom'), ...enrichedSocials]\n : [...kept, ...enrichedSocials];\n await this.database.setUserSocials(state.userId, merged);\n }\n\n if (Object.keys(updatePayload).length > 0) {\n await this.database.updateUser(state.userId, updatePayload);\n }\n\n // Post-enrichment dedup: check if this ghost matches an existing user\n if (user.isGhost) {\n const currentSocials = await this.database.getUserSocials(state.userId);\n const duplicate = await this.database.findDuplicateUser(state.userId, currentSocials);\n if (duplicate) {\n logger.info(\"Post-enrichment dedup: merging ghost into existing user\", {\n ghostId: state.userId,\n targetId: duplicate.id,\n });\n await this.database.mergeGhostUser(state.userId, duplicate.id);\n return { error: `Merged as duplicate of user ${duplicate.id}` };\n }\n }\n\n // Build a text blob from the enrichment result so it flows\n // through premise decomposition (when available) rather than\n // bypassing premises via prePopulatedProfile.\n const enrichmentParts = [\n enrichment!.identity.name ? `My name is ${enrichment!.identity.name}.` : '',\n enrichment!.identity.location ? `I am based in ${enrichment!.identity.location}.` : '',\n enrichment!.identity.bio || '',\n enrichment!.narrative.context || '',\n enrichment!.attributes.skills.length ? `My skills include ${enrichment!.attributes.skills.join(', ')}.` : '',\n enrichment!.attributes.interests.length ? `My interests include ${enrichment!.attributes.interests.join(', ')}.` : '',\n ].filter(Boolean).join('\\n');\n\n return {\n input: enrichmentParts,\n needsUserInfo: false,\n needsProfileGeneration: true,\n forceUpdate: true,\n activeSocialIds: socials.map(s => s.id),\n operationsPerformed: { scraped: true },\n };\n }\n\n if (user.isGhost) {\n logger.info(\"Low-confidence enrichment for ghost, soft-deleting\", { userId: state.userId });\n await this.database.softDeleteGhost(state.userId);\n return { error: \"Enrichment not confident for ghost user\" };\n }\n logger.warn(\"Chat API returned low-signal enrichment, falling back to basic info\", { userId: state.userId });\n } catch (enrichErr) {\n if (user.isGhost) {\n logger.info(\"Enrichment failed for ghost, soft-deleting\", { userId: state.userId });\n await this.database.softDeleteGhost(state.userId);\n return { error: \"Enrichment failed for ghost user\" };\n }\n logger.warn(\"Chat API enrichment failed, falling back to basic info\", {\n userId: state.userId,\n error: enrichErr instanceof Error ? enrichErr.message : String(enrichErr),\n });\n }\n\n return {\n input: buildBasicInfo(),\n needsUserInfo: false,\n needsProfileGeneration: true,\n operationsPerformed: { scraped: true },\n };\n } catch (err) {\n logger.error(\"Auto-generate failed\", {\n error: err instanceof Error ? err.message : String(err),\n });\n return { error: `Auto-generate failed: ${err instanceof Error ? err.message : String(err)}` };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Generate Profile\n // Generates profile from input using ProfileGenerator agent.\n // If updating existing profile, merges new information intelligently.\n // ─────────────────────────────────────────────────────────\n const generateProfileNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.generateProfile\", async () => {\n if (!state.input) {\n logger.error(\"No input provided for profile generation\");\n return {\n error: \"Input required for profile generation\"\n };\n }\n\n logger.verbose(\"Starting profile generation...\", {\n hasExistingProfile: !!state.profile,\n isUpdate: state.forceUpdate,\n inputLength: state.input.length\n });\n\n const agentTimingsAccum: DebugMetaAgent[] = [];\n\n try {\n // If updating existing profile, include it in the input for context\n let inputWithContext = state.input;\n if (state.profile && state.forceUpdate) {\n if (state.isAggregate) {\n inputWithContext = `EXISTING PROFILE:\\n${JSON.stringify(state.profile, null, 2)}\\n\\nPREMISE SYNTHESIS:\\n${state.input}\\n\\nRegenerate the profile by synthesizing the premises above. Use the existing profile as context for continuity, but the premises are the authoritative source. Output the full updated profile.`;\n logger.verbose(\"Aggregate synthesis with existing profile context\");\n } else {\n inputWithContext = `EXISTING PROFILE:\\n${JSON.stringify(state.profile, null, 2)}\\n\\nUSER REQUEST:\\n${state.input}\\n\\nApply the user's request to the existing profile. Preserve existing data unless the user asks to change or remove it. You may add, update, or remove skills and interests as requested. Output the full updated profile.`;\n logger.verbose(\"Merging with existing profile\");\n }\n }\n\n const _traceEmitterProfileGen = requestContext.getStore()?.traceEmitter;\n const profileGeneratorStart = Date.now();\n _traceEmitterProfileGen?.({ type: \"agent_start\", name: \"profile-generator\" });\n const result = await profileGenerator.invoke(inputWithContext);\n agentTimingsAccum.push({ name: 'profile.generator', durationMs: Date.now() - profileGeneratorStart });\n _traceEmitterProfileGen?.({ type: \"agent_end\", name: \"profile-generator\", durationMs: Date.now() - profileGeneratorStart, summary: `Generated profile for ${result.output.identity.name || \"user\"}` });\n\n logger.verbose(\"✅ Profile generated successfully\", {\n name: result.output.identity.name,\n skillsCount: result.output.attributes.skills.length,\n interestsCount: result.output.attributes.interests.length\n });\n\n return {\n profile: {\n ...result.output,\n userId: state.userId,\n },\n agentTimings: agentTimingsAccum,\n operationsPerformed: { generatedProfile: true }\n };\n } catch (error) {\n logger.error(\"Profile generation failed\", {\n error: error instanceof Error ? error.message : String(error)\n });\n return {\n error: `Profile generation failed: ${error instanceof Error ? error.message : String(error)}`,\n agentTimings: agentTimingsAccum\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Save Profile\n // Saves the generated profile to DB (no embedding)\n // ─────────────────────────────────────────────────────────\n const saveProfileNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.saveProfile\", async () => {\n if (!state.profile || !state.profile.identity) {\n logger.error(\"Profile or identity missing in save step\");\n return {\n error: \"Profile missing in save step\"\n };\n }\n\n logger.verbose(\"Saving profile to DB...\", {\n userId: state.userId\n });\n\n try {\n const profile = { ...state.profile };\n\n await this.database.saveProfile(state.userId, profile);\n\n logger.verbose(\"✅ Profile saved successfully\");\n\n // Fetch active premises so the questioner can see what's already covered\n let existingPremises: string[] = [];\n try {\n const activePremises = await this.database.getPremisesForUser(state.userId, 'ACTIVE');\n existingPremises = activePremises.map(p => p.assertion.text);\n logger.verbose(\"Fetched active premises for questioner context\", {\n userId: state.userId,\n count: existingPremises.length,\n });\n } catch (premiseErr) {\n logger.error(\"Failed to fetch premises for questioner context — continuing with empty list\", {\n userId: state.userId,\n error: premiseErr instanceof Error ? premiseErr.message : String(premiseErr),\n });\n }\n\n // Compute profile gaps from missing fields\n const gaps: string[] = [];\n if (!profile.identity?.location) gaps.push('location');\n if (!profile.attributes?.skills?.length) gaps.push('skills');\n if (!profile.attributes?.interests?.length) gaps.push('interests');\n if (!profile.narrative?.context) gaps.push('current work');\n\n if (gaps.length > 0 && this.questionerEnqueue) {\n this.questionerEnqueue({\n mode: 'profile',\n userId: state.userId,\n sourceType: 'profile',\n sourceId: state.userId,\n context: {\n userProfile: {\n name: profile.identity?.name,\n bio: profile.identity?.bio,\n location: profile.identity?.location,\n skills: profile.attributes?.skills,\n interests: profile.attributes?.interests,\n },\n gaps,\n existingPremises,\n },\n }).catch((err) =>\n logger.error('Failed to enqueue profile question generation', { userId: state.userId, error: err })\n );\n }\n\n return {\n profile,\n operationsPerformed: { savedProfile: true }\n };\n } catch (error) {\n logger.error(\"Failed to save profile\", {\n error: error instanceof Error ? error.message : String(error)\n });\n return {\n error: `Failed to save profile: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Aggregate Profile\n // Fetches the user's active premises and synthesizes them into profile input.\n // Sets state.input and flags so the existing generate_profile pipeline runs.\n // ─────────────────────────────────────────────────────────\n const aggregateProfileNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.aggregateProfile\", async () => {\n logger.verbose(\"Aggregating profile from premises...\", { userId: state.userId });\n\n const premises: PremiseRecord[] = await this.database.getPremisesForUser(state.userId, 'ACTIVE');\n\n if (premises.length === 0) {\n logger.verbose(\"No active premises found — skipping aggregate\");\n return { operationMode: 'query' as const };\n }\n\n const premiseTexts = premises.map(p => p.assertion.text);\n const aggregateInput = `The following are self-descriptions (premises) the user has asserted about themselves:\\n\\n${premiseTexts.map((t, i) => `${i + 1}. ${t}`).join('\\n')}\\n\\nSynthesize these into a cohesive profile.`;\n\n logger.verbose(`Aggregated ${premises.length} premise(s) into profile input`);\n\n return {\n input: aggregateInput,\n needsProfileGeneration: true,\n forceUpdate: true,\n isAggregate: true,\n };\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Decompose Premises\n // Decomposes free-text input (chat or scraped) into individual premises,\n // creates each via the premise graph, then routes to aggregate_profile\n // to synthesize the profile from all active premises.\n // ─────────────────────────────────────────────────────────\n const decomposePremisesNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.decomposePremises\", async () => {\n if (!state.input) {\n logger.error(\"No input for premise decomposition\");\n return { error: \"Input required for premise decomposition\" };\n }\n\n if (!this.premiseGraph) {\n // Fallback: if no premise graph is available, skip decomposition\n // and route directly to profile generation (legacy behavior)\n logger.warn(\"No premise graph injected — falling back to direct profile generation\");\n return {\n needsProfileGeneration: true,\n forceUpdate: true,\n };\n }\n\n logger.verbose(\"Decomposing input into premises...\", {\n userId: state.userId,\n inputLength: state.input.length,\n });\n\n const agentTimingsAccum: DebugMetaAgent[] = [];\n\n try {\n const _traceEmitter = requestContext.getStore()?.traceEmitter;\n\n const decomposeStart = Date.now();\n _traceEmitter?.({ type: \"agent_start\", name: \"premise-decomposer\" });\n const result = await premiseDecomposer.invoke(state.input);\n const decomposeMs = Date.now() - decomposeStart;\n agentTimingsAccum.push({ name: \"premise.decomposer\", durationMs: decomposeMs });\n _traceEmitter?.({\n type: \"agent_end\",\n name: \"premise-decomposer\",\n durationMs: decomposeMs,\n summary: `Decomposed into ${result.premises.length} premise(s)`,\n });\n\n if (result.premises.length === 0) {\n logger.verbose(\"No premises extracted — skipping decomposition\");\n // No premises found; fall through to aggregate which will\n // synthesize from any existing premises, or to generate_profile\n // if needsProfileGeneration is still set from check_state\n return {\n operationMode: 'aggregate' as const,\n agentTimings: agentTimingsAccum,\n };\n }\n\n logger.verbose(`Creating ${result.premises.length} premise(s) via premise graph`, {\n userId: state.userId,\n });\n\n let created = 0;\n for (const p of result.premises) {\n try {\n const premiseResult = await invokeWithAbortSignal(this.premiseGraph, {\n userId: state.userId,\n assertionText: p.text,\n tier: p.tier,\n operationMode: 'create',\n ...(state.activeSocialIds?.length\n ? { provenanceSource: 'integration' as const, provenanceSourceId: state.activeSocialIds[0] }\n : {}),\n });\n\n if (premiseResult.premise) {\n created++;\n } else if (premiseResult.error) {\n logger.warn(\"Premise creation failed\", {\n text: p.text.substring(0, 60),\n error: premiseResult.error,\n });\n }\n } catch (err) {\n logger.warn(\"Premise creation threw\", {\n text: p.text.substring(0, 60),\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n logger.verbose(`Created ${created}/${result.premises.length} premise(s)`, {\n userId: state.userId,\n });\n\n // Route to aggregate mode to rebuild the profile from all active premises\n return {\n operationMode: 'aggregate' as const,\n agentTimings: agentTimingsAccum,\n operationsPerformed: { decomposedPremises: true },\n };\n } catch (err) {\n logger.error(\"Premise decomposition failed\", {\n error: err instanceof Error ? err.message : String(err),\n });\n // Fallback: route to direct profile generation\n return {\n needsProfileGeneration: true,\n forceUpdate: true,\n agentTimings: agentTimingsAccum,\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // ROUTING CONDITIONS\n // Smart conditional routing based on operation mode and missing components\n // ─────────────────────────────────────────────────────────\n\n /**\n * Route from check_state to next step based on operation mode and detected needs.\n */\n const checkStateCondition = (state: typeof ProfileGraphState.State): string => {\n // Query mode: Return immediately (fast path)\n if (state.operationMode === 'query') {\n logger.verbose(\"Query mode - ending (fast path)\");\n return END;\n }\n\n // Aggregate mode: Synthesize profile from active premises\n if (state.operationMode === 'aggregate') {\n logger.verbose(\"Aggregate mode - synthesizing profile from premises\");\n return \"aggregate_profile\";\n }\n\n // Generate mode: use enrichUserProfile Chat API to auto-generate\n if (state.operationMode === 'generate') {\n logger.verbose(\"Generate mode - routing to auto_generate\");\n return \"auto_generate\";\n }\n\n // Check if user information is insufficient for scraping\n // Return early so chat graph can request the missing information\n if (state.needsUserInfo) {\n logger.verbose(\"⚠️ Insufficient user info - requesting from user\", {\n missingInfo: state.missingUserInfo\n });\n return END;\n }\n\n // Write mode: Check what needs generation\n if (state.needsProfileGeneration) {\n // Only use provided input if it's meaningful (not just \"Yes\" / confirmation)\n if (state.input && isMeaningfulProfileInput(state.input)) {\n // Route through premise decomposition when a premise graph is available.\n // The decompose node extracts atomic premises, creates them, then\n // routes to aggregate_profile for profile synthesis.\n if (this.premiseGraph) {\n logger.verbose(\"Profile generation needed — decomposing input into premises\");\n return \"decompose_premises\";\n }\n logger.verbose(\"Profile generation needed with meaningful input provided\");\n return \"generate_profile\";\n } else {\n logger.verbose(\"Profile generation needed - scraping first (no meaningful input)\");\n return \"scrape\";\n }\n }\n\n // Everything exists and is up to date\n logger.verbose(\"All components exist - ending\");\n return END;\n };\n\n\n // ─────────────────────────────────────────────────────────\n // GRAPH ASSEMBLY\n // Conditional flow based on operation mode and detected needs\n // ─────────────────────────────────────────────────────────\n\n const workflow = new StateGraph(ProfileGraphState)\n // Add all nodes\n .addNode(\"check_state\", checkStateNode)\n .addNode(\"scrape\", scrapeNode)\n .addNode(\"decompose_premises\", decomposePremisesNode)\n .addNode(\"auto_generate\", autoGenerateNode)\n .addNode(\"aggregate_profile\", aggregateProfileNode)\n .addNode(\"generate_profile\", generateProfileNode)\n .addNode(\"save_profile\", saveProfileNode)\n\n // Start with state check\n .addEdge(START, \"check_state\")\n\n // Conditional routing from check_state\n .addConditionalEdges(\n \"check_state\",\n checkStateCondition,\n {\n auto_generate: \"auto_generate\", // Generate mode -> Chat API enrichment\n aggregate_profile: \"aggregate_profile\", // Aggregate mode -> synthesize from premises\n decompose_premises: \"decompose_premises\", // Write mode + input + premise graph -> decompose first\n scrape: \"scrape\", // Need profile, no input -> scrape first\n generate_profile: \"generate_profile\", // Need profile, have input -> generate (legacy, no premise graph)\n [END]: END // Query mode or everything exists\n }\n )\n\n // Decompose premises routes to aggregate (normal) or generate_profile (fallback)\n .addConditionalEdges(\n \"decompose_premises\",\n (state: typeof ProfileGraphState.State) => {\n if (state.operationMode === 'aggregate') return \"aggregate_profile\";\n // Fallback when decomposition failed (no premise graph or error)\n if (state.needsProfileGeneration) return \"generate_profile\";\n return \"aggregate_profile\";\n },\n {\n aggregate_profile: \"aggregate_profile\",\n generate_profile: \"generate_profile\",\n },\n )\n\n // Aggregate profile: generate if premises found, END if none\n .addConditionalEdges(\n \"aggregate_profile\",\n (state: typeof ProfileGraphState.State) => {\n if (state.needsProfileGeneration) return \"generate_profile\";\n logger.verbose(\"Aggregate mode — no premises, ending\");\n return END;\n },\n { generate_profile: \"generate_profile\", [END]: END },\n )\n\n // Auto-generate routes to decompose_premises (when premise graph\n // available) or generate_profile (legacy, no premise graph)\n .addConditionalEdges(\n \"auto_generate\",\n (state: typeof ProfileGraphState.State) => {\n if (state.input && this.premiseGraph) {\n logger.verbose(\"Enrichment produced input — routing to premise decomposition\");\n return \"decompose_premises\";\n }\n if (state.input) {\n logger.verbose(\"Enrichment produced input — routing to LLM generation (no premise graph)\");\n return \"generate_profile\";\n }\n logger.verbose(\"Enrichment ended without data (ghost soft-deleted or error) — done\");\n return END;\n },\n {\n decompose_premises: \"decompose_premises\",\n generate_profile: \"generate_profile\",\n [END]: END,\n }\n )\n\n // Scrape -> decompose_premises (when premise graph available) or generate_profile (legacy)\n .addConditionalEdges(\n \"scrape\",\n (_state: typeof ProfileGraphState.State) => {\n if (this.premiseGraph) return \"decompose_premises\";\n return \"generate_profile\";\n },\n {\n decompose_premises: \"decompose_premises\",\n generate_profile: \"generate_profile\",\n },\n )\n\n // Generate profile -> Save profile (linear)\n .addEdge(\"generate_profile\", \"save_profile\")\n\n // Save profile -> END (linear)\n .addEdge(\"save_profile\", END);\n\n logger.verbose(\"Graph built successfully\");\n return workflow.compile();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"profile.graph.js","sourceRoot":"/","sources":["profile/profile.graph.ts"],"names":[],"mappings":"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","sourcesContent":["import { StateGraph, START, END } from \"@langchain/langgraph\";\nimport { ProfileGraphState } from \"./profile.state.js\";\nimport { ProfileGenerator, ProfileDocument } from \"./profile.generator.js\";\nimport { ProfileGraphDatabase, PremiseRecord, PremiseProvenance } from \"../shared/interfaces/database.interface.js\";\nimport { Scraper } from \"../shared/interfaces/scraper.interface.js\";\nimport type { ProfileEnricher } from \"../shared/interfaces/enrichment.interface.js\";\nimport { shouldEnrichGhostDisplayNameFromParallel, isEnrichedNameMeaningful } from \"./profile.enricher.js\";\nimport { socialsToEnrichmentRequest } from \"../shared/utils/social-label.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport type { QuestionerEnqueueFn } from \"../questioner/questioner.types.js\";\nimport { timed } from \"../shared/observability/performance.js\";\nimport { requestContext } from \"../shared/observability/request-context.js\";\nimport type { DebugMetaAgent } from \"../chat/chat-streaming.types.js\";\nimport { PremiseDecomposer } from \"../premise/premise.decomposer.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\n\n/**\n * Compiled premise graph interface. Matches the invoke signature of a compiled LangGraph.\n * Accepted as an optional dependency so write-mode input can be decomposed into premises.\n */\nexport interface CompiledPremiseGraph {\n invoke(input: {\n userId: string;\n assertionText: string;\n tier: 'assertive' | 'contextual';\n operationMode: 'create';\n provenanceSource?: PremiseProvenance['source'];\n provenanceSourceId?: string;\n }): Promise<{\n premise?: { id: string } | undefined;\n error?: string | undefined;\n }>;\n}\n\nconst logger = protocolLogger(\"ProfileGraphFactory\");\n\n/** Minimum length for input to be considered meaningful (e.g. not just \"Yes\") */\nconst MIN_MEANINGFUL_INPUT_LENGTH = 20;\n\n/** Phrases that are confirmations only and must not be used as profile content */\nconst CONFIRMATION_PHRASES = new Set([\n \"yes\", \"yeah\", \"yep\", \"sure\", \"ok\", \"okay\", \"go ahead\", \"do it\", \"please\",\n \"correct\", \"right\", \"exactly\", \"absolutely\", \"of course\", \"sounds good\",\n \"create one\", \"create it\", \"set one up\", \"set it up\", \"create my profile\",\n \"create profile\", \"set up profile\", \"create a profile\"\n]);\n\n/**\n * Returns true only if the input contains real profile information.\n * Confirmation-only replies (e.g. \"Yes\" to \"Would you like to create a profile?\")\n * must not be treated as input so we ask for user info / use scraper instead of inventing a profile.\n */\nfunction isMeaningfulProfileInput(input: string | undefined): boolean {\n if (!input || typeof input !== \"string\") return false;\n const trimmed = input.trim();\n if (trimmed.length < MIN_MEANINGFUL_INPUT_LENGTH) return false;\n const lower = trimmed.toLowerCase();\n if (CONFIRMATION_PHRASES.has(lower)) return false;\n if (CONFIRMATION_PHRASES.has(lower.replace(/[.!?]+$/, \"\"))) return false;\n return true;\n}\n\n\n/**\n * Factory class to build and compile the Profile Generation Graph.\n *\n * Flow:\n * 1. check_state - Detect whether profile needs generation\n * 2. Conditional routing based on operation mode and missing components:\n * - Query mode: Return immediately (fast path)\n * - Write mode: Generate only what's needed\n * 3. Profile generation (if needed)\n * 4. Save profile to DB\n *\n * Key Features:\n * - Read/Write separation (query vs write)\n * - Conditional generation (skip generation if profile already exists)\n */\nexport class ProfileGraphFactory {\n constructor(\n private database: ProfileGraphDatabase,\n private scraper: Scraper,\n private enricher?: ProfileEnricher,\n private questionerEnqueue?: QuestionerEnqueueFn,\n private premiseGraph?: CompiledPremiseGraph,\n ) { }\n\n public createGraph() {\n const profileGenerator = new ProfileGenerator();\n const premiseDecomposer = new PremiseDecomposer();\n\n // ─────────────────────────────────────────────────────────\n // NODE: Check State\n // Loads existing profile from DB and detects what needs generation:\n // - Profile missing\n // - User information insufficient for scraping\n // ─────────────────────────────────────────────────────────\n const checkStateNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.checkState\", async () => {\n if (!state.userId) {\n logger.error(\"Missing userId\");\n return {\n error: \"userId is required\"\n };\n }\n\n logger.verbose(\"Checking profile state...\", {\n userId: state.userId,\n operationMode: state.operationMode,\n forceUpdate: state.forceUpdate\n });\n\n try {\n const profile = await this.database.getProfile(state.userId) as any;\n\n // Query mode: Just return the profile (fast path)\n if (state.operationMode === 'query') {\n logger.verbose(\"🚀 Query mode - returning existing profile (fast path)\", {\n hasProfile: !!profile\n });\n const profileWithId = profile ? await this.database.getProfileByUserId(state.userId) : null;\n return {\n profile: profile || undefined,\n readResult: profile\n ? {\n hasProfile: true,\n profile: {\n id: profileWithId?.id,\n name: profile.identity?.name,\n bio: profile.identity?.bio,\n location: profile.identity?.location,\n skills: profile.attributes?.skills,\n interests: profile.attributes?.interests,\n },\n }\n : {\n hasProfile: false,\n message:\n \"You don't have a profile yet. Would you like to create one? You can share your LinkedIn, GitHub, or X/Twitter profile, or just tell me about yourself.\",\n },\n };\n }\n\n // Write mode: Detect what needs generation\n // Treat confirmation-only input (e.g. \"Yes\") as no input so we ask for info / use scraper\n const hasMeaningfulInput = !!state.input && isMeaningfulProfileInput(state.input);\n const needsProfileGeneration = !profile || (state.forceUpdate && hasMeaningfulInput);\n\n // Check if we need to scrape (profile generation needed but no meaningful input provided)\n const willNeedScraping = needsProfileGeneration && !hasMeaningfulInput;\n\n // If we need to scrape, check if we have sufficient user information\n let needsUserInfo = false;\n const missingUserInfo: string[] = [];\n\n if (willNeedScraping) {\n logger.verbose(\"Will need scraping - checking user information...\");\n\n const user = await this.database.getUser(state.userId);\n\n if (!user) {\n logger.error(\"User not found\", { userId: state.userId });\n return {\n error: `User not found: ${state.userId}`\n };\n }\n\n // Check what information we have from the user table (schema: users)\n // Required fields: email, name (always present)\n // Optional fields: intro, avatar, location, socials\n\n const socials = await this.database.getUserSocials(state.userId);\n const hasSocials = socials.length > 0;\n\n // Check if name is a full name (not just email username)\n // For scraping to work well, we need first + last name\n const hasMeaningfulName = user.name &&\n user.name.trim() !== '' &&\n !user.name.includes('@') &&\n user.name.split(/\\s+/).filter(Boolean).length >= 2;\n\n const hasLocation = !!(user.location && user.location.trim() !== '');\n\n // Minimum requirement for accurate scraping:\n // - At least ONE social link (preferred - most reliable for finding the right person)\n // - OR a full name (first + last) - less reliable but workable\n // Location helps disambiguate but is not required\n\n const hasMinimumInfo = hasSocials || hasMeaningfulName;\n\n if (!hasMinimumInfo) {\n needsUserInfo = true;\n\n // Build precise list of what's missing and would help\n if (!hasSocials) {\n missingUserInfo.push('social_urls');\n }\n if (!hasMeaningfulName) {\n missingUserInfo.push('full_name');\n }\n if (!hasLocation) {\n missingUserInfo.push('location'); // Nice to have\n }\n\n logger.verbose(\"⚠️ Insufficient user information for scraping\", {\n hasSocials,\n hasMeaningfulName,\n hasLocation,\n currentName: user.name,\n missingUserInfo\n });\n } else {\n logger.verbose(\"✅ Sufficient user information for scraping\", {\n hasSocials,\n hasMeaningfulName,\n hasLocation,\n willProceedWith: hasSocials ? 'social links' : 'full name'\n });\n }\n }\n\n logger.verbose(\"📊 State detection complete\", {\n hasProfile: !!profile,\n needsProfileGeneration,\n needsUserInfo,\n missingUserInfo,\n forceUpdate: state.forceUpdate,\n hasInput: !!state.input,\n hasMeaningfulInput,\n });\n\n return {\n profile: profile || undefined,\n needsProfileGeneration,\n needsUserInfo,\n missingUserInfo\n };\n } catch (error) {\n logger.error(\"Failed to load profile\", {\n error: error instanceof Error ? error.message : String(error)\n });\n return {\n profile: undefined,\n error: `Failed to load profile from database: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Scrape\n // Scrapes data from web if input is not provided\n // ─────────────────────────────────────────────────────────\n const scrapeNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.scrape\", async () => {\n if (state.input && isMeaningfulProfileInput(state.input)) {\n logger.verbose(\"Meaningful input already provided - skipping scrape\");\n return {};\n }\n\n logger.verbose(\"Starting web scrape...\", {\n userId: state.userId\n });\n\n try {\n // Fetch user details to construct objective for web scraping\n const user = await this.database.getUser(state.userId);\n\n if (!user) {\n logger.error(\"User not found\", { userId: state.userId });\n return {\n error: `User not found: ${state.userId}`\n };\n }\n\n // Build scraping objective from available user information\n // Priority: social links (most reliable) > name + location > email\n const socialParts: string[] = [];\n const socials = await this.database.getUserSocials(state.userId);\n for (const s of socials) {\n switch (s.label) {\n case 'twitter': socialParts.push(`X/Twitter: ${s.value}`); break;\n case 'linkedin': socialParts.push(`LinkedIn: ${s.value}`); break;\n case 'github': socialParts.push(`GitHub: ${s.value}`); break;\n case 'telegram': socialParts.push(`Telegram: ${s.value}`); break;\n default: socialParts.push(`Website: ${s.value}`); break;\n }\n }\n\n // Construct objective based on what we have\n let objective = `Find information about ${user.name || 'this person'}`;\n\n if (user.location) {\n objective += ` located in ${user.location}`;\n }\n\n objective += '.\\n\\n';\n\n if (socialParts.length > 0) {\n objective += `Their social profiles:\\n${socialParts.join('\\n')}\\n\\n`;\n objective += 'Use these links to find accurate information about their professional background, skills, and interests.';\n } else if (user.email) {\n objective += `Their email: ${user.email}\\n\\n`;\n objective += 'Search for professional information, skills, and background about this person.';\n } else {\n objective += 'Search for professional information and background about this person.';\n }\n\n logger.verbose(\"Constructed scraping objective\", {\n hasSocials: socialParts.length > 0,\n hasLocation: !!user.location,\n objectivePreview: objective.substring(0, 100)\n });\n\n const scrapedData = await this.scraper.scrape(objective);\n\n logger.verbose(\"✅ Scrape complete\", {\n dataLength: scrapedData?.length || 0\n });\n\n return {\n objective,\n input: scrapedData,\n activeSocialIds: socials.map(s => s.id),\n operationsPerformed: { scraped: true }\n };\n } catch (error) {\n logger.error(\"Scrape failed\", {\n error: error instanceof Error ? error.message : String(error)\n });\n return {\n error: `Web scrape failed: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Auto-Generate (Parallel Chat API enrichment)\n // Calls enrichUserProfile to get structured data, then builds a\n // text blob as input for the decompose → aggregate → generate\n // pipeline. This ensures enriched users get premises with\n // embeddings, making them discoverable via premise-to-premise\n // matching.\n // On failure, falls back to basic user info for LLM generation.\n // Used in 'generate' mode only.\n // ─────────────────────────────────────────────────────────\n const autoGenerateNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.autoGenerate\", async () => {\n logger.verbose(\"Starting auto-generate via Chat API enrichment\", {\n userId: state.userId,\n });\n\n try {\n const user = await this.database.getUser(state.userId);\n if (!user) {\n logger.error(\"User not found for auto-generate\", { userId: state.userId });\n return { error: `User not found: ${state.userId}` };\n }\n\n const socials = await this.database.getUserSocials(state.userId);\n const enrichmentSocials = socialsToEnrichmentRequest(socials);\n const request = {\n name: user.name || undefined,\n email: user.email || undefined,\n linkedin: enrichmentSocials.linkedin || undefined,\n twitter: enrichmentSocials.twitter || undefined,\n github: enrichmentSocials.github || undefined,\n telegram: enrichmentSocials.telegram || undefined,\n websites: enrichmentSocials.websites?.length ? enrichmentSocials.websites : undefined,\n };\n\n const buildBasicInfo = () => {\n const parts = [\n user.name ? `Name: ${user.name}` : '',\n user.email ? `Email: ${user.email}` : '',\n user.location ? `Location: ${user.location}` : '',\n user.intro ? `Bio: ${user.intro}` : '',\n ].filter(Boolean).join('\\n');\n return parts || \"No information available\";\n };\n\n if (!this.enricher) {\n logger.warn(\"No enricher configured — falling back to basic info\", { userId: state.userId });\n return {\n input: buildBasicInfo(),\n needsUserInfo: false,\n needsProfileGeneration: true,\n operationsPerformed: { scraped: true },\n };\n }\n\n try {\n const enrichment = await this.enricher.enrichUserProfile(request);\n\n if (enrichment && !enrichment.isHuman) {\n logger.info(\"Enrichment detected non-human entity, soft-deleting ghost\", { userId: state.userId });\n await this.database.softDeleteGhost(state.userId);\n return { error: \"Non-human entity detected\" };\n }\n\n const hasMeaningfulEnrichment = !!enrichment &&\n enrichment.confidentMatch &&\n (\n enrichment.identity.bio.trim().length > 0 ||\n enrichment.narrative.context.trim().length > 0 ||\n enrichment.attributes.skills.length > 0 ||\n enrichment.attributes.interests.length > 0\n );\n\n if (hasMeaningfulEnrichment) {\n if (user.isGhost && !isEnrichedNameMeaningful(user.email || '', enrichment!.identity.name || '')) {\n logger.info(\"Enrichment has content but no real name for ghost, soft-deleting\", { userId: state.userId });\n await this.database.softDeleteGhost(state.userId);\n return { error: \"No real name found for ghost user\" };\n }\n\n logger.verbose(\"Chat API enrichment succeeded\", {\n userId: state.userId,\n skillsCount: enrichment!.attributes.skills.length,\n interestsCount: enrichment!.attributes.interests.length,\n });\n\n // Update user record with enriched data\n const updatePayload: {\n name?: string;\n intro?: string;\n location?: string;\n } = {};\n const enrichedName = enrichment!.identity.name?.trim();\n if (\n enrichedName &&\n shouldEnrichGhostDisplayNameFromParallel(\n { isGhost: !!user.isGhost, name: user.name ?? '', email: user.email ?? '' },\n enrichedName,\n )\n ) {\n updatePayload.name = enrichedName;\n }\n if (enrichment!.identity.bio?.trim()) updatePayload.intro = enrichment!.identity.bio.trim();\n if (enrichment!.identity.location?.trim()) updatePayload.location = enrichment!.identity.location.trim();\n\n const enrichedSocials: { label: string; value: string }[] = [];\n if (enrichment!.socials.twitter) enrichedSocials.push({ label: 'twitter', value: enrichment!.socials.twitter });\n if (enrichment!.socials.linkedin) enrichedSocials.push({ label: 'linkedin', value: enrichment!.socials.linkedin });\n if (enrichment!.socials.github) enrichedSocials.push({ label: 'github', value: enrichment!.socials.github });\n if (enrichment!.socials.telegram) enrichedSocials.push({ label: 'telegram', value: enrichment!.socials.telegram });\n if (enrichment!.socials.websites?.length) {\n for (const w of enrichment!.socials.websites) enrichedSocials.push({ label: 'custom', value: w });\n }\n if (enrichedSocials.length > 0) {\n const existingSocials = await this.database.getUserSocials(state.userId);\n const enrichedLabels = new Set(enrichedSocials.map(s => s.label));\n const kept = existingSocials\n .filter(s => !enrichedLabels.has(s.label) || s.label === 'custom')\n .map(s => ({ label: s.label, value: s.value }));\n const merged = enrichedLabels.has('custom')\n ? [...kept.filter(s => s.label !== 'custom'), ...enrichedSocials]\n : [...kept, ...enrichedSocials];\n await this.database.setUserSocials(state.userId, merged);\n }\n\n if (Object.keys(updatePayload).length > 0) {\n await this.database.updateUser(state.userId, updatePayload);\n }\n\n // Post-enrichment dedup: check if this ghost matches an existing user\n if (user.isGhost) {\n const currentSocials = await this.database.getUserSocials(state.userId);\n const duplicate = await this.database.findDuplicateUser(state.userId, currentSocials);\n if (duplicate) {\n logger.info(\"Post-enrichment dedup: merging ghost into existing user\", {\n ghostId: state.userId,\n targetId: duplicate.id,\n });\n await this.database.mergeGhostUser(state.userId, duplicate.id);\n return { error: `Merged as duplicate of user ${duplicate.id}` };\n }\n }\n\n // Build a text blob from the enrichment result so it flows\n // through premise decomposition (when available) rather than\n // bypassing premises via prePopulatedProfile.\n const enrichmentParts = [\n enrichment!.identity.name ? `My name is ${enrichment!.identity.name}.` : '',\n enrichment!.identity.location ? `I am based in ${enrichment!.identity.location}.` : '',\n enrichment!.identity.bio || '',\n enrichment!.narrative.context || '',\n enrichment!.attributes.skills.length ? `My skills include ${enrichment!.attributes.skills.join(', ')}.` : '',\n enrichment!.attributes.interests.length ? `My interests include ${enrichment!.attributes.interests.join(', ')}.` : '',\n ].filter(Boolean).join('\\n');\n\n return {\n input: enrichmentParts,\n needsUserInfo: false,\n needsProfileGeneration: true,\n forceUpdate: true,\n activeSocialIds: socials.map(s => s.id),\n operationsPerformed: { scraped: true },\n };\n }\n\n if (user.isGhost) {\n logger.info(\"Low-confidence enrichment for ghost, soft-deleting\", { userId: state.userId });\n await this.database.softDeleteGhost(state.userId);\n return { error: \"Enrichment not confident for ghost user\" };\n }\n logger.warn(\"Chat API returned low-signal enrichment, falling back to basic info\", { userId: state.userId });\n } catch (enrichErr) {\n if (user.isGhost) {\n logger.info(\"Enrichment failed for ghost, soft-deleting\", { userId: state.userId });\n await this.database.softDeleteGhost(state.userId);\n return { error: \"Enrichment failed for ghost user\" };\n }\n logger.warn(\"Chat API enrichment failed, falling back to basic info\", {\n userId: state.userId,\n error: enrichErr instanceof Error ? enrichErr.message : String(enrichErr),\n });\n }\n\n return {\n input: buildBasicInfo(),\n needsUserInfo: false,\n needsProfileGeneration: true,\n operationsPerformed: { scraped: true },\n };\n } catch (err) {\n logger.error(\"Auto-generate failed\", {\n error: err instanceof Error ? err.message : String(err),\n });\n return { error: `Auto-generate failed: ${err instanceof Error ? err.message : String(err)}` };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Generate Profile\n // Generates profile from input using ProfileGenerator agent.\n // If updating existing profile, merges new information intelligently.\n // ─────────────────────────────────────────────────────────\n const generateProfileNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.generateProfile\", async () => {\n if (!state.input) {\n logger.error(\"No input provided for profile generation\");\n return {\n error: \"Input required for profile generation\"\n };\n }\n\n logger.verbose(\"Starting profile generation...\", {\n hasExistingProfile: !!state.profile,\n isUpdate: state.forceUpdate,\n inputLength: state.input.length\n });\n\n const agentTimingsAccum: DebugMetaAgent[] = [];\n\n try {\n // If updating existing profile, include it in the input for context\n let inputWithContext = state.input;\n if (state.profile && state.forceUpdate) {\n if (state.isAggregate) {\n inputWithContext = `EXISTING PROFILE:\\n${JSON.stringify(state.profile, null, 2)}\\n\\nPREMISE SYNTHESIS:\\n${state.input}\\n\\nRegenerate the profile by synthesizing the premises above. Use the existing profile as context for continuity, but the premises are the authoritative source. Output the full updated profile.`;\n logger.verbose(\"Aggregate synthesis with existing profile context\");\n } else {\n inputWithContext = `EXISTING PROFILE:\\n${JSON.stringify(state.profile, null, 2)}\\n\\nUSER REQUEST:\\n${state.input}\\n\\nApply the user's request to the existing profile. Preserve existing data unless the user asks to change or remove it. You may add, update, or remove skills and interests as requested. Output the full updated profile.`;\n logger.verbose(\"Merging with existing profile\");\n }\n }\n\n const _traceEmitterProfileGen = requestContext.getStore()?.traceEmitter;\n const profileGeneratorStart = Date.now();\n _traceEmitterProfileGen?.({ type: \"agent_start\", name: \"profile-generator\" });\n const result = await profileGenerator.invoke(inputWithContext);\n agentTimingsAccum.push({ name: 'profile.generator', durationMs: Date.now() - profileGeneratorStart });\n _traceEmitterProfileGen?.({ type: \"agent_end\", name: \"profile-generator\", durationMs: Date.now() - profileGeneratorStart, summary: `Generated profile for ${result.output.identity.name || \"user\"}` });\n\n logger.verbose(\"✅ Profile generated successfully\", {\n name: result.output.identity.name,\n skillsCount: result.output.attributes.skills.length,\n interestsCount: result.output.attributes.interests.length\n });\n\n return {\n profile: {\n ...result.output,\n userId: state.userId,\n },\n agentTimings: agentTimingsAccum,\n operationsPerformed: { generatedProfile: true }\n };\n } catch (error) {\n logger.error(\"Profile generation failed\", {\n error: error instanceof Error ? error.message : String(error)\n });\n return {\n error: `Profile generation failed: ${error instanceof Error ? error.message : String(error)}`,\n agentTimings: agentTimingsAccum\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Save Profile\n // Saves the generated profile to DB (no embedding)\n // ─────────────────────────────────────────────────────────\n const saveProfileNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.saveProfile\", async () => {\n if (!state.profile || !state.profile.identity) {\n logger.error(\"Profile or identity missing in save step\");\n return {\n error: \"Profile missing in save step\"\n };\n }\n\n logger.verbose(\"Saving profile to DB...\", {\n userId: state.userId\n });\n\n try {\n const profile = { ...state.profile };\n\n await this.database.saveProfile(state.userId, profile);\n\n logger.verbose(\"✅ Profile saved successfully\");\n\n // Fetch active premises so the questioner can see what's already covered\n let existingPremises: string[] = [];\n try {\n const activePremises = await this.database.getPremisesForUser(state.userId, 'ACTIVE');\n existingPremises = activePremises.map(p => p.assertion.text);\n logger.verbose(\"Fetched active premises for questioner context\", {\n userId: state.userId,\n count: existingPremises.length,\n });\n } catch (premiseErr) {\n logger.error(\"Failed to fetch premises for questioner context — continuing with empty list\", {\n userId: state.userId,\n error: premiseErr instanceof Error ? premiseErr.message : String(premiseErr),\n });\n }\n\n // Compute profile gaps from missing fields\n const gaps: string[] = [];\n if (!profile.identity?.location) gaps.push('location');\n if (!profile.attributes?.skills?.length) gaps.push('skills');\n if (!profile.attributes?.interests?.length) gaps.push('interests');\n if (!profile.narrative?.context) gaps.push('current work');\n\n if (gaps.length > 0 && this.questionerEnqueue) {\n this.questionerEnqueue({\n mode: 'profile',\n userId: state.userId,\n sourceType: 'profile',\n sourceId: state.userId,\n context: {\n userProfile: {\n name: profile.identity?.name,\n bio: profile.identity?.bio,\n location: profile.identity?.location,\n skills: profile.attributes?.skills,\n interests: profile.attributes?.interests,\n },\n gaps,\n existingPremises,\n },\n }).catch((err) =>\n logger.error('Failed to enqueue profile question generation', { userId: state.userId, error: err })\n );\n }\n\n return {\n profile,\n operationsPerformed: { savedProfile: true }\n };\n } catch (error) {\n logger.error(\"Failed to save profile\", {\n error: error instanceof Error ? error.message : String(error)\n });\n return {\n error: `Failed to save profile: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Aggregate Profile\n // Fetches the user's active premises and synthesizes them into profile input.\n // Sets state.input and flags so the existing generate_profile pipeline runs.\n // ─────────────────────────────────────────────────────────\n const aggregateProfileNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.aggregateProfile\", async () => {\n logger.verbose(\"Aggregating profile from premises...\", { userId: state.userId });\n\n const premises: PremiseRecord[] = await this.database.getPremisesForUser(state.userId, 'ACTIVE');\n\n if (premises.length === 0) {\n logger.verbose(\"No active premises found — skipping aggregate\");\n return { operationMode: 'query' as const };\n }\n\n const premiseTexts = premises.map(p => p.assertion.text);\n const aggregateInput = `The following are self-descriptions (premises) the user has asserted about themselves:\\n\\n${premiseTexts.map((t, i) => `${i + 1}. ${t}`).join('\\n')}\\n\\nSynthesize these into a cohesive profile.`;\n\n logger.verbose(`Aggregated ${premises.length} premise(s) into profile input`);\n\n return {\n input: aggregateInput,\n needsProfileGeneration: true,\n forceUpdate: true,\n isAggregate: true,\n };\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // NODE: Decompose Premises\n // Decomposes free-text input (chat or scraped) into individual premises,\n // creates each via the premise graph, then routes to aggregate_profile\n // to synthesize the profile from all active premises.\n // ─────────────────────────────────────────────────────────\n const decomposePremisesNode = async (state: typeof ProfileGraphState.State) => {\n return timed(\"ProfileGraph.decomposePremises\", async () => {\n if (!state.input) {\n logger.error(\"No input for premise decomposition\");\n return { error: \"Input required for premise decomposition\" };\n }\n\n if (!this.premiseGraph) {\n // Fallback: if no premise graph is available, skip decomposition\n // and route directly to profile generation (legacy behavior)\n logger.warn(\"No premise graph injected — falling back to direct profile generation\");\n return {\n needsProfileGeneration: true,\n forceUpdate: true,\n };\n }\n\n logger.verbose(\"Decomposing input into premises...\", {\n userId: state.userId,\n inputLength: state.input.length,\n });\n\n const agentTimingsAccum: DebugMetaAgent[] = [];\n\n try {\n const _traceEmitter = requestContext.getStore()?.traceEmitter;\n\n const decomposeStart = Date.now();\n _traceEmitter?.({ type: \"agent_start\", name: \"premise-decomposer\" });\n const result = await premiseDecomposer.invoke(state.input);\n const decomposeMs = Date.now() - decomposeStart;\n agentTimingsAccum.push({ name: \"premise.decomposer\", durationMs: decomposeMs });\n _traceEmitter?.({\n type: \"agent_end\",\n name: \"premise-decomposer\",\n durationMs: decomposeMs,\n summary: `Decomposed into ${result.premises.length} premise(s)`,\n });\n\n if (result.premises.length === 0) {\n logger.verbose(\"No premises extracted — skipping decomposition\");\n // No premises found; fall through to aggregate which will\n // synthesize from any existing premises, or to generate_profile\n // if needsProfileGeneration is still set from check_state\n return {\n operationMode: 'aggregate' as const,\n agentTimings: agentTimingsAccum,\n };\n }\n\n logger.verbose(`Creating ${result.premises.length} premise(s) via premise graph`, {\n userId: state.userId,\n });\n\n let created = 0;\n for (const p of result.premises) {\n try {\n const premiseResult = await invokeWithAbortSignal(this.premiseGraph, {\n userId: state.userId,\n assertionText: p.text,\n tier: p.tier,\n operationMode: 'create',\n ...(state.activeSocialIds?.length\n ? { provenanceSource: 'integration' as const, provenanceSourceId: state.activeSocialIds[0] }\n : {}),\n });\n\n if (premiseResult.premise) {\n created++;\n } else if (premiseResult.error) {\n logger.warn(\"Premise creation failed\", {\n text: p.text.substring(0, 60),\n error: premiseResult.error,\n });\n }\n } catch (err) {\n logger.warn(\"Premise creation threw\", {\n text: p.text.substring(0, 60),\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n logger.verbose(`Created ${created}/${result.premises.length} premise(s)`, {\n userId: state.userId,\n });\n\n // Route to aggregate mode to rebuild the profile from all active premises\n return {\n operationMode: 'aggregate' as const,\n agentTimings: agentTimingsAccum,\n operationsPerformed: { decomposedPremises: true },\n };\n } catch (err) {\n logger.error(\"Premise decomposition failed\", {\n error: err instanceof Error ? err.message : String(err),\n });\n // Fallback: route to direct profile generation\n return {\n needsProfileGeneration: true,\n forceUpdate: true,\n agentTimings: agentTimingsAccum,\n };\n }\n });\n };\n\n // ─────────────────────────────────────────────────────────\n // ROUTING CONDITIONS\n // Smart conditional routing based on operation mode and missing components\n // ─────────────────────────────────────────────────────────\n\n /**\n * Route from check_state to next step based on operation mode and detected needs.\n */\n const checkStateCondition = (state: typeof ProfileGraphState.State): string => {\n // Query mode: Return immediately (fast path)\n if (state.operationMode === 'query') {\n logger.verbose(\"Query mode - ending (fast path)\");\n return END;\n }\n\n // Aggregate mode: Synthesize profile from active premises\n if (state.operationMode === 'aggregate') {\n logger.verbose(\"Aggregate mode - synthesizing profile from premises\");\n return \"aggregate_profile\";\n }\n\n // Generate mode: use enrichUserProfile Chat API to auto-generate\n if (state.operationMode === 'generate') {\n logger.verbose(\"Generate mode - routing to auto_generate\");\n return \"auto_generate\";\n }\n\n // Check if user information is insufficient for scraping\n // Return early so chat graph can request the missing information\n if (state.needsUserInfo) {\n logger.verbose(\"⚠️ Insufficient user info - requesting from user\", {\n missingInfo: state.missingUserInfo\n });\n return END;\n }\n\n // Write mode: Check what needs generation\n if (state.needsProfileGeneration) {\n // Only use provided input if it's meaningful (not just \"Yes\" / confirmation)\n if (state.input && isMeaningfulProfileInput(state.input)) {\n // Route through premise decomposition when a premise graph is available.\n // The decompose node extracts atomic premises, creates them, then\n // routes to aggregate_profile for profile synthesis.\n if (this.premiseGraph) {\n logger.verbose(\"Profile generation needed — decomposing input into premises\");\n return \"decompose_premises\";\n }\n logger.verbose(\"Profile generation needed with meaningful input provided\");\n return \"generate_profile\";\n } else {\n logger.verbose(\"Profile generation needed - scraping first (no meaningful input)\");\n return \"scrape\";\n }\n }\n\n // Everything exists and is up to date\n logger.verbose(\"All components exist - ending\");\n return END;\n };\n\n\n // ─────────────────────────────────────────────────────────\n // GRAPH ASSEMBLY\n // Conditional flow based on operation mode and detected needs\n // ─────────────────────────────────────────────────────────\n\n const workflow = new StateGraph(ProfileGraphState)\n // Add all nodes\n .addNode(\"check_state\", checkStateNode)\n .addNode(\"scrape\", scrapeNode)\n .addNode(\"decompose_premises\", decomposePremisesNode)\n .addNode(\"auto_generate\", autoGenerateNode)\n .addNode(\"aggregate_profile\", aggregateProfileNode)\n .addNode(\"generate_profile\", generateProfileNode)\n .addNode(\"save_profile\", saveProfileNode)\n\n // Start with state check\n .addEdge(START, \"check_state\")\n\n // Conditional routing from check_state\n .addConditionalEdges(\n \"check_state\",\n checkStateCondition,\n {\n auto_generate: \"auto_generate\", // Generate mode -> Chat API enrichment\n aggregate_profile: \"aggregate_profile\", // Aggregate mode -> synthesize from premises\n decompose_premises: \"decompose_premises\", // Write mode + input + premise graph -> decompose first\n scrape: \"scrape\", // Need profile, no input -> scrape first\n generate_profile: \"generate_profile\", // Need profile, have input -> generate (legacy, no premise graph)\n [END]: END // Query mode or everything exists\n }\n )\n\n // Decompose premises routes to aggregate (normal) or generate_profile (fallback)\n .addConditionalEdges(\n \"decompose_premises\",\n (state: typeof ProfileGraphState.State) => {\n if (state.operationMode === 'aggregate') return \"aggregate_profile\";\n // Fallback when decomposition failed (no premise graph or error)\n if (state.needsProfileGeneration) return \"generate_profile\";\n return \"aggregate_profile\";\n },\n {\n aggregate_profile: \"aggregate_profile\",\n generate_profile: \"generate_profile\",\n },\n )\n\n // Aggregate profile: generate if premises found, END if none\n .addConditionalEdges(\n \"aggregate_profile\",\n (state: typeof ProfileGraphState.State) => {\n if (state.needsProfileGeneration) return \"generate_profile\";\n logger.verbose(\"Aggregate mode — no premises, ending\");\n return END;\n },\n { generate_profile: \"generate_profile\", [END]: END },\n )\n\n // Auto-generate routes to decompose_premises (when premise graph\n // available) or generate_profile (legacy, no premise graph)\n .addConditionalEdges(\n \"auto_generate\",\n (state: typeof ProfileGraphState.State) => {\n if (state.input && this.premiseGraph) {\n logger.verbose(\"Enrichment produced input — routing to premise decomposition\");\n return \"decompose_premises\";\n }\n if (state.input) {\n logger.verbose(\"Enrichment produced input — routing to LLM generation (no premise graph)\");\n return \"generate_profile\";\n }\n logger.verbose(\"Enrichment ended without data (ghost soft-deleted or error) — done\");\n return END;\n },\n {\n decompose_premises: \"decompose_premises\",\n generate_profile: \"generate_profile\",\n [END]: END,\n }\n )\n\n // Scrape -> decompose_premises (when premise graph available) or generate_profile (legacy)\n .addConditionalEdges(\n \"scrape\",\n (_state: typeof ProfileGraphState.State) => {\n if (this.premiseGraph) return \"decompose_premises\";\n return \"generate_profile\";\n },\n {\n decompose_premises: \"decompose_premises\",\n generate_profile: \"generate_profile\",\n },\n )\n\n // Generate profile -> Save profile (linear)\n .addEdge(\"generate_profile\", \"save_profile\")\n\n // Save profile -> END (linear)\n .addEdge(\"save_profile\", END);\n\n logger.verbose(\"Graph built successfully\");\n return workflow.compile();\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questioner.agent.d.ts","sourceRoot":"/","sources":["questioner/questioner.agent.ts"],"names":[],"mappings":"AAYA,OAAO,
|
|
1
|
+
{"version":3,"file":"questioner.agent.d.ts","sourceRoot":"/","sources":["questioner/questioner.agent.ts"],"names":[],"mappings":"AAYA,OAAO,EAAkD,KAAK,wBAAwB,EAAoD,MAAM,sCAAsC,CAAC;AACvL,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAK9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAO7D,MAAM,WAAW,qBAAqB;IACpC,sCAAsC;IACtC,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACjD;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAiD;gBAElD,MAAM,CAAC,EAAE,qBAAqB;IAO1C;;;;;;;;OAQG;IAEG,MAAM,CACV,KAAK,EAAE,eAAe,EACtB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;CA8C5C"}
|
|
@@ -8,7 +8,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
10
|
import { HumanMessage, SystemMessage } from "@langchain/core/messages";
|
|
11
|
-
import { QuestionGeneratorResponseSchema
|
|
11
|
+
import { QuestionGeneratorResponseSchema } from "../shared/schemas/question.schema.js";
|
|
12
12
|
import { createModel } from "../shared/agent/model.config.js";
|
|
13
13
|
import { invokeWithAbortSignal } from "../shared/agent/model-signal.js";
|
|
14
14
|
import { protocolLogger } from "../shared/observability/protocol.logger.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questioner.agent.js","sourceRoot":"/","sources":["questioner/questioner.agent.ts"],"names":[],"mappings":";;;;;;;;;AAUA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,
|
|
1
|
+
{"version":3,"file":"questioner.agent.js","sourceRoot":"/","sources":["questioner/questioner.agent.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * QuestionerAgent — stateless, mode-driven agent that generates structured\n * decision questions from arbitrary protocol contexts.\n *\n * Follows the IndexNegotiator pattern: constructor takes optional config,\n * single public `invoke()` method receives the full context per call.\n * The LLM model is bound once at construction; the preset (system prompt +\n * builder) is selected per invocation based on `input.mode`.\n */\nimport type { ChatOpenAI } from \"@langchain/openai\";\nimport { HumanMessage, SystemMessage } from \"@langchain/core/messages\";\n\nimport { QuestionGeneratorResponseSchema, type Question, type QuestionGenerationResult, type QuestionStrategy, type QuestionWithStrategy } from \"../shared/schemas/question.schema.js\";\nimport { createModel } from \"../shared/agent/model.config.js\";\nimport { invokeWithAbortSignal } from \"../shared/agent/model-signal.js\";\nimport { protocolLogger } from \"../shared/observability/protocol.logger.js\";\nimport { Timed } from \"../shared/observability/performance.js\";\nimport { getPreset } from \"./questioner.presets.js\";\nimport type { QuestionerInput } from \"./questioner.types.js\";\n\nconst logger = protocolLogger(\"QuestionerAgent\");\n\n/** Maximum same-strategy questions allowed in a single emission. */\nconst MAX_SAME_STRATEGY = 2;\n\nexport interface QuestionerAgentConfig {\n /** Optional model config override. */\n modelConfig?: Parameters<typeof createModel>[1];\n}\n\n/**\n * Stateless question-generation agent. Accepts a `QuestionerInput` envelope,\n * selects the preset for the given mode, invokes the LLM, and applies\n * guardrails (dedup + strategy diversity).\n */\nexport class QuestionerAgent {\n private model: ReturnType<ChatOpenAI[\"withStructuredOutput\"]>;\n\n constructor(config?: QuestionerAgentConfig) {\n const llm = createModel(\"questioner\", config?.modelConfig);\n this.model = llm.withStructuredOutput(QuestionGeneratorResponseSchema, {\n name: \"clarifying_questions\",\n });\n }\n\n /**\n * Generate up to 3 decision questions from the given input.\n *\n * @param input Envelope with mode, userId, source info, and mode-specific context.\n * @param options.signal Optional AbortSignal to cancel the in-flight LLM call.\n * @returns A result with parallel questions[] and strategies[] arrays,\n * or null when generation failed, guardrails dropped all candidates,\n * the LLM threw, or the call was aborted.\n */\n @Timed()\n async invoke(\n input: QuestionerInput,\n options?: { signal?: AbortSignal },\n ): Promise<QuestionGenerationResult | null> {\n const preset = getPreset(input.mode);\n const userMessage = preset.buildPrompt(input.context);\n\n let raw: unknown;\n try {\n raw = await invokeWithAbortSignal(\n this.model,\n [new SystemMessage(preset.systemPrompt), new HumanMessage(userMessage)],\n options?.signal,\n );\n } catch (err) {\n const aborted = options?.signal?.aborted ?? false;\n if (aborted) {\n logger.info(\"QuestionerAgent aborted by signal\", {\n mode: input.mode,\n reason: options?.signal?.reason instanceof Error\n ? options.signal.reason.message\n : String(options?.signal?.reason ?? \"unknown\"),\n });\n } else {\n logger.warn(\"QuestionerAgent LLM call failed\", {\n mode: input.mode,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n return null;\n }\n\n const parsed = QuestionGeneratorResponseSchema.safeParse(raw);\n if (!parsed.success) {\n logger.warn(\"QuestionerAgent parse failed\", {\n mode: input.mode,\n error: parsed.error.message,\n });\n return null;\n }\n\n const filtered = applyGuardrails(parsed.data.questions);\n if (filtered.length === 0) return null;\n\n return {\n questions: filtered.map(stripStrategy),\n strategies: filtered.map((q) => q.strategy),\n };\n }\n}\n\n// --- Guardrails (migrated from question.generator.ts) -------------------------\n\nfunction applyGuardrails(questions: QuestionWithStrategy[]): QuestionWithStrategy[] {\n const dedupedByTitle = dedupByTitle(questions);\n return enforceStrategyDiversity(dedupedByTitle);\n}\n\nfunction dedupByTitle(questions: QuestionWithStrategy[]): QuestionWithStrategy[] {\n const seen = new Set<string>();\n const out: QuestionWithStrategy[] = [];\n for (const q of questions) {\n if (seen.has(q.title)) continue;\n seen.add(q.title);\n out.push(q);\n }\n return out;\n}\n\nfunction enforceStrategyDiversity(\n questions: QuestionWithStrategy[],\n): QuestionWithStrategy[] {\n const counts = new Map<QuestionStrategy, number>();\n const out: QuestionWithStrategy[] = [];\n for (const q of questions) {\n const n = counts.get(q.strategy) ?? 0;\n if (n >= MAX_SAME_STRATEGY) continue;\n counts.set(q.strategy, n + 1);\n out.push(q);\n }\n return out;\n}\n\nfunction stripStrategy(q: QuestionWithStrategy): Question {\n const { strategy: _strategy, ...publicShape } = q;\n return publicShape;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questioner.presets.d.ts","sourceRoot":"/","sources":["questioner/questioner.presets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"questioner.presets.d.ts","sourceRoot":"/","sources":["questioner/questioner.presets.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAqBzE,MAAM,WAAW,gBAAgB;IAC/B,2CAA2C;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;CAC3C;AAqPD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,gBAAgB,CAM9D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SYSTEM_PROMPT as DISCOVERY_SYSTEM_PROMPT, buildQuestionPrompt as buildDiscoveryPrompt
|
|
1
|
+
import { SYSTEM_PROMPT as DISCOVERY_SYSTEM_PROMPT, buildQuestionPrompt as buildDiscoveryPrompt } from "../opportunity/question.prompt.js";
|
|
2
2
|
/**
|
|
3
3
|
* Shared rule block appended to every questioner system prompt. Enforces that
|
|
4
4
|
* the generated `prompt` resolves on its own — no demonstratives/anaphora that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questioner.presets.js","sourceRoot":"/","sources":["questioner/questioner.presets.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mode presets for the QuestionerAgent. Each preset provides a system prompt\n * and a buildPrompt function that assembles the user message from a typed\n * context object. Only the `discovery` preset ships in Slice 1; others throw\n * until their implementation slices land.\n */\nimport type { QuestionMode } from \"../shared/schemas/question.schema.js\";\nimport {\n SYSTEM_PROMPT as DISCOVERY_SYSTEM_PROMPT,\n buildQuestionPrompt as buildDiscoveryPrompt,\n} from \"../opportunity/question.prompt.js\";\n\nimport type { IntentContext, NegotiationContext, ProfileContext } from \"./questioner.types.js\";\n\n/**\n * Shared rule block appended to every questioner system prompt. Enforces that\n * the generated `prompt` resolves on its own — no demonstratives/anaphora that\n * point at people, events, or prior turns the reader cannot see — and never\n * narrates Index's own matching pipeline. Closes the referential-leak class\n * surfaced in digest audits (\"…with these builders?\", \"the previous\n * negotiation stalled because the counterparty didn't mention …\").\n */\nconst REFERENTIAL_CLOSURE_RULES = `Referential closure. The prompt must resolve entirely on its own, with no dangling references. The reader sees ONLY the question text — never the people you reviewed, the counterparty, the events on their calendar, or this conversation. Do not use demonstratives or definite anaphora that point at things the reader cannot see: \"these builders\", \"those founders\", \"these researchers\", \"these conversations\", \"this lunch\", \"the speaker\". If you reference a person, name them. If you reference a group, restate the concrete shared attribute inside the question itself (\"founders working on decentralized identity\"), never \"these founders\". Never imply a list, set, or prior exchange the reader is not currently looking at.\n- Bad: \"What kind of collaboration are you looking for with these builders?\"\n- Good: \"You're meeting people building agent infrastructure — what kind of collaboration are you looking for?\"\n\nNo process narration. Never describe Index's own activity or internal state. Forbidden: \"the previous negotiation\", \"the negotiation stalled\", \"opportunities found so far\", \"my search\", \"the counterparty\", \"candidates reviewed\", restating why a match did or did not happen, or quoting words a counterparty did or did not use. Ask about the user's goal or intent directly, never about the matching pipeline.\n- Bad: \"The previous negotiation stalled because the counterparty didn't mention 'matchmaking'. Should I broaden the search?\"\n- Good: \"Do you want to focus on dedicated matchmakers, or also people interested in relationships more broadly?\"`;\n\nexport interface QuestionerPreset {\n /** The LLM system prompt for this mode. */\n systemPrompt: string;\n /** Builds the user-message string from the mode-specific context. */\n buildPrompt: (context: unknown) => string;\n}\n\n// ─── Intent preset ──────────────────────────────────────────────────────────\n\nconst INTENT_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user has stated an intent — what they are looking for. Your job: surface the minimum set of structured questions that help the user sharpen that intent before the protocol runs discovery on their behalf.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- refine_intent: ask the user to sharpen or pivot the core signal (scope, scale, specificity, direction).\n- surface_missing_detail: ask for one concrete missing input that would change which candidates surface (stage, location, timing, budget, constraints, format, …).\n\nAsk a question only when ALL of these hold:\n1. The agent cannot infer the answer from the intent text or user profile already shown.\n2. The answer would materially change which candidates surface.\n3. The question targets a different decision domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the source intent/topic in the question text itself, using concise plain language from the intent or summary. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"What kind of collaboration are you looking for?\"\n- Good: \"For your decentralized identity protocol-design search, what kind of collaboration are you looking for?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ (different titles).\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Stage\", \"Timing\", \"Location\", \"Scope\", \"Budget\", \"Format\", \"Skills\", \"Collab\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I start searching?\").\n- Don't ask about hypothetical edge cases not implied by the intent.\n- Don't re-ask for facts already visible in the user profile.\n- Don't ask vague introspective questions (\"What do you really want?\").\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the intent is already specific enough, return \"questions\": [].`;\n\n/**\n * Build the user message for the intent preset from an IntentContext.\n * @param ctx - The intent context.\n * @returns The assembled user message string.\n */\nfunction buildIntentPrompt(ctx: IntentContext): string {\n const profileLines: string[] = [];\n if (ctx.userProfile.name) profileLines.push(`Name: ${ctx.userProfile.name}`);\n if (ctx.userProfile.bio) profileLines.push(`Bio: ${ctx.userProfile.bio}`);\n if (ctx.userProfile.skills && ctx.userProfile.skills.length > 0) {\n profileLines.push(`Skills: ${ctx.userProfile.skills.join(\", \")}`);\n }\n if (ctx.userProfile.interests && ctx.userProfile.interests.length > 0) {\n profileLines.push(`Interests: ${ctx.userProfile.interests.join(\", \")}`);\n }\n const profileBlock = profileLines.length > 0 ? profileLines.join(\"\\n\") : \"(no profile data)\";\n\n const summaryBlock = ctx.summary ? ctx.summary : \"(no summary available)\";\n\n return [\n \"## Intent\",\n ctx.payload,\n \"\",\n \"## Summary\",\n summaryBlock,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of questions the user must answer to sharpen this intent.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the intent is already specific enough.\",\n ].join(\"\\n\");\n}\n\n// ─── Profile preset ─────────────────────────────────────────────────────────\n\nconst PROFILE_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user has a profile that is incomplete. Your job: surface the minimum set of structured questions that fill the identified gaps — asking about location, skills, interests, current work, or goals — so the protocol can run better discovery on their behalf.\n\nThe user may already have premises — atomic self-descriptions they have stated. These cover specific profile domains. Do not ask about domains already addressed by existing premises. Focus only on gaps not covered by any premise.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- surface_missing_detail: ask for one concrete missing piece of profile data (location, current role, skills, interests, goals, availability, …).\n- refine_intent: ask the user to clarify or sharpen an existing profile signal so candidates can be ranked more accurately.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the profile data shown.\n2. The answer is not already covered by an existing premise listed below the profile.\n3. The answer would meaningfully change which opportunities surface for this user.\n4. The question targets a different profile domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the profile signal or gap being clarified in the question text itself, using concise plain language from the current profile, existing premises, or identified gaps. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"What kind of role are you looking for?\"\n- Good: \"To improve matches from your founder/operator profile, what kind of role are you looking for?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically.\n\nTitle rules. ≤12 chars. Noun of the profile domain. Examples: \"Location\", \"Role\", \"Skills\", \"Goals\", \"Interests\", \"Availability\", \"Stage\".\n\nAnti-patterns — never do these.\n- Don't ask about fields already filled in the profile.\n- Don't ask about information already captured in an existing premise.\n- Don't ask procedural confirmations (\"Should I update your profile?\").\n- Don't ask vague introspective questions (\"Who are you really?\").\n- Don't re-ask for facts visible anywhere in the profile data or premises shown.\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the profile is already complete enough for discovery, return \"questions\": [].`;\n\n/**\n * Build the user message for the profile preset from a ProfileContext.\n * @param ctx - The profile context including current profile data and identified gaps.\n * @returns The assembled user message string.\n */\nfunction buildProfilePrompt(ctx: ProfileContext): string {\n const profileLines: string[] = [];\n if (ctx.userProfile.name) profileLines.push(`Name: ${ctx.userProfile.name}`);\n if (ctx.userProfile.bio) profileLines.push(`Bio: ${ctx.userProfile.bio}`);\n if (ctx.userProfile.location) profileLines.push(`Location: ${ctx.userProfile.location}`);\n if (ctx.userProfile.skills && ctx.userProfile.skills.length > 0) {\n profileLines.push(`Skills: ${ctx.userProfile.skills.join(\", \")}`);\n }\n if (ctx.userProfile.interests && ctx.userProfile.interests.length > 0) {\n profileLines.push(`Interests: ${ctx.userProfile.interests.join(\", \")}`);\n }\n const profileBlock = profileLines.length > 0 ? profileLines.join(\"\\n\") : \"(no profile data)\";\n\n const premisesBlock =\n ctx.existingPremises && ctx.existingPremises.length > 0\n ? ctx.existingPremises.map((p, i) => `${i + 1}. ${p}`).join(\"\\n\")\n : \"(none)\";\n\n const gapsBlock = ctx.gaps.length > 0 ? ctx.gaps.join(\", \") : \"(none identified)\";\n\n const parts: string[] = [\n \"## Current profile\",\n profileBlock,\n \"\",\n \"## Existing premises\",\n premisesBlock,\n \"\",\n \"## Identified gaps\",\n gapsBlock,\n \"\",\n ];\n\n parts.push(\n \"## Your task\",\n \"Generate the minimum set of questions needed to fill the identified gaps.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the profile is already complete enough.\",\n );\n\n return parts.join(\"\\n\");\n}\n\n// ─── Negotiation preset ──────────────────────────────────────────────────────\n\nconst NEGOTIATION_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. A negotiation between this user and a counterparty has ended without a clear outcome — either the turn budget was exhausted, the session timed out, or conversation stalled. Your job: surface the minimum set of structured questions that help the user provide the missing signal needed to unblock or refine the next discovery attempt on their behalf.\n\nYou may pick from three strategies. Choose contextually; mix only when each question is genuinely distinct.\n- refine_intent: help the user sharpen their underlying signal based on what the negotiation revealed (scope, scale, priority, direction).\n- surface_missing_detail: ask for one concrete piece of information that was absent and would have moved the negotiation forward (timeline, budget, format, constraints, decision criteria, …).\n- reflective_summary: mirror the key takeaway from the negotiation and ask the user to confirm, correct, or decide — useful when the conversation revealed partial signal worth locking in.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the negotiation context or user profile shown.\n2. The answer would materially change how the next attempt surfaces or engages candidates.\n3. The question targets a different decision domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the user's underlying goal or topic and the relevant community in the question text itself, in plain language drawn from their intent or profile — NOT the mechanics of the match attempt. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"Which role is a better fit for your immediate needs?\"\n- Good: \"For your search for AI infrastructure collaborators in the AI founders community, what kind of working relationship fits your immediate needs?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Scope\", \"Timeline\", \"Budget\", \"Priority\", \"Format\", \"Stance\", \"Criteria\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I try again?\").\n- Don't re-ask for facts already visible in the user profile.\n- Don't ask vague introspective questions (\"What do you really want?\").\n- Don't ask about hypothetical edge cases not implied by the negotiation context.\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the three values above). If the context already contains enough signal to proceed, return \"questions\": [].`;\n\n/**\n * Build the user message for the negotiation preset from a NegotiationContext.\n * @param ctx - The negotiation context including counterparty hint, stall reason, and key takeaway.\n * @returns The assembled user message string.\n */\nfunction buildNegotiationPrompt(ctx: NegotiationContext): string {\n const profileLines: string[] = [];\n if (ctx.userProfile.name) profileLines.push(`Name: ${ctx.userProfile.name}`);\n if (ctx.userProfile.bio) profileLines.push(`Bio: ${ctx.userProfile.bio}`);\n if (ctx.userProfile.skills && ctx.userProfile.skills.length > 0) {\n profileLines.push(`Skills: ${ctx.userProfile.skills.join(\", \")}`);\n }\n if (ctx.userProfile.interests && ctx.userProfile.interests.length > 0) {\n profileLines.push(`Interests: ${ctx.userProfile.interests.join(\", \")}`);\n }\n const profileBlock = profileLines.length > 0 ? profileLines.join(\"\\n\") : \"(no profile data)\";\n\n return [\n \"## Negotiation context\",\n `Community: ${ctx.indexContext}`,\n `Counterparty: ${ctx.counterpartyHint}`,\n `Stall reason: ${ctx.outcomeReason}`,\n \"\",\n \"## Key takeaway\",\n ctx.keyTake,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of questions the user must answer to unblock the next discovery attempt.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the context already contains enough signal to proceed.\",\n ].join(\"\\n\");\n}\n\nconst presets: Record<QuestionMode, QuestionerPreset> = {\n discovery: {\n systemPrompt: DISCOVERY_SYSTEM_PROMPT,\n buildPrompt: (context: unknown) =>\n buildDiscoveryPrompt(context as Parameters<typeof buildDiscoveryPrompt>[0]),\n },\n intent: {\n systemPrompt: INTENT_SYSTEM_PROMPT,\n buildPrompt: (context: unknown) => buildIntentPrompt(context as IntentContext),\n },\n profile: {\n systemPrompt: PROFILE_SYSTEM_PROMPT,\n buildPrompt: (context: unknown) => buildProfilePrompt(context as ProfileContext),\n },\n negotiation: {\n systemPrompt: NEGOTIATION_SYSTEM_PROMPT,\n buildPrompt: (context: unknown) => buildNegotiationPrompt(context as NegotiationContext),\n },\n};\n\n/**\n * Retrieve the preset for the given mode.\n * @param mode - The question mode to look up.\n * @returns The matching preset with systemPrompt and buildPrompt.\n * @throws Error if the mode's preset is not yet implemented.\n */\nexport function getPreset(mode: QuestionMode): QuestionerPreset {\n const preset = presets[mode];\n if (!preset) {\n throw new Error(`QuestionerAgent preset \"${mode}\" is not implemented yet`);\n }\n return preset;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"questioner.presets.js","sourceRoot":"/","sources":["questioner/questioner.presets.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mode presets for the QuestionerAgent. Each preset provides a system prompt\n * and a buildPrompt function that assembles the user message from a typed\n * context object. Only the `discovery` preset ships in Slice 1; others throw\n * until their implementation slices land.\n */\nimport type { QuestionMode } from \"../shared/schemas/question.schema.js\";\nimport { SYSTEM_PROMPT as DISCOVERY_SYSTEM_PROMPT, buildQuestionPrompt as buildDiscoveryPrompt } from \"../opportunity/question.prompt.js\";\n\nimport type { IntentContext, NegotiationContext, ProfileContext } from \"./questioner.types.js\";\n\n/**\n * Shared rule block appended to every questioner system prompt. Enforces that\n * the generated `prompt` resolves on its own — no demonstratives/anaphora that\n * point at people, events, or prior turns the reader cannot see — and never\n * narrates Index's own matching pipeline. Closes the referential-leak class\n * surfaced in digest audits (\"…with these builders?\", \"the previous\n * negotiation stalled because the counterparty didn't mention …\").\n */\nconst REFERENTIAL_CLOSURE_RULES = `Referential closure. The prompt must resolve entirely on its own, with no dangling references. The reader sees ONLY the question text — never the people you reviewed, the counterparty, the events on their calendar, or this conversation. Do not use demonstratives or definite anaphora that point at things the reader cannot see: \"these builders\", \"those founders\", \"these researchers\", \"these conversations\", \"this lunch\", \"the speaker\". If you reference a person, name them. If you reference a group, restate the concrete shared attribute inside the question itself (\"founders working on decentralized identity\"), never \"these founders\". Never imply a list, set, or prior exchange the reader is not currently looking at.\n- Bad: \"What kind of collaboration are you looking for with these builders?\"\n- Good: \"You're meeting people building agent infrastructure — what kind of collaboration are you looking for?\"\n\nNo process narration. Never describe Index's own activity or internal state. Forbidden: \"the previous negotiation\", \"the negotiation stalled\", \"opportunities found so far\", \"my search\", \"the counterparty\", \"candidates reviewed\", restating why a match did or did not happen, or quoting words a counterparty did or did not use. Ask about the user's goal or intent directly, never about the matching pipeline.\n- Bad: \"The previous negotiation stalled because the counterparty didn't mention 'matchmaking'. Should I broaden the search?\"\n- Good: \"Do you want to focus on dedicated matchmakers, or also people interested in relationships more broadly?\"`;\n\nexport interface QuestionerPreset {\n /** The LLM system prompt for this mode. */\n systemPrompt: string;\n /** Builds the user-message string from the mode-specific context. */\n buildPrompt: (context: unknown) => string;\n}\n\n// ─── Intent preset ──────────────────────────────────────────────────────────\n\nconst INTENT_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user has stated an intent — what they are looking for. Your job: surface the minimum set of structured questions that help the user sharpen that intent before the protocol runs discovery on their behalf.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- refine_intent: ask the user to sharpen or pivot the core signal (scope, scale, specificity, direction).\n- surface_missing_detail: ask for one concrete missing input that would change which candidates surface (stage, location, timing, budget, constraints, format, …).\n\nAsk a question only when ALL of these hold:\n1. The agent cannot infer the answer from the intent text or user profile already shown.\n2. The answer would materially change which candidates surface.\n3. The question targets a different decision domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the source intent/topic in the question text itself, using concise plain language from the intent or summary. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"What kind of collaboration are you looking for?\"\n- Good: \"For your decentralized identity protocol-design search, what kind of collaboration are you looking for?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ (different titles).\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Stage\", \"Timing\", \"Location\", \"Scope\", \"Budget\", \"Format\", \"Skills\", \"Collab\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I start searching?\").\n- Don't ask about hypothetical edge cases not implied by the intent.\n- Don't re-ask for facts already visible in the user profile.\n- Don't ask vague introspective questions (\"What do you really want?\").\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the intent is already specific enough, return \"questions\": [].`;\n\n/**\n * Build the user message for the intent preset from an IntentContext.\n * @param ctx - The intent context.\n * @returns The assembled user message string.\n */\nfunction buildIntentPrompt(ctx: IntentContext): string {\n const profileLines: string[] = [];\n if (ctx.userProfile.name) profileLines.push(`Name: ${ctx.userProfile.name}`);\n if (ctx.userProfile.bio) profileLines.push(`Bio: ${ctx.userProfile.bio}`);\n if (ctx.userProfile.skills && ctx.userProfile.skills.length > 0) {\n profileLines.push(`Skills: ${ctx.userProfile.skills.join(\", \")}`);\n }\n if (ctx.userProfile.interests && ctx.userProfile.interests.length > 0) {\n profileLines.push(`Interests: ${ctx.userProfile.interests.join(\", \")}`);\n }\n const profileBlock = profileLines.length > 0 ? profileLines.join(\"\\n\") : \"(no profile data)\";\n\n const summaryBlock = ctx.summary ? ctx.summary : \"(no summary available)\";\n\n return [\n \"## Intent\",\n ctx.payload,\n \"\",\n \"## Summary\",\n summaryBlock,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of questions the user must answer to sharpen this intent.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the intent is already specific enough.\",\n ].join(\"\\n\");\n}\n\n// ─── Profile preset ─────────────────────────────────────────────────────────\n\nconst PROFILE_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. The user has a profile that is incomplete. Your job: surface the minimum set of structured questions that fill the identified gaps — asking about location, skills, interests, current work, or goals — so the protocol can run better discovery on their behalf.\n\nThe user may already have premises — atomic self-descriptions they have stated. These cover specific profile domains. Do not ask about domains already addressed by existing premises. Focus only on gaps not covered by any premise.\n\nYou may pick from two strategies. Choose contextually; mix only when each question is genuinely distinct.\n- surface_missing_detail: ask for one concrete missing piece of profile data (location, current role, skills, interests, goals, availability, …).\n- refine_intent: ask the user to clarify or sharpen an existing profile signal so candidates can be ranked more accurately.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the profile data shown.\n2. The answer is not already covered by an existing premise listed below the profile.\n3. The answer would meaningfully change which opportunities surface for this user.\n4. The question targets a different profile domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the profile signal or gap being clarified in the question text itself, using concise plain language from the current profile, existing premises, or identified gaps. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"What kind of role are you looking for?\"\n- Good: \"To improve matches from your founder/operator profile, what kind of role are you looking for?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically.\n\nTitle rules. ≤12 chars. Noun of the profile domain. Examples: \"Location\", \"Role\", \"Skills\", \"Goals\", \"Interests\", \"Availability\", \"Stage\".\n\nAnti-patterns — never do these.\n- Don't ask about fields already filled in the profile.\n- Don't ask about information already captured in an existing premise.\n- Don't ask procedural confirmations (\"Should I update your profile?\").\n- Don't ask vague introspective questions (\"Who are you really?\").\n- Don't re-ask for facts visible anywhere in the profile data or premises shown.\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the two values above). If the profile is already complete enough for discovery, return \"questions\": [].`;\n\n/**\n * Build the user message for the profile preset from a ProfileContext.\n * @param ctx - The profile context including current profile data and identified gaps.\n * @returns The assembled user message string.\n */\nfunction buildProfilePrompt(ctx: ProfileContext): string {\n const profileLines: string[] = [];\n if (ctx.userProfile.name) profileLines.push(`Name: ${ctx.userProfile.name}`);\n if (ctx.userProfile.bio) profileLines.push(`Bio: ${ctx.userProfile.bio}`);\n if (ctx.userProfile.location) profileLines.push(`Location: ${ctx.userProfile.location}`);\n if (ctx.userProfile.skills && ctx.userProfile.skills.length > 0) {\n profileLines.push(`Skills: ${ctx.userProfile.skills.join(\", \")}`);\n }\n if (ctx.userProfile.interests && ctx.userProfile.interests.length > 0) {\n profileLines.push(`Interests: ${ctx.userProfile.interests.join(\", \")}`);\n }\n const profileBlock = profileLines.length > 0 ? profileLines.join(\"\\n\") : \"(no profile data)\";\n\n const premisesBlock =\n ctx.existingPremises && ctx.existingPremises.length > 0\n ? ctx.existingPremises.map((p, i) => `${i + 1}. ${p}`).join(\"\\n\")\n : \"(none)\";\n\n const gapsBlock = ctx.gaps.length > 0 ? ctx.gaps.join(\", \") : \"(none identified)\";\n\n const parts: string[] = [\n \"## Current profile\",\n profileBlock,\n \"\",\n \"## Existing premises\",\n premisesBlock,\n \"\",\n \"## Identified gaps\",\n gapsBlock,\n \"\",\n ];\n\n parts.push(\n \"## Your task\",\n \"Generate the minimum set of questions needed to fill the identified gaps.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the profile is already complete enough.\",\n );\n\n return parts.join(\"\\n\");\n}\n\n// ─── Negotiation preset ──────────────────────────────────────────────────────\n\nconst NEGOTIATION_SYSTEM_PROMPT = `You sit between a human and a discovery protocol. A negotiation between this user and a counterparty has ended without a clear outcome — either the turn budget was exhausted, the session timed out, or conversation stalled. Your job: surface the minimum set of structured questions that help the user provide the missing signal needed to unblock or refine the next discovery attempt on their behalf.\n\nYou may pick from three strategies. Choose contextually; mix only when each question is genuinely distinct.\n- refine_intent: help the user sharpen their underlying signal based on what the negotiation revealed (scope, scale, priority, direction).\n- surface_missing_detail: ask for one concrete piece of information that was absent and would have moved the negotiation forward (timeline, budget, format, constraints, decision criteria, …).\n- reflective_summary: mirror the key takeaway from the negotiation and ask the user to confirm, correct, or decide — useful when the conversation revealed partial signal worth locking in.\n\nAsk a question only when ALL of these hold:\n1. The answer is not already visible in the negotiation context or user profile shown.\n2. The answer would materially change how the next attempt surfaces or engages candidates.\n3. The question targets a different decision domain from any other question in this batch.\n\nStandalone prompt rule. Every generated \\`prompt\\` must be understandable outside the conversation where it was created. Naturally include the user's underlying goal or topic and the relevant community in the question text itself, in plain language drawn from their intent or profile — NOT the mechanics of the match attempt. Do not rely on \\`title\\`, UI labels, hidden metadata, or surrounding digest/chat text to explain what the question is about.\n- Bad: \"Which role is a better fit for your immediate needs?\"\n- Good: \"For your search for AI infrastructure collaborators in the AI founders community, what kind of working relationship fits your immediate needs?\"\n\n${REFERENTIAL_CLOSURE_RULES}\n\nCardinality. Default one question. Add a second only when a DIFFERENT strategy genuinely complements the first and unblocks a clearly distinct decision. Never ask two questions of the same strategy unless their decision domains differ.\n\nOption construction. Each option must represent a meaningfully different outcome. Suffix the safest or most common path with \" (Recommended)\" and list it first. The description states the CONSEQUENCE of choosing the option, not its definition. 2–4 options. Never add an \"Other\" option — clients provide a free-text fallback automatically.\n\nTitle rules. ≤12 chars. Noun of the decision domain. Examples: \"Scope\", \"Timeline\", \"Budget\", \"Priority\", \"Format\", \"Stance\", \"Criteria\".\n\nAnti-patterns — never do these.\n- Don't ask procedural confirmations (\"Should I try again?\").\n- Don't re-ask for facts already visible in the user profile.\n- Don't ask vague introspective questions (\"What do you really want?\").\n- Don't ask about hypothetical edge cases not implied by the negotiation context.\n\nOutput. Return at most 2 entries in the \"questions\" array. Each entry must include a \"strategy\" field (one of the three values above). If the context already contains enough signal to proceed, return \"questions\": [].`;\n\n/**\n * Build the user message for the negotiation preset from a NegotiationContext.\n * @param ctx - The negotiation context including counterparty hint, stall reason, and key takeaway.\n * @returns The assembled user message string.\n */\nfunction buildNegotiationPrompt(ctx: NegotiationContext): string {\n const profileLines: string[] = [];\n if (ctx.userProfile.name) profileLines.push(`Name: ${ctx.userProfile.name}`);\n if (ctx.userProfile.bio) profileLines.push(`Bio: ${ctx.userProfile.bio}`);\n if (ctx.userProfile.skills && ctx.userProfile.skills.length > 0) {\n profileLines.push(`Skills: ${ctx.userProfile.skills.join(\", \")}`);\n }\n if (ctx.userProfile.interests && ctx.userProfile.interests.length > 0) {\n profileLines.push(`Interests: ${ctx.userProfile.interests.join(\", \")}`);\n }\n const profileBlock = profileLines.length > 0 ? profileLines.join(\"\\n\") : \"(no profile data)\";\n\n return [\n \"## Negotiation context\",\n `Community: ${ctx.indexContext}`,\n `Counterparty: ${ctx.counterpartyHint}`,\n `Stall reason: ${ctx.outcomeReason}`,\n \"\",\n \"## Key takeaway\",\n ctx.keyTake,\n \"\",\n \"## User profile\",\n profileBlock,\n \"\",\n \"## Your task\",\n \"Identify the minimum set of questions the user must answer to unblock the next discovery attempt.\",\n \"Apply every rule from your system prompt before outputting.\",\n \"Return an empty `questions` array if the context already contains enough signal to proceed.\",\n ].join(\"\\n\");\n}\n\nconst presets: Record<QuestionMode, QuestionerPreset> = {\n discovery: {\n systemPrompt: DISCOVERY_SYSTEM_PROMPT,\n buildPrompt: (context: unknown) =>\n buildDiscoveryPrompt(context as Parameters<typeof buildDiscoveryPrompt>[0]),\n },\n intent: {\n systemPrompt: INTENT_SYSTEM_PROMPT,\n buildPrompt: (context: unknown) => buildIntentPrompt(context as IntentContext),\n },\n profile: {\n systemPrompt: PROFILE_SYSTEM_PROMPT,\n buildPrompt: (context: unknown) => buildProfilePrompt(context as ProfileContext),\n },\n negotiation: {\n systemPrompt: NEGOTIATION_SYSTEM_PROMPT,\n buildPrompt: (context: unknown) => buildNegotiationPrompt(context as NegotiationContext),\n },\n};\n\n/**\n * Retrieve the preset for the given mode.\n * @param mode - The question mode to look up.\n * @returns The matching preset with systemPrompt and buildPrompt.\n * @throws Error if the mode's preset is not yet implemented.\n */\nexport function getPreset(mode: QuestionMode): QuestionerPreset {\n const preset = presets[mode];\n if (!preset) {\n throw new Error(`QuestionerAgent preset \"${mode}\" is not implemented yet`);\n }\n return preset;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.streamer.d.ts","sourceRoot":"/","sources":["shared/agent/response.streamer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"response.streamer.d.ts","sourceRoot":"/","sources":["shared/agent/response.streamer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAU1E;;;;;;;;;;;;;GAaG;AACH,qBAAa,gBAAgB;IAC3B;;;;;OAKG;IACH,kBAAkB,CAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;QAAE,IAAI,CAAC,EAAE;YAAE,MAAM,CAAC,EAAE;gBAAE,YAAY,CAAC,EAAE,MAAM,CAAC;gBAAC,KAAK,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,GACvE;QAAE,MAAM,EAAE,eAAe,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE;CA4B1E"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createTokenEvent, createErrorEvent
|
|
1
|
+
import { createTokenEvent, createErrorEvent } from "../../chat/chat-streaming.types.js";
|
|
2
2
|
import { protocolLogger } from "../observability/protocol.logger.js";
|
|
3
3
|
const logger = protocolLogger("ResponseStreamer");
|
|
4
4
|
// ══════════════════════════════════════════════════════════════════════════════
|