@indexnetwork/protocol 1.25.1-rc.209.1 → 1.25.3-rc.211.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/dist/agent/agent.tools.d.ts.map +1 -1
- package/dist/agent/agent.tools.js.map +1 -1
- package/dist/agent/tests/fakes.d.ts.map +1 -1
- package/dist/agent/tests/fakes.js.map +1 -1
- package/dist/chat/chat-streaming.types.d.ts.map +1 -1
- package/dist/chat/chat-streaming.types.js.map +1 -1
- package/dist/chat/chat.agent.d.ts.map +1 -1
- package/dist/chat/chat.agent.js.map +1 -1
- package/dist/chat/chat.graph.d.ts.map +1 -1
- package/dist/chat/chat.graph.js.map +1 -1
- package/dist/chat/chat.prompt.d.ts.map +1 -1
- package/dist/chat/chat.prompt.js.map +1 -1
- package/dist/chat/chat.prompt.modules.d.ts.map +1 -1
- package/dist/chat/chat.prompt.modules.js.map +1 -1
- package/dist/chat/chat.question-dedup.d.ts.map +1 -1
- package/dist/chat/chat.question-dedup.js.map +1 -1
- package/dist/chat/chat.state.d.ts.map +1 -1
- package/dist/chat/chat.state.js.map +1 -1
- package/dist/chat/chat.streamer.d.ts.map +1 -1
- package/dist/chat/chat.streamer.js.map +1 -1
- package/dist/chat/chat.suggester.d.ts.map +1 -1
- package/dist/chat/chat.suggester.js.map +1 -1
- package/dist/chat/chat.summarizer.d.ts.map +1 -1
- package/dist/chat/chat.summarizer.js.map +1 -1
- package/dist/chat/chat.title.generator.d.ts.map +1 -1
- package/dist/chat/chat.title.generator.js.map +1 -1
- package/dist/chat/chat.tools.d.ts.map +1 -1
- package/dist/chat/chat.tools.js.map +1 -1
- package/dist/chat/chat.utils.d.ts.map +1 -1
- package/dist/chat/chat.utils.js.map +1 -1
- package/dist/chat/tests/chat.graph.mocks.d.ts.map +1 -1
- package/dist/chat/tests/chat.graph.mocks.js.map +1 -1
- package/dist/contact/contact.inviter.d.ts.map +1 -1
- package/dist/contact/contact.inviter.js.map +1 -1
- package/dist/contact/contact.tools.d.ts.map +1 -1
- package/dist/contact/contact.tools.js.map +1 -1
- package/dist/context/context.generator.d.ts.map +1 -1
- package/dist/context/context.generator.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/integration/integration.tools.d.ts.map +1 -1
- package/dist/integration/integration.tools.js.map +1 -1
- package/dist/intent/intent.clarifier.d.ts.map +1 -1
- package/dist/intent/intent.clarifier.js.map +1 -1
- package/dist/intent/intent.graph.d.ts.map +1 -1
- package/dist/intent/intent.graph.js.map +1 -1
- package/dist/intent/intent.indexer.d.ts.map +1 -1
- package/dist/intent/intent.indexer.js.map +1 -1
- package/dist/intent/intent.inferrer.d.ts.map +1 -1
- package/dist/intent/intent.inferrer.js.map +1 -1
- package/dist/intent/intent.reconciler.d.ts.map +1 -1
- package/dist/intent/intent.reconciler.js.map +1 -1
- package/dist/intent/intent.state.d.ts.map +1 -1
- package/dist/intent/intent.state.js.map +1 -1
- package/dist/intent/intent.tools.d.ts.map +1 -1
- package/dist/intent/intent.tools.js.map +1 -1
- package/dist/intent/intent.verifier.d.ts.map +1 -1
- package/dist/intent/intent.verifier.js.map +1 -1
- package/dist/maintenance/maintenance.graph.d.ts.map +1 -1
- package/dist/maintenance/maintenance.graph.js.map +1 -1
- package/dist/maintenance/maintenance.state.d.ts.map +1 -1
- package/dist/maintenance/maintenance.state.js.map +1 -1
- package/dist/mcp/elicitation.builder.d.ts.map +1 -1
- package/dist/mcp/elicitation.builder.js.map +1 -1
- package/dist/mcp/elicitation.dispatcher.d.ts.map +1 -1
- package/dist/mcp/elicitation.dispatcher.js.map +1 -1
- package/dist/mcp/mcp.server.d.ts.map +1 -1
- package/dist/mcp/mcp.server.js.map +1 -1
- package/dist/negotiation/insight.generator.d.ts.map +1 -1
- package/dist/negotiation/insight.generator.js.map +1 -1
- package/dist/negotiation/negotiation.agent.d.ts.map +1 -1
- package/dist/negotiation/negotiation.agent.js.map +1 -1
- package/dist/negotiation/negotiation.graph.d.ts.map +1 -1
- package/dist/negotiation/negotiation.graph.js.map +1 -1
- package/dist/negotiation/negotiation.state.d.ts.map +1 -1
- package/dist/negotiation/negotiation.state.js.map +1 -1
- package/dist/negotiation/negotiation.summarizer.d.ts.map +1 -1
- package/dist/negotiation/negotiation.summarizer.js.map +1 -1
- package/dist/negotiation/negotiation.tools.d.ts.map +1 -1
- package/dist/negotiation/negotiation.tools.js.map +1 -1
- package/dist/network/indexer/indexer.graph.d.ts.map +1 -1
- package/dist/network/indexer/indexer.graph.js.map +1 -1
- package/dist/network/indexer/indexer.state.d.ts.map +1 -1
- package/dist/network/indexer/indexer.state.js.map +1 -1
- package/dist/network/membership/membership.graph.d.ts.map +1 -1
- package/dist/network/membership/membership.graph.js.map +1 -1
- package/dist/network/membership/membership.state.d.ts.map +1 -1
- package/dist/network/membership/membership.state.js.map +1 -1
- package/dist/network/network.graph.d.ts.map +1 -1
- package/dist/network/network.graph.js.map +1 -1
- package/dist/network/network.state.d.ts.map +1 -1
- package/dist/network/network.state.js.map +1 -1
- package/dist/network/network.tools.d.ts.map +1 -1
- package/dist/network/network.tools.js.map +1 -1
- package/dist/opportunity/delivery-card.cache.d.ts.map +1 -1
- package/dist/opportunity/delivery-card.cache.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.categorizer.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.categorizer.js.map +1 -1
- package/dist/opportunity/feed/feed.graph.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.graph.js.map +1 -1
- package/dist/opportunity/feed/feed.health.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.health.js.map +1 -1
- package/dist/opportunity/feed/feed.state.d.ts.map +1 -1
- package/dist/opportunity/feed/feed.state.js.map +1 -1
- package/dist/opportunity/negotiation-context.loader.d.ts.map +1 -1
- package/dist/opportunity/negotiation-context.loader.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.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.evaluator.d.ts.map +1 -1
- package/dist/opportunity/opportunity.evaluator.js.map +1 -1
- package/dist/opportunity/opportunity.graph.d.ts.map +1 -1
- package/dist/opportunity/opportunity.graph.js.map +1 -1
- package/dist/opportunity/opportunity.introducer.d.ts.map +1 -1
- package/dist/opportunity/opportunity.introducer.js.map +1 -1
- package/dist/opportunity/opportunity.labels.d.ts.map +1 -1
- package/dist/opportunity/opportunity.labels.js.map +1 -1
- package/dist/opportunity/opportunity.pending-questions.d.ts.map +1 -1
- package/dist/opportunity/opportunity.pending-questions.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/opportunity.presentation.d.ts.map +1 -1
- package/dist/opportunity/opportunity.presentation.js.map +1 -1
- package/dist/opportunity/opportunity.presenter.d.ts.map +1 -1
- package/dist/opportunity/opportunity.presenter.js.map +1 -1
- package/dist/opportunity/opportunity.state.d.ts.map +1 -1
- package/dist/opportunity/opportunity.state.js.map +1 -1
- package/dist/opportunity/opportunity.tools.d.ts.map +1 -1
- package/dist/opportunity/opportunity.tools.js.map +1 -1
- package/dist/opportunity/opportunity.utils.d.ts.map +1 -1
- package/dist/opportunity/opportunity.utils.js.map +1 -1
- package/dist/opportunity/question.generator.d.ts.map +1 -1
- package/dist/opportunity/question.generator.js.map +1 -1
- package/dist/opportunity/question.prompt.d.ts.map +1 -1
- package/dist/opportunity/question.prompt.js.map +1 -1
- package/dist/premise/premise.analyzer.d.ts.map +1 -1
- package/dist/premise/premise.analyzer.js.map +1 -1
- package/dist/premise/premise.decomposer.d.ts.map +1 -1
- package/dist/premise/premise.decomposer.js.map +1 -1
- package/dist/premise/premise.graph.d.ts.map +1 -1
- package/dist/premise/premise.graph.js.map +1 -1
- package/dist/premise/premise.indexer.d.ts.map +1 -1
- package/dist/premise/premise.indexer.js.map +1 -1
- package/dist/premise/premise.state.d.ts.map +1 -1
- package/dist/premise/premise.state.js.map +1 -1
- package/dist/premise/premise.tools.d.ts.map +1 -1
- package/dist/premise/premise.tools.js.map +1 -1
- package/dist/profile/profile.enricher.d.ts.map +1 -1
- package/dist/profile/profile.enricher.js.map +1 -1
- package/dist/profile/profile.generator.d.ts.map +1 -1
- package/dist/profile/profile.generator.js.map +1 -1
- package/dist/profile/profile.graph.d.ts.map +1 -1
- package/dist/profile/profile.graph.js.map +1 -1
- package/dist/profile/profile.state.d.ts.map +1 -1
- package/dist/profile/profile.state.js.map +1 -1
- package/dist/profile/profile.tools.d.ts.map +1 -1
- package/dist/profile/profile.tools.js.map +1 -1
- package/dist/questioner/questioner.agent.d.ts.map +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.map +1 -1
- package/dist/questioner/questioner.types.d.ts.map +1 -1
- package/dist/questioner/questioner.types.js.map +1 -1
- package/dist/shared/agent/model-signal.d.ts.map +1 -1
- package/dist/shared/agent/model-signal.js.map +1 -1
- package/dist/shared/agent/model.config.d.ts.map +1 -1
- package/dist/shared/agent/model.config.js.map +1 -1
- package/dist/shared/agent/response.streamer.d.ts.map +1 -1
- package/dist/shared/agent/response.streamer.js.map +1 -1
- package/dist/shared/agent/tests/llm-assert.d.ts.map +1 -1
- package/dist/shared/agent/tests/llm-assert.js.map +1 -1
- package/dist/shared/agent/tool.factory.d.ts.map +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/agent/tool.registry.d.ts.map +1 -1
- package/dist/shared/agent/tool.registry.js.map +1 -1
- package/dist/shared/agent/tool.runtime.d.ts.map +1 -1
- package/dist/shared/agent/tool.runtime.js +4 -0
- package/dist/shared/agent/tool.runtime.js.map +1 -1
- package/dist/shared/agent/utility.tools.d.ts.map +1 -1
- package/dist/shared/agent/utility.tools.js.map +1 -1
- package/dist/shared/hyde/hyde.generator.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.generator.js.map +1 -1
- package/dist/shared/hyde/hyde.graph.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.graph.js.map +1 -1
- package/dist/shared/hyde/hyde.state.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.state.js.map +1 -1
- package/dist/shared/hyde/hyde.strategies.d.ts.map +1 -1
- package/dist/shared/hyde/hyde.strategies.js.map +1 -1
- package/dist/shared/hyde/lens.inferrer.d.ts.map +1 -1
- package/dist/shared/hyde/lens.inferrer.js.map +1 -1
- package/dist/shared/interfaces/agent-dispatcher.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/agent-dispatcher.interface.js.map +1 -1
- package/dist/shared/interfaces/agent.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/agent.interface.js.map +1 -1
- package/dist/shared/interfaces/auth.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/auth.interface.js.map +1 -1
- package/dist/shared/interfaces/cache.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/cache.interface.js.map +1 -1
- package/dist/shared/interfaces/chat-message-writer.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/chat-message-writer.interface.js.map +1 -1
- package/dist/shared/interfaces/chat-session.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/chat-session.interface.js.map +1 -1
- package/dist/shared/interfaces/chat-summary.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/chat-summary.interface.js.map +1 -1
- package/dist/shared/interfaces/connect-link.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/connect-link.interface.js.map +1 -1
- package/dist/shared/interfaces/contact.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/contact.interface.js.map +1 -1
- package/dist/shared/interfaces/database.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/database.interface.js.map +1 -1
- package/dist/shared/interfaces/delivery-ledger.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/delivery-ledger.interface.js.map +1 -1
- package/dist/shared/interfaces/discovery-run.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/discovery-run.interface.js.map +1 -1
- package/dist/shared/interfaces/embedder.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/embedder.interface.js.map +1 -1
- package/dist/shared/interfaces/enrichment.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/enrichment.interface.js.map +1 -1
- package/dist/shared/interfaces/integration.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/integration.interface.js.map +1 -1
- package/dist/shared/interfaces/negotiation-events.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/negotiation-events.interface.js.map +1 -1
- package/dist/shared/interfaces/negotiation-summary.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/negotiation-summary.interface.js.map +1 -1
- package/dist/shared/interfaces/question-generator.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/question-generator.interface.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/dist/shared/interfaces/queue.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/queue.interface.js.map +1 -1
- package/dist/shared/interfaces/scraper.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/scraper.interface.js.map +1 -1
- package/dist/shared/interfaces/storage.interface.d.ts.map +1 -1
- package/dist/shared/interfaces/storage.interface.js.map +1 -1
- package/dist/shared/network/metadata.renderer.d.ts.map +1 -1
- package/dist/shared/network/metadata.renderer.js.map +1 -1
- package/dist/shared/observability/debug-meta.sanitizer.d.ts.map +1 -1
- package/dist/shared/observability/debug-meta.sanitizer.js.map +1 -1
- package/dist/shared/observability/log.d.ts.map +1 -1
- package/dist/shared/observability/log.js.map +1 -1
- package/dist/shared/observability/performance.d.ts +7 -0
- package/dist/shared/observability/performance.d.ts.map +1 -1
- package/dist/shared/observability/performance.js +22 -10
- package/dist/shared/observability/performance.js.map +1 -1
- package/dist/shared/observability/protocol.logger.d.ts.map +1 -1
- package/dist/shared/observability/protocol.logger.js.map +1 -1
- package/dist/shared/observability/request-context.d.ts.map +1 -1
- package/dist/shared/observability/request-context.js.map +1 -1
- package/dist/shared/observability/trace.d.ts.map +1 -1
- package/dist/shared/observability/trace.js.map +1 -1
- package/dist/shared/schemas/chat-context.schema.d.ts.map +1 -1
- package/dist/shared/schemas/chat-context.schema.js.map +1 -1
- package/dist/shared/schemas/negotiation-digest.schema.d.ts.map +1 -1
- package/dist/shared/schemas/negotiation-digest.schema.js.map +1 -1
- package/dist/shared/schemas/pending-question.schema.d.ts.map +1 -1
- package/dist/shared/schemas/pending-question.schema.js.map +1 -1
- package/dist/shared/schemas/question.schema.d.ts.map +1 -1
- package/dist/shared/schemas/question.schema.js.map +1 -1
- package/dist/shared/ui/lucide.icon-catalog.d.ts.map +1 -1
- package/dist/shared/ui/lucide.icon-catalog.js.map +1 -1
- package/dist/shared/utils/social-label.d.ts.map +1 -1
- package/dist/shared/utils/social-label.js.map +1 -1
- package/dist/shared/utils/telegram-handle.d.ts.map +1 -1
- package/dist/shared/utils/telegram-handle.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.interface.js","sourceRoot":"","sources":["../../../src/shared/interfaces/database.interface.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"database.interface.js","sourceRoot":"/","sources":["shared/interfaces/database.interface.ts"],"names":[],"mappings":"","sourcesContent":["import { ProfileDocument } from '../../profile/profile.generator.js';\n\n// ─── Inlined types (previously imported from outside the protocol lib) ───────\n\n/** Branded string ID for type-safe entity references (keyed by Drizzle table name). */\nexport type Id<T extends string = string> = string & { readonly __table?: T };\n\nexport type PrivacyConsentSource = 'agentvillage_onboarding' | 'hermes_setup' | 'web_onboarding' | 'api';\n\nexport interface PrivacyConsentDecision {\n granted: boolean;\n decidedAt: string;\n source: PrivacyConsentSource;\n}\n\nexport interface OnboardingPrivacyState {\n edgeosImport?: PrivacyConsentDecision;\n publicProfileLookup?: PrivacyConsentDecision;\n}\n\nexport interface OnboardingProfileSeed {\n source: 'experiment_signup' | 'experiment_csv_import';\n networkId: string;\n capturedAt: string;\n name?: string;\n bio?: string;\n location?: string;\n socials?: { label: string; value: string }[];\n}\n\n/** Onboarding flow state stored as JSON on the user record. */\nexport interface OnboardingState {\n completedAt?: string;\n flow?: 1 | 2 | 3;\n currentStep?: 'profile' | 'summary' | 'connections' | 'create_network' | 'invite_members' | 'join_networks';\n networkId?: string;\n invitationCode?: string;\n privacy?: OnboardingPrivacyState;\n profileSeeds?: OnboardingProfileSeed[];\n}\n\n/** Single social-link row from the user_socials table. */\nexport interface UserSocial {\n id: string;\n userId: string;\n label: string;\n value: string;\n}\n\n/** Detection metadata recorded when an opportunity is created. */\nexport interface OpportunityDetection {\n source: 'opportunity_graph' | 'chat' | 'manual' | 'cron' | 'member_added' | 'enrichment' | 'introducer_discovery';\n createdBy?: Id<'users'> | string;\n createdByName?: string;\n triggeredBy?: Id<'intents'>;\n timestamp: string;\n enrichedFrom?: string[];\n}\n\n/** A participant (user + network) involved in an opportunity. */\nexport interface OpportunityActor {\n networkId: Id<'networks'>;\n userId: Id<'users'>;\n intent?: Id<'intents'>;\n /** Which premise grounded this match (set when discoverySource is 'premise-similarity'). */\n premise?: Id<'premises'>;\n role: string;\n /** Only set on role === 'introducer'. false until the introducer explicitly approves; true after approval. */\n approved?: boolean;\n /**\n * ISO-8601 timestamp set the first time this actor advanced the opportunity's\n * state (patient sending, agent accepting, peer \"accepting\" on draft = sending\n * under the hood, peer accepting on pending, introducer sending). Once set,\n * this actor has committed and cannot be the one to subsequently `accept` the\n * same opportunity — enforced by the self-accept guard in `updateNode`.\n */\n actedAt?: string;\n}\n\n/** Individual signal contributing to an opportunity score. */\nexport interface OpportunitySignal {\n type: string;\n weight: number;\n detail?: string;\n}\n\n/** LLM-generated interpretation of an opportunity's category and confidence. */\nexport interface OpportunityInterpretation {\n category: string;\n reasoning: string;\n confidence: number;\n signals?: OpportunitySignal[];\n}\n\n/** Optional scoping context (network / conversation) for an opportunity. */\nexport interface OpportunityContext {\n networkId?: Id<'networks'>;\n conversationId?: Id<'conversations'>;\n}\n\n/** User record returned by getUser (minimal fields plus optional profile fields). */\nexport interface UserRecord {\n id: string;\n name: string;\n email: string;\n intro?: string | null;\n avatar?: string | null;\n location?: string | null;\n socials: UserSocial[];\n onboarding?: OnboardingState | null;\n isGhost?: boolean;\n deletedAt?: Date | null;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// INTENT TYPES\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Minimal intent representation used for graph state population.\n * Contains only the fields needed for reconciliation logic.\n */\nexport interface ActiveIntent {\n /** Unique identifier of the intent */\n id: string;\n /** Full intent description/payload */\n payload: string;\n /** Short summary of the intent (may be null if not generated) */\n summary: string | null;\n /** When the intent was created */\n createdAt: Date;\n /** Relevancy score for this intent in its index context (0.0–1.0, null if not scored) */\n relevancyScore?: number | null;\n}\n\n/**\n * Input data for creating a new intent.\n * Supports the full intent pipeline including embedding and index association.\n */\nexport interface CreateIntentData {\n /** The user who owns this intent */\n userId: string;\n /** Full intent description/payload */\n payload: string;\n /** Pre-computed summary (optional, will be generated if not provided) */\n summary?: string | null;\n /** Pre-computed embedding vector (optional, will be generated if not provided) */\n embedding?: number[];\n /** Whether the intent should be hidden from public views */\n isIncognito?: boolean;\n /** Index IDs to associate with (optional, uses dynamic scoping if empty) */\n networkIds?: string[];\n /** Source type for provenance tracking */\n sourceType?: 'file' | 'integration' | 'link' | 'discovery_form' | 'enrichment';\n /** Source ID for provenance tracking */\n sourceId?: string;\n /** Confidence score from inference (0-1, required) */\n confidence: number;\n /** How the intent was inferred */\n inferenceType: 'explicit' | 'implicit';\n /** Semantic entropy from verifier (0 specific -> 1 vague) */\n semanticEntropy?: number | null;\n /** Referential anchor extracted by verifier (if any) */\n referentialAnchor?: string | null;\n /** Felicity authority score from verifier (0-100) */\n felicityAuthority?: number | null;\n /** Felicity sincerity score from verifier (0-100) */\n felicitySincerity?: number | null;\n /** Felicity clarity score from verifier (0-100) */\n felicityClarity?: number | null;\n /** Donnellan intent mode */\n intentMode?: 'REFERENTIAL' | 'ATTRIBUTIVE' | null;\n /** Speech act category used by protocol enum */\n speechActType?: 'COMMISSIVE' | 'DIRECTIVE' | null;\n}\n\n/**\n * Input data for updating an existing intent.\n * All fields are optional - only provided fields will be updated.\n */\nexport interface UpdateIntentData {\n /** Updated intent description/payload */\n payload?: string;\n /** Updated summary */\n summary?: string | null;\n /** Updated embedding vector */\n embedding?: number[];\n /** Updated incognito status */\n isIncognito?: boolean;\n /** Updated index associations (replaces existing) */\n networkIds?: string[];\n /** Semantic entropy from verifier (0 specific -> 1 vague) */\n semanticEntropy?: number | null;\n /** Referential anchor extracted by verifier (if any) */\n referentialAnchor?: string | null;\n /** Felicity authority score from verifier (0-100) */\n felicityAuthority?: number | null;\n /** Felicity sincerity score from verifier (0-100) */\n felicitySincerity?: number | null;\n /** Felicity clarity score from verifier (0-100) */\n felicityClarity?: number | null;\n /** Donnellan intent mode */\n intentMode?: 'REFERENTIAL' | 'ATTRIBUTIVE' | null;\n /** Speech act category used by protocol enum */\n speechActType?: 'COMMISSIVE' | 'DIRECTIVE' | null;\n}\n\n/**\n * The result of a successful intent creation.\n * Contains the core fields needed for immediate use.\n */\nexport interface CreatedIntent {\n /** Unique identifier of the created intent */\n id: string;\n /** Full intent description/payload */\n payload: string;\n /** Generated or provided summary */\n summary: string | null;\n /** Incognito status */\n isIncognito: boolean;\n /** Creation timestamp */\n createdAt: Date;\n /** Last update timestamp */\n updatedAt: Date;\n /** Owner user ID */\n userId: string;\n}\n\n/**\n * Full intent record with all fields (for detailed queries).\n */\nexport interface IntentRecord extends CreatedIntent {\n /** Archival timestamp (null if active) */\n archivedAt: Date | null;\n /** Embedding vector (may be null) */\n embedding?: number[] | null;\n /** Source type for provenance */\n sourceType?: string | null;\n /** Source ID for provenance */\n sourceId?: string | null;\n}\n\n/**\n * Intent with similarity score from vector search.\n */\nexport interface SimilarIntent extends IntentRecord {\n /** Cosine similarity score (0-1) */\n similarity: number;\n}\n\n/**\n * Result of an archive operation.\n */\nexport interface ArchiveResult {\n /** Whether the operation succeeded */\n success: boolean;\n /** Error message if failed */\n error?: string;\n}\n\n/**\n * Options for vector similarity search.\n */\nexport interface SimilarIntentSearchOptions {\n /** Maximum number of results to return (default: 10) */\n limit?: number;\n /** Minimum similarity threshold (default: 0.7) */\n threshold?: number;\n}\n\n/**\n * Represents a user's membership in an index with full details.\n * Used for displaying index memberships in chat (index_query).\n */\nexport interface NetworkMembership {\n /** Unique identifier of the index */\n networkId: string;\n /** Display title of the index */\n networkTitle: string;\n /** Index description/prompt (what the community is about) */\n indexPrompt: string | null;\n /** Member's permissions in this index */\n permissions: string[];\n /** Member's custom prompt (overrides index prompt for their intents) */\n memberPrompt: string | null;\n /** Whether new intents are auto-assigned to this index */\n autoAssign: boolean;\n /** Whether this is the user's personal index (\"My Network\") */\n isPersonal: boolean;\n /** When the user joined the index */\n joinedAt: Date;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// PREMISE TYPES\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport interface PremiseAssertion {\n text: string;\n tier: 'assertive' | 'contextual';\n summary?: string;\n}\n\nexport interface PremiseProvenance {\n source: 'explicit' | 'enrichment' | 'integration' | 'onboarding';\n sourceId?: string;\n confidence: number;\n timestamp: string;\n}\n\nexport interface PremiseAnalysis {\n speechActType: 'DECLARATIVE' | 'ASSERTIVE';\n felicityAuthority: number;\n felicitySincerity: number;\n felicityClarity: number;\n semanticEntropy: number;\n}\n\nexport interface PremiseValidity {\n validFrom?: string;\n validUntil?: string;\n volatile: boolean;\n}\n\nexport interface PremiseRecord {\n id: string;\n userId: string;\n assertion: PremiseAssertion;\n provenance: PremiseProvenance;\n analysis: PremiseAnalysis | null;\n validity: PremiseValidity;\n embedding: number[] | null;\n status: 'ACTIVE' | 'RETRACTED' | 'EXPIRED';\n createdAt: Date;\n updatedAt: Date;\n retractedAt: Date | null;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// INDEX OWNERSHIP TYPES\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Represents an index owned by the user with full details.\n */\nexport interface OwnedIndex {\n /** Index ID */\n id: string;\n /** Display title */\n title: string;\n /** Index purpose/scope prompt */\n prompt: string | null;\n /** Cover image URL */\n imageUrl: string | null;\n /** Permission settings */\n permissions: {\n joinPolicy: 'anyone' | 'invite_only';\n allowGuestVibeCheck: boolean;\n invitationLink: { code: string } | null;\n };\n /** Whether this is a personal index */\n isPersonal: boolean;\n /** When the index was created */\n createdAt: Date;\n /** When the index was last updated */\n updatedAt: Date;\n /** Member count */\n memberCount: number;\n /** Total intents indexed */\n intentCount: number;\n /** Owner summary */\n user: { id: string; name: string; avatar: string | null };\n /** Aggregate counts for frontend compatibility */\n _count: { members: number };\n}\n\n/**\n * Member details visible to index owners (and optionally to members with privacy rules).\n */\nexport interface IndexMemberDetails {\n /** User ID */\n userId: string;\n /** User's display name */\n name: string;\n /** User's avatar URL */\n avatar: string | null;\n /** User's email; only present when viewer is owner/admin or the member themselves (privacy-safe) */\n email?: string | null;\n /** Member's permissions in this index */\n permissions: string[];\n /** Member's custom prompt */\n memberPrompt: string | null;\n /** Whether auto-assign is enabled */\n autoAssign: boolean;\n /** When they joined */\n joinedAt: Date;\n /** Count of their intents in this index */\n intentCount: number;\n /** Whether this user is a ghost (not yet onboarded) */\n isGhost?: boolean;\n}\n\n/**\n * Intent details visible to index owners.\n */\nexport interface IndexedIntentDetails {\n /** Intent ID */\n id: string;\n /** Intent payload/description */\n payload: string;\n /** Intent summary */\n summary: string | null;\n /** Owner's user ID */\n userId: string;\n /** Owner's name */\n userName: string;\n /** When the intent was created */\n createdAt: Date;\n /** Relevancy score for this intent in its index context (0.0–1.0, null if not scored) */\n relevancyScore?: number | null;\n}\n\n/**\n * Options for updating index settings.\n */\nexport interface UpdateIndexSettingsData {\n /** New title (optional) */\n title?: string;\n /** New prompt (optional) */\n prompt?: string | null;\n /** New image URL (optional) */\n imageUrl?: string | null;\n /** New join policy (optional) */\n joinPolicy?: 'anyone' | 'invite_only';\n /** Allow guest vibe check (optional) */\n allowGuestVibeCheck?: boolean;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// HYDE DOCUMENT TYPES (Opportunity Redesign)\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport type HydeSourceType = 'intent' | 'profile' | 'query' | 'context';\n\nexport interface HydeDocument {\n id: string;\n sourceType: HydeSourceType;\n sourceId: string | null;\n sourceText: string | null;\n strategy: string;\n targetCorpus: string;\n hydeText: string;\n hydeEmbedding: number[];\n context: Record<string, unknown> | null;\n createdAt: Date;\n expiresAt: Date | null;\n}\n\nexport interface CreateHydeDocumentData {\n sourceType: HydeSourceType;\n sourceId?: string;\n sourceText?: string;\n strategy: string;\n targetCorpus: string;\n hydeText: string;\n hydeEmbedding: number[];\n context?: Record<string, unknown>;\n expiresAt?: Date;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// OPPORTUNITY TYPES (Opportunity Redesign)\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport type OpportunityStatus = 'latent' | 'draft' | 'negotiating' | 'pending' | 'stalled' | 'accepted' | 'rejected' | 'expired';\n\nexport interface Opportunity {\n id: string;\n detection: OpportunityDetection;\n actors: OpportunityActor[];\n interpretation: OpportunityInterpretation;\n context: OpportunityContext;\n confidence: string;\n status: OpportunityStatus;\n createdAt: Date;\n updatedAt: Date;\n expiresAt: Date | null;\n}\n\nexport interface CreateOpportunityData {\n detection: OpportunityDetection;\n actors: OpportunityActor[];\n interpretation: OpportunityInterpretation;\n context: OpportunityContext;\n confidence: string;\n status?: OpportunityStatus;\n expiresAt?: Date;\n}\n\nexport interface OpportunityQueryOptions {\n status?: OpportunityStatus;\n /** When set, filter to opportunities whose status is in this list. Orthogonal to `status` (single) — callers pick one. */\n statuses?: OpportunityStatus[];\n networkId?: string;\n role?: string;\n limit?: number;\n offset?: number;\n /** When set, include draft opportunities for this chat session. When unset, exclude all draft opportunities (e.g. home view, API). */\n conversationId?: string;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// DATABASE INTERFACE\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Abstract database interface for performing specific domain operations.\n * Decouples the protocol layer from the infrastructure layer.\n */\nexport interface Database {\n // ─────────────────────────────────────────────────────────────────────────────\n // Profile Operations (Preserved)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Retrieves a user profile by userId.\n * @param userId - The unique identifier of the user\n * @returns The user's profile or null if not found\n */\n getProfile(userId: string): Promise<ProfileDocument | null>;\n\n /**\n * Creates or updates a user profile.\n * @param userId - The unique identifier of the user\n * @param profile - The profile data to save\n */\n saveProfile(userId: string, profile: ProfileDocument): Promise<void>;\n\n /**\n * Retrieves basic user information (name, email, socials) by userId.\n * @param userId - The unique identifier of the user\n * @returns The user record or null if not found\n */\n getUser(userId: string): Promise<UserRecord | null>;\n\n /**\n * Updates user account fields (name, location, socials).\n * Merges socials with existing values (does not overwrite the whole object).\n * Used by create_user_profile tool to persist user-provided info before\n * invoking the Profile Graph in generate mode.\n *\n * @param userId - The unique identifier of the user\n * @param data - Partial user fields to update\n * @returns The updated user record or null if not found\n */\n updateUser(userId: string, data: { name?: string; intro?: string; location?: string; onboarding?: OnboardingState }): Promise<UserRecord | null>;\n\n getUserSocials(userId: string): Promise<UserSocial[]>;\n setUserSocials(userId: string, socials: { label: string; value: string }[]): Promise<void>;\n\n /**\n * Soft-delete a ghost user and all their contact memberships.\n * Used when enrichment determines the entity is not a real person.\n * @param userId - The ghost user to soft-delete\n * @returns true if the user was soft-deleted\n */\n softDeleteGhost(userId: string): Promise<boolean>;\n\n /**\n * Find an existing user that matches the given social handles.\n * Checks LinkedIn, GitHub, and Twitter/X handles (case-insensitive, exact match).\n * Excludes the given userId and soft-deleted users.\n * Prefers real users over ghosts; among ghosts, returns the oldest.\n * @param userId - The ghost user being enriched (excluded from results)\n * @param socials - Enriched social handles to match against\n * @returns The matching user's id, or null if no match\n */\n findDuplicateUser(userId: string, socials: UserSocial[]): Promise<{ id: string } | null>;\n\n /**\n * Merge a ghost user (source) into a target user.\n * Re-points all data (intents, opportunities, memberships, etc.) from source to target,\n * deletes ghost-only records (profile, sessions, etc.), and soft-deletes the source user.\n * Runs in a single transaction.\n * @param sourceId - The ghost user to merge away\n * @param targetId - The user to merge into\n */\n mergeGhostUser(sourceId: string, targetId: string): Promise<void>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Pre-Graph Operations (State Population)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Retrieves all active (non-archived) intents for a user.\n * Used to populate the `activeIntents` field in the Intent Graph state\n * before graph execution.\n *\n * @param userId - The unique identifier of the user\n * @returns Array of active intents with minimal fields needed for reconciliation\n *\n * @example\n * ```typescript\n * const activeIntents = await db.getActiveIntents(userId);\n * const formattedIntents = activeIntents\n * .map(i => `ID: ${i.id}, Description: ${i.payload}, Summary: ${i.summary || 'N/A'}`)\n * .join('\\n');\n * ```\n */\n getActiveIntents(userId: string): Promise<ActiveIntent[]>;\n\n /**\n * Get active intents that belong to the user and are assigned to a specific index.\n * Caller must be a member of that index; only the user's own intents are returned.\n *\n * @param userId - The user requesting (must be a member of the index)\n * @param indexNameOrId - Index UUID or display name (e.g. \"Commons\")\n * @returns Array of active intents in that index for the user, or empty if not a member / no match\n */\n getIntentsInIndexForMember(userId: string, indexNameOrId: string): Promise<ActiveIntent[]>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Post-Graph Operations (Action Execution)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Creates a new intent with full processing pipeline.\n * Handles summarization, embedding generation, and index association.\n *\n * Called when the reconciler outputs a \"create\" action.\n *\n * @param data - The intent creation data\n * @returns The created intent with generated fields\n *\n * @example\n * ```typescript\n * // After graph outputs CREATE action\n * const newIntent = await db.createIntent({\n * userId,\n * payload: action.payload,\n * confidence: action.score / 100,\n * inferenceType: 'explicit',\n * sourceType: 'discovery_form'\n * });\n * ```\n */\n createIntent(data: CreateIntentData): Promise<CreatedIntent>;\n\n /**\n * Updates an existing intent.\n * Re-generates summary and embedding if payload changes.\n *\n * Called when the reconciler outputs an \"update\" action.\n *\n * @param intentId - The unique identifier of the intent to update\n * @param data - The fields to update\n * @returns The updated intent or null if not found\n * @throws Error if the intent exists but user doesn't have access\n *\n * @example\n * ```typescript\n * // After graph outputs UPDATE action\n * const updated = await db.updateIntent(action.id, {\n * payload: action.payload\n * });\n * ```\n */\n updateIntent(intentId: string, data: UpdateIntentData): Promise<CreatedIntent | null>;\n\n /**\n * Archives (soft-deletes) an intent.\n * Sets the archivedAt timestamp rather than hard deleting.\n *\n * Called when the reconciler outputs an \"expire\" action.\n *\n * @param intentId - The unique identifier of the intent to archive\n * @returns Result object indicating success or failure with error message\n *\n * @example\n * ```typescript\n * // After graph outputs EXPIRE action\n * const result = await db.archiveIntent(action.id);\n * if (!result.success) {\n * console.error(`Failed to archive: ${result.error}`);\n * }\n * ```\n */\n archiveIntent(intentId: string): Promise<ArchiveResult>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Query Operations\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Retrieves a single intent by ID.\n *\n * @param intentId - The unique identifier of the intent\n * @returns The full intent record or null if not found\n */\n getIntent(intentId: string): Promise<IntentRecord | null>;\n\n /**\n * Retrieves an intent with ownership verification.\n * Ensures the requesting user owns the intent before returning.\n *\n * Used for processing operations (refine, suggestions) that require ownership.\n *\n * @param intentId - The unique identifier of the intent\n * @param userId - The user requesting access\n * @returns The intent if found and owned by user, null if not found\n * @throws Error with message 'Access denied' if intent exists but is not owned by user\n *\n * @example\n * ```typescript\n * try {\n * const intent = await db.getIntentWithOwnership(intentId, userId);\n * if (!intent) return res.status(404).json({ error: 'Not found' });\n * // Process intent...\n * } catch (e) {\n * if (e.message === 'Access denied') {\n * return res.status(403).json({ error: 'Forbidden' });\n * }\n * throw e;\n * }\n * ```\n */\n getIntentWithOwnership(intentId: string, userId: string): Promise<IntentRecord | null>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Index Association Operations\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Gets Index IDs where the user has auto-assign membership enabled.\n * Used for determining which indexes to associate new intents with.\n *\n * @param userId - The unique identifier of the user\n * @returns Array of index IDs\n *\n * @example\n * ```typescript\n * const networkIds = await db.getUserIndexIds(userId);\n * if (networkIds.length > 0) {\n * await db.associateIntentWithNetworks(intentId, networkIds);\n * }\n * ```\n */\n getUserIndexIds(userId: string): Promise<string[]>;\n\n /**\n * Retrieves all indexes the user is a member of with full details.\n * Used for displaying index memberships in chat (index_query).\n *\n * @param userId - The unique identifier of the user\n * @returns Array of index memberships with details\n */\n getNetworkMemberships(userId: string): Promise<NetworkMembership[]>;\n\n /**\n * Get a single index membership by index and user.\n * Used when the preloaded memberships list may not contain this index (e.g. after isNetworkMember check).\n *\n * @param networkId - The index ID\n * @param userId - The user ID\n * @returns The membership or null if not found\n */\n getNetworkMembership(networkId: string, userId: string): Promise<NetworkMembership | null>;\n\n /**\n * Get index by ID with core fields. Used for opportunity presentation and context rendering.\n */\n getNetwork(networkId: string): Promise<{\n id: string;\n title: string;\n prompt?: string | null;\n type?: string;\n metadata?: Record<string, unknown> | null;\n permissions?: Record<string, unknown> | null;\n } | null>;\n\n /**\n * Get index by ID with permissions (e.g. joinPolicy). Used by chat tools for create_index_membership.\n */\n getNetworkWithPermissions(networkId: string): Promise<{ id: string; title: string; permissions: { joinPolicy: 'anyone' | 'invite_only' } } | null>;\n\n /**\n * Associates an intent with one or more networks.\n * Creates entries in the intentNetworks join table.\n *\n * @param intentId - The intent to associate\n * @param networkIds - Array of network IDs to associate with\n *\n * @example\n * ```typescript\n * await db.associateIntentWithNetworks(intentId, ['idx_1', 'idx_2']);\n * ```\n */\n associateIntentWithNetworks(intentId: string, networkIds: string[]): Promise<void>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Vector Search Operations\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Finds semantically similar intents using vector search.\n * Used for deduplication during intent creation and discovery.\n *\n * Privacy scoping: Results are always filtered by userId to ensure\n * users only see their own intents.\n *\n * @param embedding - The query embedding vector\n * @param userId - The user ID for privacy scoping (required)\n * @param options - Search options (limit, threshold)\n * @returns Array of intents with similarity scores, sorted by similarity\n *\n * @example\n * ```typescript\n * // Check for duplicates before creating\n * const embedding = await embedder.generate(payload);\n * const similar = await db.findSimilarIntents(embedding, userId, {\n * limit: 5,\n * threshold: 0.85\n * });\n * if (similar.length > 0 && similar[0].similarity > 0.95) {\n * // Likely duplicate - consider updating instead\n * }\n * ```\n */\n findSimilarIntents(\n embedding: number[],\n userId: string,\n options?: SimilarIntentSearchOptions\n ): Promise<SimilarIntent[]>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Index Graph Operations (Intent–Index Assignment)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Intent fields needed for index appropriateness evaluation.\n */\n getIntentForIndexing(intentId: string): Promise<{\n id: string;\n payload: string;\n userId: string;\n sourceType: string | null;\n sourceId: string | null;\n } | null>;\n\n /**\n * Index + member prompts for a user in an index (only when member has autoAssign).\n * Returns null if user is not a member or autoAssign is false.\n */\n getNetworkMemberContext(\n networkId: string,\n userId: string\n ): Promise<{\n networkId: string;\n indexPrompt: string | null;\n memberPrompt: string | null;\n } | null>;\n\n /**\n * Whether the intent is currently assigned to the index.\n */\n isIntentAssignedToIndex(intentId: string, networkId: string): Promise<boolean>;\n\n /**\n * Assigns an intent to an index (inserts intent_indexes row).\n */\n assignIntentToNetwork(intentId: string, networkId: string, relevancyScore?: number): Promise<void>;\n\n /**\n * Returns per-index relevancy scores for an intent's index assignments.\n */\n getIntentIndexScores(intentId: string): Promise<Array<{ networkId: string; relevancyScore: number | null }>>;\n\n /**\n * Removes an intent from an index (deletes intent_indexes row).\n */\n unassignIntentFromIndex(intentId: string, networkId: string): Promise<void>;\n\n /**\n * Returns all network IDs that an intent is registered to.\n */\n getNetworkIdsForIntent(intentId: string): Promise<string[]>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Index Ownership Operations (Owner-Only)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Get indexes where the user has owner permissions.\n * Returns full index details with member and intent counts.\n *\n * @param userId - The user ID to check ownership for\n * @returns Array of owned indexes with counts\n */\n getOwnedIndexes(userId: string): Promise<OwnedIndex[]>;\n\n /**\n * Get public indexes (joinPolicy 'anyone') that the user has not joined.\n * Used for discovering communities available to join.\n *\n * @param userId - The user ID to check memberships against\n * @returns Object containing array of public indexes with owner info\n */\n getPublicIndexesNotJoined(userId: string): Promise<{\n networks: Array<{\n id: string;\n title: string;\n prompt: string | null;\n memberCount: number;\n owner: { id: string; name: string; avatar: string | null } | null;\n }>;\n }>;\n\n /**\n * Check if user is an owner of a specific index.\n *\n * @param networkId - The index to check\n * @param userId - The user to verify ownership for\n * @returns True if user is an owner\n */\n isIndexOwner(networkId: string, userId: string): Promise<boolean>;\n\n /**\n * Check if user is a member of a specific index.\n *\n * @param networkId - The index to check\n * @param userId - The user to verify membership for\n * @returns True if user is a member\n */\n isNetworkMember(networkId: string, userId: string): Promise<boolean>;\n\n /**\n * Get all members of an index with their details.\n * **OWNER ONLY** - throws if user is not an owner.\n *\n * @param networkId - The index to get members for\n * @param requestingUserId - The user requesting (must be owner)\n * @returns Array of member details with intent counts\n * @throws Error if requestingUserId is not an owner\n */\n getNetworkMembersForOwner(\n networkId: string,\n requestingUserId: string\n ): Promise<IndexMemberDetails[]>;\n\n /**\n * Get all members of an index with their details.\n * **MEMBER ONLY** - any member of the index can list members (not just owners).\n * Returns same shape as getNetworkMembersForOwner; email may be omitted for privacy.\n *\n * @param networkId - The index to get members for\n * @param requestingUserId - The user requesting (must be a member of the index)\n * @returns Array of member details with intent counts\n * @throws Error if requestingUserId is not a member of the index\n */\n getNetworkMembersForMember(\n networkId: string,\n requestingUserId: string\n ): Promise<IndexMemberDetails[]>;\n\n /**\n * Get all members from every index the user is a member of (deduplicated).\n * Used for mentionable-users: anyone who shares at least one index with the requesting user.\n *\n * @param userId - The signed-in user\n * @returns Array of member summaries (id, name, avatar only; no email)\n */\n getMembersFromUserIndexes(userId: Id<'users'>): Promise<{ userId: Id<'users'>; name: string; avatar: string | null }[]>;\n\n /**\n * Get all indexed intents for an index.\n * **OWNER ONLY** - throws if user is not an owner.\n *\n * @param networkId - The index to get intents for\n * @param requestingUserId - The user requesting (must be owner)\n * @param options - Pagination options\n * @returns Array of intent details with owner info\n * @throws Error if requestingUserId is not an owner\n */\n getNetworkIntentsForOwner(\n networkId: string,\n requestingUserId: string,\n options?: { limit?: number; offset?: number }\n ): Promise<IndexedIntentDetails[]>;\n\n /**\n * Get all indexed intents for an index.\n * **MEMBER ONLY** - any member of the index can list intents (not just owners).\n *\n * @param networkId - The index to get intents for\n * @param requestingUserId - The user requesting (must be a member of the index)\n * @param options - Pagination options\n * @returns Array of intent details with owner info\n * @throws Error if requestingUserId is not a member of the index\n */\n getNetworkIntentsForMember(\n networkId: string,\n requestingUserId: string,\n options?: { limit?: number; offset?: number }\n ): Promise<IndexedIntentDetails[]>;\n\n /**\n * Get the caller's own active intents across a set of indexes.\n * Returns intents owned by `userId` that are linked (via intent_networks)\n * to at least one of `indexIds`. Used by network-scoped agents to honor\n * indexScope without falling back to global getActiveIntents (which would\n * include intents in indexes outside scope).\n *\n * @param userId - The intent owner (always the caller).\n * @param indexIds - The set of index IDs to filter on. Empty → empty result.\n * @returns Active intents owned by userId in any of indexIds, deduped by intent id.\n */\n getActiveIntentsAcrossIndexes(userId: string, indexIds: string[]): Promise<ActiveIntent[]>;\n\n /**\n * Update index settings.\n * **OWNER ONLY** - throws if user is not an owner.\n *\n * @param networkId - The index to update\n * @param requestingUserId - The user requesting (must be owner)\n * @param data - The settings to update\n * @returns The updated index\n * @throws Error if requestingUserId is not an owner\n */\n updateIndexSettings(\n networkId: string,\n requestingUserId: string,\n data: UpdateIndexSettingsData\n ): Promise<OwnedIndex>;\n\n /**\n * Soft-delete a network (set deletedAt).\n * Caller must ensure network is not personal and has no other members.\n *\n * @param networkId - The network to soft-delete\n */\n softDeleteNetwork(networkId: string): Promise<void>;\n\n /**\n * Delete a user's profile (removes profile row).\n * Used after confirmation in chat tools.\n *\n * @param userId - User whose profile to delete\n */\n deleteProfile(userId: string): Promise<void>;\n\n /**\n * Get a user's profile including its row id (for update_user_profile validation).\n *\n * @param userId - The user whose profile to fetch\n * @returns Profile with id, or null if not found\n */\n getProfileByUserId(userId: string): Promise<(ProfileDocument & { id: string }) | null>;\n\n /**\n * Create a new index and return its record.\n *\n * @param data - Title, optional prompt, optional imageUrl, optional joinPolicy\n * @returns The created index with id, title, prompt, imageUrl, permissions\n */\n createNetwork(data: {\n title: string;\n prompt?: string | null;\n imageUrl?: string | null;\n joinPolicy?: 'anyone' | 'invite_only';\n }): Promise<{\n id: string;\n title: string;\n prompt: string | null;\n imageUrl: string | null;\n permissions: { joinPolicy: 'anyone' | 'invite_only'; invitationLink: { code: string } | null; allowGuestVibeCheck: boolean };\n }>;\n\n /**\n * Count members in an index (for delete guard).\n *\n * @param networkId - The index to count\n * @returns Number of members\n */\n getNetworkMemberCount(networkId: string): Promise<number>;\n\n /**\n * Add a user as a member of a network.\n *\n * @param networkId - The network to add to\n * @param userId - The user to add\n * @param role - owner | member\n * @returns success and optionally alreadyMember if they were already in the network\n */\n addMemberToNetwork(\n networkId: string,\n userId: string,\n role: 'owner' | 'member'\n ): Promise<{ success: boolean; alreadyMember?: boolean }>;\n\n /**\n * Removes a user from an index.\n * Only the index owner can remove members. Cannot remove the owner.\n *\n * @param networkId - The index to remove from\n * @param userId - The user to remove\n * @returns success, or wasOwner/notMember if removal failed\n */\n removeMemberFromIndex(\n networkId: string,\n userId: string\n ): Promise<{ success: boolean; wasOwner?: boolean; notMember?: boolean }>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // HyDE Document Operations (Opportunity Redesign)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Get a HyDE document by source and strategy/lens hash.\n * Returns the first matching document when multiple target corpuses exist.\n *\n * @param sourceType - 'intent' | 'profile' | 'query'\n * @param sourceId - Source entity ID (e.g. intent ID, user ID)\n * @param strategy - Lens hash (SHA-256 of lens label) or legacy strategy name\n * @returns The HyDE document or null if not found\n */\n getHydeDocument(\n sourceType: HydeSourceType,\n sourceId: string,\n strategy: string\n ): Promise<HydeDocument | null>;\n\n /**\n * Get all HyDE documents for a source (all strategies).\n *\n * @param sourceType - 'intent' | 'profile' | 'query'\n * @param sourceId - Source entity ID\n * @returns Array of HyDE documents for that source\n */\n getHydeDocumentsForSource(\n sourceType: HydeSourceType,\n sourceId: string\n ): Promise<HydeDocument[]>;\n\n /**\n * Save a HyDE document (upsert by sourceType + sourceId + strategy/lensHash + targetCorpus).\n *\n * @param data - HyDE document data\n * @returns The saved HyDE document\n */\n saveHydeDocument(data: CreateHydeDocumentData): Promise<HydeDocument>;\n\n /**\n * Delete all HyDE documents for a source (e.g. when intent/profile archived).\n *\n * @param sourceType - 'intent' | 'profile' | 'query'\n * @param sourceId - Source entity ID\n * @returns Number of documents deleted\n */\n deleteHydeDocumentsForSource(\n sourceType: HydeSourceType,\n sourceId: string\n ): Promise<number>;\n\n /**\n * Delete expired HyDE documents (expires_at <= now). Used by maintenance jobs.\n *\n * @returns Number of documents deleted\n */\n deleteExpiredHydeDocuments(): Promise<number>;\n\n /**\n * Get stale HyDE documents for refresh (e.g. createdAt < threshold).\n *\n * @param threshold - Date threshold; documents created before this are considered stale\n * @returns Array of stale HyDE documents\n */\n getStaleHydeDocuments(threshold: Date): Promise<HydeDocument[]>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Opportunity Operations (Opportunity Redesign)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /**\n * Create a new opportunity.\n *\n * @param data - Opportunity creation data\n * @returns The created opportunity\n */\n createOpportunity(data: CreateOpportunityData): Promise<Opportunity>;\n\n /**\n * Get a single opportunity by ID.\n *\n * @param id - Opportunity ID\n * @returns The opportunity or null if not found\n */\n getOpportunity(id: string): Promise<Opportunity | null>;\n\n /**\n * Get multiple opportunities by ID in a single batched query.\n *\n * Returns rows in arbitrary order; callers should index by `id`.\n * Missing IDs are silently dropped (no error).\n *\n * @param ids - Opportunity IDs (deduplicated by the caller is fine but not required)\n * @returns Opportunities found\n */\n getOpportunitiesByIds(ids: string[]): Promise<Opportunity[]>;\n\n /**\n * Resolve an opportunity identifier (full UUID or short prefix) to a full UUID.\n * @param idOrPrefix - Full UUID or short hex prefix\n * @param userId - The user ID (for visibility scoping)\n * @returns Resolved ID, ambiguous marker, or null if not found\n */\n resolveOpportunityId(idOrPrefix: string, userId: string): Promise<{ id: string } | { ambiguous: true } | null>;\n\n /**\n * Get opportunities for a user (as any actor role).\n *\n * @param userId - User ID (actor userId)\n * @param options - Optional filters and pagination\n * @returns Array of opportunities\n */\n getOpportunitiesForUser(\n userId: string,\n options?: OpportunityQueryOptions\n ): Promise<Opportunity[]>;\n\n /**\n * Get opportunities in an index (for index admins).\n *\n * @param networkId - Index ID\n * @param options - Optional filters and pagination\n * @returns Array of opportunities\n */\n getOpportunitiesForNetwork(\n networkId: string,\n options?: OpportunityQueryOptions\n ): Promise<Opportunity[]>;\n\n /**\n * Update an opportunity's status.\n *\n * @param id - Opportunity ID\n * @param status - New status\n * @returns The updated opportunity or null if not found\n */\n updateOpportunityStatus(\n id: string,\n status: OpportunityStatus,\n acceptedBy?: string,\n ): Promise<Opportunity | null>;\n\n /**\n * Stamp `actedAt` on the actor matching `actorUserId` and update the\n * opportunity's status atomically (row-lock + JSONB merge in one txn).\n *\n * Used by `sendNode` (status → 'pending') and `updateNode` (status →\n * 'accepted'). The self-accept guard is enforced in the caller, not here —\n * this method blindly stamps. Callers must pre-check `actor.actedAt` before\n * invocation when the semantics require it (i.e. accepting).\n *\n * @param id - Opportunity ID\n * @param actorUserId - The user whose actor entry should be stamped\n * @param status - New opportunity status\n * @param acceptedBy - Required when `status === 'accepted'`\n * @returns The updated opportunity, or null if not found\n */\n stampOpportunityActorAction(\n id: string,\n actorUserId: string,\n status: OpportunityStatus,\n acceptedBy?: string,\n ): Promise<Opportunity | null>;\n\n /**\n * Update the `approved` field on an opportunity's introducer actor.\n * Fetches the opportunity, patches the matching actor in JS, and writes\n * the updated actors JSONB back. Returns the updated opportunity or null.\n */\n updateOpportunityActorApproval(\n id: string,\n introducerUserId: string,\n approved: boolean,\n ): Promise<Opportunity | null>;\n\n /**\n * Create one opportunity and expire others in a single transaction.\n * Atomic: insert then update status to 'expired' for each id in expireIds.\n * Used when enriching replaces overlapping opportunities so subscribers see consistent state.\n *\n * @param data - Opportunity creation data (caller may set status when enriched)\n * @param expireIds - Opportunity IDs to set status to 'expired'\n * @returns The created opportunity and the list of opportunities that were expired\n */\n createOpportunityAndExpireIds(\n data: CreateOpportunityData,\n expireIds: string[]\n ): Promise<{ created: Opportunity; expired: Opportunity[] }>;\n\n /**\n * Check if an opportunity already exists between the given actors in the index (deduplication).\n *\n * @param actorIds - Array of user IDs that would be actors\n * @param networkId - Index ID\n * @returns True if a non-expired opportunity exists with exactly these actors in this index\n */\n opportunityExistsBetweenActors(\n actorIds: string[],\n networkId: string\n ): Promise<boolean>;\n\n /**\n * Find opportunities whose actors contain all the given user IDs.\n *\n * The `includeIntroducers` flag controls actor matching: when false (default), matching\n * is restricted to non-introducer roles; when true, any role in `actors` counts.\n *\n * Index-agnostic. Ordered by updatedAt desc.\n *\n * @param actorIds - User IDs that must all appear in each returned opportunity's actors\n * @param options - includeIntroducers (default false), statuses (include filter), excludeStatuses (exclude filter)\n * @returns Matching opportunities, newest first\n */\n findOpportunitiesByActors(\n actorIds: string[],\n options?: {\n includeIntroducers?: boolean;\n statuses?: OpportunityStatus[];\n excludeStatuses?: OpportunityStatus[];\n }\n ): Promise<Opportunity[]>;\n\n /**\n * Expire opportunities referencing an intent (e.g. when intent is archived).\n *\n * @param intentId - Intent ID to match in opportunity actors\n * @returns Number of opportunities updated to expired\n */\n expireOpportunitiesByIntent(intentId: string): Promise<number>;\n\n /**\n * Expire opportunities for a user removed from an index.\n *\n * @param networkId - Index ID\n * @param userId - User ID that was removed\n * @returns Number of opportunities updated to expired\n */\n expireOpportunitiesForRemovedMember(\n networkId: string,\n userId: string\n ): Promise<number>;\n\n /**\n * Expire opportunities whose expires_at <= now. Used by maintenance cron.\n *\n * @returns Number of opportunities updated to expired\n */\n expireStaleOpportunities(): Promise<number>;\n\n /**\n * Accept all sibling opportunities between the same actor pair in one transaction.\n * Selects opportunities where both userId and counterpartUserId are actors and status\n * is not accepted/expired/rejected, excludes excludeOpportunityId, then bulk-updates status to accepted.\n * Rolls back on any failure.\n *\n * @param userId - First actor user ID\n * @param counterpartUserId - Second actor user ID\n * @param excludeOpportunityId - Opportunity ID to exclude (the one already being accepted)\n * @returns IDs of opportunities that were updated to accepted\n */\n acceptSiblingOpportunities(\n userId: string,\n counterpartUserId: string,\n excludeOpportunityId: string\n ): Promise<string[]>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Contact / My Network Operations\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Create a ghost user (unregistered contact) with empty profile. */\n createGhostUser(data: { name: string; email: string }): Promise<{ id: string }>;\n\n /** Upsert a contact membership in the owner's personal index (index_members with permissions=['contact']). */\n upsertContactMembership(ownerId: string, contactUserId: string, options?: { restore?: boolean }): Promise<void>;\n\n /**\n * Finds an existing DM conversation between two users, or creates one.\n * Uses a unique `dmPair` column (sorted user IDs joined by ':') to\n * prevent duplicate DMs under concurrency. Used by the Start Chat flow\n * (Plan B Task 8) to atomically surface the h2h conversation when\n * accepting an opportunity.\n */\n getOrCreateDM(userA: string, userB: string, participantType?: 'user' | 'agent'): Promise<{ id: string }>;\n\n /**\n * Clears hiddenAt for a user on a conversation, making it visible in their\n * conversation list again. Called by startChat when reusing an existing DM\n * that the user had previously hidden.\n */\n unhideConversation(userId: string, conversationId: string): Promise<void>;\n\n /** Hard-delete a contact membership from the owner's personal index. */\n hardDeleteContactMembership(ownerId: string, contactUserId: string): Promise<void>;\n\n /** Get all contact members from the owner's personal index with user details. */\n getContactMembers(ownerId: string): Promise<Array<{\n userId: string;\n user: { id: string; name: string; email: string; avatar: string | null; isGhost: boolean };\n }>>;\n\n /** Clear a reverse opt-out (reactivate soft-deleted contact membership in another user's personal index). */\n clearReverseOptOut(ownerId: string, otherUserId: string): Promise<void>;\n\n /**\n * Returns the IDs of personal indexes where the given user is a contact member.\n * Used for auto-assigning new intents to personal indexes of contacts who imported this user.\n *\n * @param userId - The user whose contact memberships to look up\n * @returns Array of personal index IDs\n */\n getPersonalIndexesForContact(userId: string): Promise<{ networkId: string }[]>;\n\n /** Find a user by email. */\n getUserByEmail(email: string): Promise<{ id: string; name: string; email: string; isGhost: boolean } | null>;\n\n // ─── Premise operations ──────────────────────────────────────────────────────\n\n createPremise(input: {\n userId: string;\n assertion: PremiseAssertion;\n provenance: PremiseProvenance;\n analysis?: PremiseAnalysis;\n validity: PremiseValidity;\n embedding?: number[];\n }): Promise<PremiseRecord>;\n\n getPremise(premiseId: string): Promise<PremiseRecord | null>;\n\n getPremisesForUser(userId: string, status?: 'ACTIVE' | 'RETRACTED' | 'EXPIRED'): Promise<PremiseRecord[]>;\n\n updatePremise(premiseId: string, updates: {\n assertion?: PremiseAssertion;\n analysis?: PremiseAnalysis;\n validity?: PremiseValidity;\n embedding?: number[];\n status?: 'ACTIVE' | 'RETRACTED' | 'EXPIRED';\n retractedAt?: Date;\n }): Promise<PremiseRecord>;\n\n assignPremiseToNetwork(premiseId: string, networkId: string, relevancyScore: number): Promise<void>;\n\n getPremiseNetworks(premiseId: string): Promise<Array<{ networkId: string; relevancyScore: number | null }>>;\n\n /**\n * Cosine similarity search against premise embeddings, scoped to shared networks.\n * Used by the opportunity graph's premise discovery path (path D).\n */\n searchPremisesBySimilarity(params: {\n embedding: number[];\n networkIds: string[];\n excludeUserId: string;\n limit: number;\n }): Promise<Array<{\n premiseId: string;\n userId: string;\n networkId: string;\n assertionText: string;\n similarity: number;\n }>>;\n\n // ─── User Context Methods ───\n\n /**\n * Upsert a user context for a specific network.\n * Creates or updates the synthesized context paragraph + embedding.\n */\n upsertUserContext(params: {\n userId: string;\n networkId: string;\n text: string;\n embedding: number[];\n premiseHash: string;\n }): Promise<{ id: string }>;\n\n /**\n * Get the user context for a specific user+network pair.\n */\n getUserContext(userId: string, networkId: string): Promise<{\n id: string;\n text: string;\n embedding: number[];\n premiseHash: string;\n generatedAt: Date;\n } | null>;\n\n /**\n * Get user contexts for a user across all their networks.\n */\n getUserContexts(userId: string): Promise<Array<{\n id: string;\n networkId: string;\n text: string;\n embedding: number[];\n premiseHash: string;\n generatedAt: Date;\n }>>;\n\n /**\n * Cosine similarity search against intent embeddings using a context embedding.\n * Restores the profile→intent cross-search deleted when Path B was removed.\n */\n searchIntentsByContextEmbedding(params: {\n embedding: number[];\n networkIds: string[];\n excludeUserId: string;\n limit: number;\n minScore?: number;\n }): Promise<Array<{\n intentId: string;\n userId: string;\n networkId: string;\n payload: string;\n summary: string | null;\n similarity: number;\n }>>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// USER DATABASE INTERFACE (Own Resources Only)\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Context-bound database for accessing the authenticated user's own resources.\n * Created with authUserId bound at construction; no userId parameter needed on methods.\n *\n * **NOT index-scoped**: Returns ALL of the user's own resources regardless of index.\n * This is critical for the IntentReconciler which needs the full picture for deduplication.\n *\n * Use via `createUserDatabase(db, authUserId)` factory function.\n */\nexport interface UserDatabase {\n /** The bound authenticated user ID */\n readonly authUserId: string;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Profile Operations (own only)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get the authenticated user's profile. */\n getProfile(): Promise<ProfileDocument | null>;\n\n /** Get the authenticated user's profile with row ID. */\n getProfileByUserId(): Promise<(ProfileDocument & { id: string }) | null>;\n\n /** Save/update the authenticated user's profile. */\n saveProfile(profile: ProfileDocument): Promise<void>;\n\n /** Delete the authenticated user's profile. */\n deleteProfile(): Promise<void>;\n\n /** Get the authenticated user's basic record (name, email, socials). */\n getUser(): Promise<UserRecord | null>;\n\n /** Update the authenticated user's account fields. */\n updateUser(data: { name?: string; intro?: string; location?: string; onboarding?: OnboardingState }): Promise<UserRecord | null>;\n\n getUserSocials(): Promise<UserSocial[]>;\n setUserSocials(socials: { label: string; value: string }[]): Promise<void>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Intent Operations (own only, ALL intents - not index-scoped)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get ALL active intents for the authenticated user (not index-filtered). */\n getActiveIntents(): Promise<ActiveIntent[]>;\n\n /**\n * Case-insensitive substring search over the authenticated user's own\n * active intents. Matches against `payload` and `summary`. Most recent first.\n */\n searchOwnIntents(\n q: string,\n limit: number,\n ): Promise<Array<{ id: string; payload: string; summary: string | null; createdAt: Date }>>;\n\n /** Get a single intent by ID (ownership enforced). */\n getIntent(intentId: string): Promise<IntentRecord | null>;\n\n /** Create a new intent for the authenticated user. */\n createIntent(data: Omit<CreateIntentData, 'userId'>): Promise<CreatedIntent>;\n\n /** Update an intent owned by the authenticated user. */\n updateIntent(intentId: string, data: UpdateIntentData): Promise<CreatedIntent | null>;\n\n /** Archive an intent owned by the authenticated user. */\n archiveIntent(intentId: string): Promise<ArchiveResult>;\n\n /** Find similar intents among the user's own intents (for deduplication). */\n findSimilarIntents(embedding: number[], options?: SimilarIntentSearchOptions): Promise<SimilarIntent[]>;\n\n /** Get intent fields for indexing (own intent). */\n getIntentForIndexing(intentId: string): Promise<{\n id: string;\n payload: string;\n userId: string;\n sourceType: string | null;\n sourceId: string | null;\n } | null>;\n\n /** Associate an intent with networks. */\n associateIntentWithNetworks(intentId: string, networkIds: string[]): Promise<void>;\n\n /** Assign an intent to an index. */\n assignIntentToNetwork(intentId: string, networkId: string, relevancyScore?: number): Promise<void>;\n\n /** Unassign an intent from an index. */\n unassignIntentFromIndex(intentId: string, networkId: string): Promise<void>;\n\n /** Get network IDs for an intent. */\n getNetworkIdsForIntent(intentId: string): Promise<string[]>;\n\n /** Check if intent is assigned to index. */\n isIntentAssignedToIndex(intentId: string, networkId: string): Promise<boolean>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Index Membership Operations (own memberships only)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get all index memberships for the authenticated user. */\n getNetworkMemberships(): Promise<NetworkMembership[]>;\n\n /** Get index IDs with auto-assign enabled for the authenticated user. */\n getUserIndexIds(): Promise<string[]>;\n\n /** Get indexes owned by the authenticated user. */\n getOwnedIndexes(): Promise<OwnedIndex[]>;\n\n /** Get a specific index membership for the authenticated user. */\n getNetworkMembership(networkId: string): Promise<NetworkMembership | null>;\n\n /** Get index + member context for the authenticated user (for auto-assign). */\n getNetworkMemberContext(networkId: string): Promise<{\n networkId: string;\n indexPrompt: string | null;\n memberPrompt: string | null;\n } | null>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Index CRUD Operations (owner operations on own indexes)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Create a new index (user becomes owner). */\n createNetwork(data: {\n title: string;\n prompt?: string | null;\n imageUrl?: string | null;\n joinPolicy?: 'anyone' | 'invite_only';\n }): Promise<{\n id: string;\n title: string;\n prompt: string | null;\n imageUrl: string | null;\n permissions: { joinPolicy: 'anyone' | 'invite_only'; invitationLink: { code: string } | null; allowGuestVibeCheck: boolean };\n }>;\n\n /** Update index settings (owner only). */\n updateIndexSettings(networkId: string, data: UpdateIndexSettingsData): Promise<OwnedIndex>;\n\n /** Soft-delete a network (owner only). */\n softDeleteNetwork(networkId: string): Promise<void>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Public Index Discovery (joinable indexes the user is not a member of)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get public indexes (joinPolicy 'anyone') that the user has not joined. */\n getPublicIndexesNotJoined(): Promise<{\n networks: Array<{\n id: string;\n title: string;\n prompt: string | null;\n memberCount: number;\n owner: { id: string; name: string; avatar: string | null } | null;\n }>;\n }>;\n\n /** Join a public index (validates joinPolicy === 'anyone'). */\n joinPublicNetwork(networkId: string): Promise<{ success: boolean; alreadyMember?: boolean }>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Opportunity Operations (where user is actor)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get opportunities where the authenticated user is an actor. */\n getOpportunitiesForUser(options?: OpportunityQueryOptions): Promise<Opportunity[]>;\n\n /** Get a specific opportunity (if user is an actor). */\n getOpportunity(id: string): Promise<Opportunity | null>;\n\n /** Update an opportunity's status (if user is an actor). acceptedBy is derived from the auth context. */\n updateOpportunityStatus(id: string, status: OpportunityStatus): Promise<Opportunity | null>;\n\n /** Accept sibling opportunities between the authenticated user and another actor. */\n acceptSiblingOpportunities(counterpartUserId: string, excludeOpportunityId: string): Promise<string[]>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // HyDE Operations (own sources only)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get a HyDE document for the user's own source. */\n getHydeDocument(sourceType: HydeSourceType, sourceId: string, strategy: string): Promise<HydeDocument | null>;\n\n /** Get all HyDE documents for the user's own source. */\n getHydeDocumentsForSource(sourceType: HydeSourceType, sourceId: string): Promise<HydeDocument[]>;\n\n /** Save a HyDE document for the user's own source. */\n saveHydeDocument(data: CreateHydeDocumentData): Promise<HydeDocument>;\n\n /** Delete HyDE documents for the user's own source. */\n deleteHydeDocumentsForSource(sourceType: HydeSourceType, sourceId: string): Promise<number>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// SYSTEM DATABASE INTERFACE (Cross-User Within Shared Indexes)\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Context-bound database for LLM/system operations that access cross-user resources.\n * Created with authUserId + indexScope[]; validates membership before access.\n *\n * **Index-scoped**: All cross-user operations are restricted to users/resources\n * within the bound indexScope[]. This prevents the LLM from accessing arbitrary users' data.\n *\n * Use via `createSystemDatabase(db, authUserId, indexScope)` factory function.\n */\nexport interface SystemDatabase {\n /** The bound authenticated user ID */\n readonly authUserId: string;\n\n /** The indexes the authenticated user has access to (determines cross-user scope) */\n readonly indexScope: string[];\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Profile Operations (any user in scope)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get a user's profile (requires shared index membership). */\n getProfile(userId: string): Promise<ProfileDocument | null>;\n\n /** Get a user's basic record (requires shared index membership). */\n getUser(userId: string): Promise<UserRecord | null>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Intent Operations (cross-user within shared indexes)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get all intents in an index (cross-user, requires membership). */\n getIntentsInIndex(networkId: string, options?: { limit?: number; offset?: number }): Promise<IndexedIntentDetails[]>;\n\n /** Get a specific user's intents in an index (requires shared membership). */\n getUserIntentsInIndex(userId: string, networkId: string): Promise<ActiveIntent[]>;\n\n /**\n * Get the caller's own active intents across a set of indexes.\n * Returns intents owned by `userId` that are linked (via intent_networks)\n * to at least one of `indexIds`. Used by network-scoped agents to honor\n * indexScope without falling back to global getActiveIntents (which would\n * include intents in indexes outside scope).\n *\n * @param userId - The intent owner (always the caller).\n * @param indexIds - The set of index IDs to filter on. Empty → empty result.\n * @returns Active intents owned by userId in any of indexIds, deduped by intent id.\n */\n getActiveIntentsAcrossIndexes(userId: string, indexIds: string[]): Promise<ActiveIntent[]>;\n\n /** Get a single intent by ID (if in scope). */\n getIntent(intentId: string): Promise<IntentRecord | null>;\n\n /** Find similar intents across users within the index scope. */\n findSimilarIntentsInScope(embedding: number[], options?: SimilarIntentSearchOptions): Promise<SimilarIntent[]>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Index Membership Operations (any index in scope)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Check if a user is a member of an index. */\n isNetworkMember(networkId: string, userId: string): Promise<boolean>;\n\n /** Check if a user is an owner of an index. */\n isIndexOwner(networkId: string, userId: string): Promise<boolean>;\n\n /** Get all members of an index (requires membership). */\n getNetworkMembers(networkId: string): Promise<IndexMemberDetails[]>;\n\n /** Get all members across all indexes in scope (deduplicated). */\n getMembersFromScope(): Promise<{ userId: Id<'users'>; name: string; avatar: string | null }[]>;\n\n /** Add a user to an index (requires ownership or 'anyone' policy). */\n addMemberToNetwork(networkId: string, userId: string, role: 'owner' | 'member'): Promise<{ success: boolean; alreadyMember?: boolean }>;\n\n /** Remove a user from an index (requires ownership). Cannot remove the owner. */\n removeMemberFromIndex(networkId: string, userId: string): Promise<{ success: boolean; wasOwner?: boolean; notMember?: boolean }>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Index Operations (any index in scope)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get index info by ID with core fields (requires scope). */\n getNetwork(networkId: string): Promise<{\n id: string;\n title: string;\n prompt?: string | null;\n type?: string;\n metadata?: Record<string, unknown> | null;\n permissions?: Record<string, unknown> | null;\n } | null>;\n\n /** Get index with permissions (requires scope). */\n getNetworkWithPermissions(networkId: string): Promise<{ id: string; title: string; permissions: { joinPolicy: 'anyone' | 'invite_only' } } | null>;\n\n /** Get member count for an index (requires scope). */\n getNetworkMemberCount(networkId: string): Promise<number>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Opportunity Operations (cross-user within scope)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Create an opportunity (cross-user). */\n createOpportunity(data: CreateOpportunityData): Promise<Opportunity>;\n\n /** Create opportunity and expire overlapping ones atomically. */\n createOpportunityAndExpireIds(data: CreateOpportunityData, expireIds: string[]): Promise<{ created: Opportunity; expired: Opportunity[] }>;\n\n /** Get an opportunity by ID (for system processing). */\n getOpportunity(id: string): Promise<Opportunity | null>;\n\n /** Get opportunities for an index (requires membership). */\n getOpportunitiesForNetwork(networkId: string, options?: OpportunityQueryOptions): Promise<Opportunity[]>;\n\n /** Update an opportunity's status (system-level). */\n updateOpportunityStatus(id: string, status: OpportunityStatus, acceptedBy?: string): Promise<Opportunity | null>;\n\n /** Stamp actor `actedAt` + update status atomically (system-level). */\n stampOpportunityActorAction(\n id: string,\n actorUserId: string,\n status: OpportunityStatus,\n acceptedBy?: string,\n ): Promise<Opportunity | null>;\n\n /** Check if opportunity exists between actors in an index. */\n opportunityExistsBetweenActors(actorIds: string[], networkId: string): Promise<boolean>;\n\n /** Find opportunities by actor IDs with optional include/exclude status filters. */\n findOpportunitiesByActors(\n actorIds: string[],\n options?: { includeIntroducers?: boolean; statuses?: OpportunityStatus[]; excludeStatuses?: OpportunityStatus[] }\n ): Promise<Opportunity[]>;\n\n /** Expire opportunities referencing an intent. */\n expireOpportunitiesByIntent(intentId: string): Promise<number>;\n\n /** Expire opportunities for a removed member. */\n expireOpportunitiesForRemovedMember(networkId: string, userId: string): Promise<number>;\n\n /** Expire stale opportunities (maintenance). */\n expireStaleOpportunities(): Promise<number>;\n\n // ─────────────────────────────────────────────────────────────────────────────\n // HyDE Operations (cross-user for opportunity matching)\n // ─────────────────────────────────────────────────────────────────────────────\n\n /** Get a HyDE document (cross-user for matching). */\n getHydeDocument(sourceType: HydeSourceType, sourceId: string, strategy: string): Promise<HydeDocument | null>;\n\n /** Get all HyDE documents for a source (cross-user). */\n getHydeDocumentsForSource(sourceType: HydeSourceType, sourceId: string): Promise<HydeDocument[]>;\n\n /** Save a HyDE document (system-level). */\n saveHydeDocument(data: CreateHydeDocumentData): Promise<HydeDocument>;\n\n /** Delete expired HyDE documents (maintenance). */\n deleteExpiredHydeDocuments(): Promise<number>;\n\n /** Get stale HyDE documents for refresh (maintenance). */\n getStaleHydeDocuments(threshold: Date): Promise<HydeDocument[]>;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// NARROWED DATABASE INTERFACES (Interface Segregation)\n// ═══════════════════════════════════════════════════════════════════════════════\n//\n// These narrowed types are Pick types from the raw Database interface.\n// They are used by graph factories to enforce interface segregation at compile time.\n//\n// Access control relationship to UserDatabase/SystemDatabase:\n// - ProfileGraphDatabase → maps to UserDatabase (user's own profile operations)\n// - IntentGraphDatabase → maps to UserDatabase (mutations) + SystemDatabase (reads)\n// - OpportunityGraphDatabase → maps to SystemDatabase (cross-user operations)\n// - NetworkGraphDatabase → maps to UserDatabase (own indexes)\n// - IntentNetworkGraphDatabase → maps to both (own intent ↔ shared index)\n// - NetworkMembershipGraphDatabase → maps to SystemDatabase (cross-user)\n// - HydeGraphDatabase → maps to both (own HyDE vs cross-user matching)\n//\n// Graphs continue to use these narrowed types because:\n// 1. They receive the raw database adapter with userId passed per method\n// 2. Access control is enforced at the tool/factory layer via createUserDatabase/createSystemDatabase\n// 3. These types ensure graphs only depend on methods they actually use\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/**\n * Database interface narrowed for Profile Graph operations.\n * Provides full profile lifecycle: read, write, and query mode.\n *\n * Access layer: Primarily UserDatabase (user's own profile)\n */\nexport type ProfileGraphDatabase = Pick<\n Database,\n 'getProfile' | 'getUser' | 'updateUser' | 'saveProfile' | 'getProfileByUserId' | 'softDeleteGhost' | 'findDuplicateUser' | 'mergeGhostUser' | 'getUserSocials' | 'setUserSocials' | 'getPremisesForUser'\n>;\n\n/**\n * Database interface narrowed for Premise Graph operations.\n * Provides premise lifecycle: create, read, update, and network assignment.\n *\n * Access layer: UserDatabase (user's own premises)\n */\nexport type PremiseGraphDatabase = Pick<\n Database,\n 'createPremise' | 'getPremise' | 'getPremisesForUser' | 'updatePremise' | 'assignPremiseToNetwork' | 'getPremiseNetworks' | 'getUserIndexIds' | 'getNetwork' | 'getNetworkMemberContext'\n>;\n\n/**\n * Composite database interface for Chat Graph.\n * Includes direct ChatGraph operations plus all methods needed by\n * internally composed subgraphs (ProfileGraph, OpportunityGraph, IntentGraph, NetworkGraph).\n *\n * Use this type when ChatGraph orchestrates subgraphs internally.\n *\n * Access layer: Both UserDatabase + SystemDatabase (orchestrates all operations)\n */\nexport type ChatGraphCompositeDatabase = Pick<\n Database,\n // Direct ChatGraph operations\n | 'getProfile'\n | 'getActiveIntents'\n | 'getActiveIntentsAcrossIndexes'\n | 'getIntentsInIndexForMember'\n // ProfileGraph subgraph requirements\n | 'getUser'\n | 'updateUser'\n | 'getUserSocials'\n | 'setUserSocials'\n | 'saveProfile'\n | 'softDeleteGhost'\n // IntentGraph subgraph requirements (getActiveIntents already included)\n | 'createIntent'\n | 'updateIntent'\n | 'archiveIntent'\n // OpportunityGraph subgraph requirements (getProfile already included)\n | 'createOpportunity'\n | 'getOpportunity'\n | 'getOpportunitiesByIds'\n | 'opportunityExistsBetweenActors'\n | 'findOpportunitiesByActors'\n | 'getOpportunitiesForUser'\n | 'updateOpportunityStatus'\n | 'updateOpportunityActorApproval'\n | 'stampOpportunityActorAction'\n | 'getOrCreateDM'\n // HyDE graph (used by OpportunityGraph)\n | 'getHydeDocument'\n | 'getHydeDocumentsForSource'\n | 'saveHydeDocument'\n | 'getIntent'\n // NetworkGraph subgraph requirements (index created intents in user's indexes)\n | 'getPublicIndexesNotJoined'\n | 'getUserIndexIds'\n | 'getNetworkMemberships'\n | 'getNetworkMembership'\n | 'getNetwork'\n | 'getNetworkWithPermissions'\n | 'getIntentForIndexing'\n | 'getNetworkMemberContext'\n | 'isIntentAssignedToIndex'\n | 'assignIntentToNetwork'\n | 'unassignIntentFromIndex'\n | 'getNetworkIdsForIntent'\n | 'getIntentIndexScores'\n // Personal index auto-assignment (used by intent graph executor)\n | 'getPersonalIndexesForContact'\n // Index Ownership Operations (owner-only)\n | 'getOwnedIndexes'\n | 'isIndexOwner'\n | 'isNetworkMember'\n | 'getNetworkMembersForOwner'\n | 'getNetworkMembersForMember'\n | 'getMembersFromUserIndexes'\n | 'getNetworkIntentsForOwner'\n | 'getNetworkIntentsForMember'\n | 'updateIndexSettings'\n | 'softDeleteNetwork'\n | 'deleteProfile'\n | 'getProfileByUserId'\n | 'createNetwork'\n | 'getNetworkMemberCount'\n | 'addMemberToNetwork'\n | 'removeMemberFromIndex'\n // ProfileGraph post-enrichment ghost deduplication\n | 'findDuplicateUser'\n | 'mergeGhostUser'\n // ProfileGraph aggregate mode (premise-to-profile materialization)\n | 'getPremisesForUser'\n // Premise-to-premise discovery (path D) in OpportunityGraph\n | 'searchPremisesBySimilarity'\n // User context methods (context-to-intent discovery) in OpportunityGraph\n | 'getUserContext'\n | 'getUserContexts'\n | 'searchIntentsByContextEmbedding'\n> & Pick<\n NegotiationQueries,\n // Orphan heal in OpportunityGraph persist node\n | 'getNegotiationTaskForOpportunity'\n>;\n\n/**\n * Database interface for Opportunity Graph operations.\n * Includes prep/scope (index membership, intents, index details), persist (create, dedupe),\n * and CRUD operations (read, update status, send).\n *\n * Access layer: SystemDatabase (cross-user opportunity operations)\n */\nexport type OpportunityGraphDatabase = Pick<\n Database,\n | 'getProfile'\n | 'createOpportunity'\n | 'opportunityExistsBetweenActors'\n | 'findOpportunitiesByActors'\n | 'getUserIndexIds'\n | 'getNetworkMemberships'\n | 'getActiveIntents'\n | 'getNetworkIdsForIntent'\n | 'getNetwork'\n | 'getNetworkMemberCount'\n | 'getIntentIndexScores'\n | 'getNetworkMemberContext'\n // Read/update/send modes\n | 'getOpportunity'\n | 'getOpportunitiesForUser'\n | 'updateOpportunityStatus'\n | 'stampOpportunityActorAction'\n | 'updateOpportunityActorApproval'\n | 'isNetworkMember'\n | 'isIndexOwner'\n | 'getUser'\n | 'getOrCreateDM'\n // Load candidate intent payload/summary for evaluator\n | 'getIntent'\n // Premise-to-premise discovery (path D)\n | 'getPremisesForUser'\n | 'searchPremisesBySimilarity'\n // User context methods (context-to-intent discovery)\n | 'getUserContext'\n | 'getUserContexts'\n | 'searchIntentsByContextEmbedding'\n // HyDE documents for context-to-intent HyDE search\n | 'getHydeDocumentsForSource'\n> & Pick<\n NegotiationQueries,\n // Orphan heal: check if a prior negotiating opportunity has a stale task\n | 'getNegotiationTaskForOpportunity'\n>;\n\n/**\n * Negotiation-specific query operations not covered by generic\n * conversation/task primitives.\n */\n/** A user's answer to a questioner-generated question, stored on opportunity metadata. */\nexport interface NegotiationUserAnswer {\n questionId: string;\n selectedOptions: string[];\n freeText?: string;\n answeredAt: string;\n}\n\nexport interface NegotiationQueries {\n /**\n * Persists the full negotiation turn context (source/candidate user contexts,\n * seed assessment, index context, discovery query) onto the task metadata so\n * that polling agents can reconstruct the same context the system agent sees\n * in-process. Merges into `metadata.turnContext`, leaving other keys intact.\n * @param taskId - Task whose metadata to enrich\n * @param turnContext - Absolute (source/candidate) view of the negotiation context\n */\n setTaskTurnContext(taskId: string, turnContext: Record<string, unknown>): Promise<void>;\n\n /**\n * Returns the most-recently-created task whose metadata carries\n * `type: 'negotiation'` and `opportunityId: <id>`. Returns null if no\n * negotiation has been started for that opportunity yet.\n */\n getNegotiationTaskForOpportunity(opportunityId: string): Promise<{\n id: string;\n conversationId: string;\n state: string;\n metadata: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n } | null>;\n\n /**\n * Returns user answers collected by the questioner system for a given\n * opportunity. Reads `metadata.userAnswers` from the opportunities table.\n * Used by the negotiation graph to inject between-session context into\n * continuation prompts.\n */\n getOpportunityUserAnswers(opportunityId: string): Promise<NegotiationUserAnswer[]>;\n}\n\n/**\n * Database dependency for the negotiation graph (A2A conversation/task/artifact\n * persistence). Composes generic conversation ops with negotiation-specific queries.\n *\n * Access layer: ConversationDatabaseAdapter\n */\nexport type NegotiationGraphDatabase = Pick<\n Database,\n | 'getOrCreateDM'\n> & NegotiationQueries & {\n /**\n * Update the status of an opportunity. Called from the negotiation graph to\n * advance the opportunity lifecycle (negotiating -> pending/rejected/stalled).\n * Returns only the narrow { id, status } needed by the graph, not the full Opportunity.\n */\n updateOpportunityStatus(\n id: string,\n status: OpportunityStatus,\n ): Promise<{ id: string; status: OpportunityStatus } | null>;\n /** Persists a negotiation turn message within a conversation. */\n createMessage(data: {\n conversationId: string;\n senderId: string;\n role: 'user' | 'agent';\n parts: unknown[];\n taskId?: string;\n metadata?: Record<string, unknown> | null;\n }): Promise<{ id: string; senderId: string; role: 'user' | 'agent'; parts: unknown; createdAt: Date }>;\n\n /** Creates a task to track the negotiation lifecycle within a conversation. */\n createTask(conversationId: string, metadata?: Record<string, unknown>): Promise<{ id: string; conversationId: string; state: string }>;\n\n /** Transitions a task to a new state (e.g. working, completed, failed). */\n updateTaskState(taskId: string, state: string, statusMessage?: unknown): Promise<{ id: string; conversationId: string; state: string }>;\n\n /** Persists a negotiation outcome artifact attached to a task. */\n createArtifact(data: { taskId: string; name?: string; parts: unknown[]; metadata?: Record<string, unknown> | null }): Promise<{ id: string }>;\n\n /** Lists negotiation tasks where the given user is source or candidate. */\n getTasksForUser(userId: string, options?: { state?: string }): Promise<Array<{\n id: string;\n conversationId: string;\n state: string;\n metadata: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n }>>;\n\n /** Gets a specific task by ID. */\n getTask(taskId: string): Promise<{\n id: string;\n conversationId: string;\n state: string;\n metadata: Record<string, unknown> | null;\n createdAt: Date;\n updatedAt: Date;\n } | null>;\n\n /** Gets all messages for a conversation, ordered by creation time. */\n getMessagesForConversation(conversationId: string): Promise<Array<{\n id: string;\n senderId: string;\n role: 'user' | 'agent';\n parts: unknown[];\n createdAt: Date;\n }>>;\n\n /** Gets artifacts for a task (e.g. negotiation outcome). */\n getArtifactsForTask(taskId: string): Promise<Array<{\n id: string;\n name: string | null;\n parts: unknown[];\n metadata: Record<string, unknown> | null;\n }>>;\n};\n\n/**\n * Database interface for opportunity controller (API).\n *\n * Access layer: Both UserDatabase + SystemDatabase (API handles auth)\n */\nexport type OpportunityControllerDatabase = Pick<\n Database,\n | 'getOpportunity'\n | 'getOpportunitiesByIds'\n | 'getOpportunitiesForUser'\n | 'getOpportunitiesForNetwork'\n | 'resolveOpportunityId'\n | 'updateOpportunityStatus'\n | 'createOpportunity'\n | 'createOpportunityAndExpireIds'\n | 'opportunityExistsBetweenActors'\n | 'findOpportunitiesByActors'\n | 'acceptSiblingOpportunities'\n | 'isIndexOwner'\n | 'isNetworkMember'\n | 'getUser'\n | 'getNetwork'\n | 'getNetworkMemberships'\n | 'getProfile'\n | 'getActiveIntents'\n | 'upsertContactMembership'\n // Start Chat endpoint (Plan B Task 8): atomic pair → conversation resolution\n // for the \"Open h2h chat from this opportunity\" flow. Kept on this interface\n // (rather than ConversationControllerDatabase) because the transition is\n // owned by OpportunityService — services cannot import other services.\n | 'getOrCreateDM'\n | 'unhideConversation'\n // Approve-introduction endpoint: flip introducer actor's approved flag.\n | 'updateOpportunityActorApproval'\n // Self-accept guard + actedAt stamping on service-layer status flips.\n | 'stampOpportunityActorAction'\n>;\n\n/**\n * Database interface narrowed for Intent Graph operations.\n * Provides state population (getActiveIntents), action execution (create/update/archive),\n * and read operations (query intents; getIntentsInIndexForMember for index-scoped reads).\n *\n * Access layer: UserDatabase (mutations on own intents) + SystemDatabase (index-scoped reads)\n */\nexport type IntentGraphDatabase = Pick<\n Database,\n | 'getActiveIntents'\n | 'getActiveIntentsAcrossIndexes'\n | 'getIntentsInIndexForMember'\n | 'createIntent'\n | 'updateIntent'\n | 'archiveIntent'\n // Read mode (queryNode) requirements\n | 'isNetworkMember'\n | 'getNetworkIntentsForMember'\n | 'getUser'\n // Profile check (prepNode gate for write operations)\n | 'getProfile'\n // Personal index auto-assignment\n | 'getPersonalIndexesForContact'\n | 'assignIntentToNetwork'\n>;\n\n/**\n * Database interface narrowed for Index Graph CRUD operations.\n * Handles create, read, update, delete of indexes (communities).\n *\n * Access layer: UserDatabase (CRUD on own indexes and memberships)\n */\nexport type NetworkGraphDatabase = Pick<\n Database,\n | 'getNetworkMemberships'\n | 'getOwnedIndexes'\n | 'getPublicIndexesNotJoined'\n | 'isIndexOwner'\n | 'isNetworkMember'\n | 'getNetwork'\n | 'createNetwork'\n | 'addMemberToNetwork'\n | 'updateIndexSettings'\n | 'softDeleteNetwork'\n | 'getNetworkMemberCount'\n>;\n\n/**\n * Database interface narrowed for Intent Index Graph operations.\n * Provides intent/index context and assignment for intent–index evaluation.\n * (Migrated from the old NetworkGraphDatabase.)\n *\n * Access layer: UserDatabase (own intent assignment) + SystemDatabase (index context)\n */\nexport type IntentNetworkGraphDatabase = Pick<\n Database,\n | 'getIntentForIndexing'\n | 'getNetworkMemberContext'\n | 'getNetwork'\n | 'isIntentAssignedToIndex'\n | 'assignIntentToNetwork'\n | 'unassignIntentFromIndex'\n | 'getIntent'\n | 'isNetworkMember'\n | 'isIndexOwner'\n | 'getNetworkIdsForIntent'\n | 'getNetworkIntentsForMember'\n | 'getIntentsInIndexForMember'\n>;\n\n/**\n * Database interface narrowed for Index Membership Graph operations.\n * Handles CRUD for index memberships (add, list, remove members).\n *\n * Access layer: SystemDatabase (cross-user membership operations)\n */\nexport type NetworkMembershipGraphDatabase = Pick<\n Database,\n | 'isNetworkMember'\n | 'isIndexOwner'\n | 'getNetworkWithPermissions'\n | 'addMemberToNetwork'\n | 'removeMemberFromIndex'\n | 'getNetworkMembersForMember'\n>;\n\n/**\n * Database interface narrowed for HyDE Graph operations.\n * Provides HyDE document CRUD and intent lookup for refresh.\n *\n * Access layer: UserDatabase (own HyDE) + SystemDatabase (cross-user matching)\n */\nexport type HydeGraphDatabase = Pick<\n Database,\n 'getHydeDocument' | 'getHydeDocumentsForSource' | 'saveHydeDocument' | 'getIntent'\n>;\n\n/**\n * Database interface for Home Graph (opportunity home view).\n * Load opportunities, enrich with profile/index, and support presenter context.\n *\n * Access layer: UserDatabase (own opportunities and profile)\n */\nexport type HomeGraphDatabase = Pick<\n Database,\n | 'getOpportunitiesForUser'\n | 'getOpportunity'\n | 'getProfile'\n | 'getActiveIntents'\n | 'getNetwork'\n | 'getUser'\n> & Pick<\n NegotiationGraphDatabase,\n | 'getNegotiationTaskForOpportunity'\n | 'getMessagesForConversation'\n | 'getArtifactsForTask'\n>;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery-ledger.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"delivery-ledger.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/delivery-ledger.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;OAQG;IACH,0BAA0B,CAAC,MAAM,EAAE;QACjC,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,OAAO,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;KAC5C,GAAG,OAAO,CAAC,WAAW,GAAG,mBAAmB,CAAC,CAAC;CAChD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delivery-ledger.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"delivery-ledger.interface.js","sourceRoot":"/","sources":["shared/interfaces/delivery-ledger.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * Delivery ledger interface for committing opportunity delivery rows.\n * Implementations live in src/adapters (e.g. database adapter).\n */\n\nexport interface DeliveryLedger {\n /**\n * Write a committed delivery row for an opportunity.\n * Returns 'confirmed' on first delivery, 'already_delivered' if previously committed.\n *\n * @param trigger - Which dispatch path produced this delivery: 'ambient' for\n * real-time critical alerts (≤3/day target), 'digest' for the\n * daily sweep of everything ambient passed on, 'accepted' for\n * accepted-opportunity notifications to the counterparty.\n */\n confirmOpportunityDelivery(params: {\n opportunityId: string;\n userId: string;\n agentId: string | null;\n trigger: 'ambient' | 'digest' | 'accepted';\n }): Promise<'confirmed' | 'already_delivered'>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery-run.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"discovery-run.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/discovery-run.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery-run.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"discovery-run.interface.js","sourceRoot":"/","sources":["shared/interfaces/discovery-run.interface.ts"],"names":[],"mappings":"","sourcesContent":["import type { ResolvedToolContext } from \"../agent/tool.helpers.js\";\n\nexport type DiscoveryRunStatus = \"queued\" | \"running\" | \"succeeded\" | \"failed\" | \"cancelled\";\n\nexport interface DiscoveryRunInput {\n continueFrom?: string;\n searchQuery?: string;\n networkId?: string;\n intentId?: string;\n targetUserId?: string;\n introTargetUserId?: string;\n partyUserIds?: string[];\n entities?: Array<{\n userId: string;\n profile?: {\n name?: string;\n bio?: string;\n location?: string;\n interests?: string[];\n skills?: string[];\n context?: string;\n };\n intents?: Array<{\n intentId: string;\n payload: string;\n summary?: string;\n }>;\n networkId: string;\n }>;\n hint?: string;\n}\n\nexport interface DiscoveryRunRecord {\n id: string;\n userId: string;\n agentId?: string | null;\n status: DiscoveryRunStatus;\n input: DiscoveryRunInput;\n context: Pick<ResolvedToolContext,\n \"userId\" |\n \"userName\" |\n \"userEmail\" |\n \"networkId\" |\n \"indexName\" |\n \"indexScope\" |\n \"sessionId\" |\n \"agentId\" |\n \"clientSurface\"\n >;\n progress?: Record<string, unknown> | null;\n result?: unknown;\n error?: string | null;\n cancelRequestedAt?: Date | null;\n createdAt: Date;\n startedAt?: Date | null;\n completedAt?: Date | null;\n expiresAt?: Date | null;\n}\n\nexport interface CreateDiscoveryRunInput {\n userId: string;\n agentId?: string | null;\n input: DiscoveryRunInput;\n context: DiscoveryRunRecord[\"context\"];\n expiresAt?: Date;\n}\n\nexport interface DiscoveryRunStore {\n create(input: CreateDiscoveryRunInput): Promise<DiscoveryRunRecord>;\n get(runId: string, userId: string): Promise<DiscoveryRunRecord | null>;\n markRunning(runId: string): Promise<DiscoveryRunRecord | null>;\n updateProgress(runId: string, progress: Record<string, unknown>): Promise<void>;\n markSucceeded(runId: string, result: unknown): Promise<void>;\n markFailed(runId: string, error: string): Promise<void>;\n requestCancel(runId: string, userId: string): Promise<DiscoveryRunRecord | null>;\n markCancelled(runId: string, reason?: string): Promise<void>;\n isCancelRequested(runId: string): Promise<boolean>;\n listActive(userId: string, limit?: number): Promise<DiscoveryRunRecord[]>;\n}\n\nexport interface DiscoveryRunQueue {\n enqueue(runId: string): Promise<{ jobId?: string | number } | void>;\n cancel(runId: string): Promise<boolean>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedder.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"embedder.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/embedder.interface.ts"],"names":[],"mappings":"AAIA,YAAY,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEvE,gDAAgD;AAChD,MAAM,WAAW,aAAa;IAC5B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;IAC5C,iCAAiC;IACjC,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAMD,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;CAC5H;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE7B,UAAU,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;KAAE,CAAC,EAAE,CAAC;IAErD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,EACN,WAAW,EAAE,MAAM,EAAE,EACrB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,QAAS,SAAQ,kBAAkB,EAAE,WAAW;IAC/D;;;;;;;OAOG;IACH,wBAAwB,CACtB,cAAc,EAAE,aAAa,EAAE,EAC/B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;CAE7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedder.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"embedder.interface.js","sourceRoot":"/","sources":["shared/interfaces/embedder.interface.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,uDAAuD;AACvD,kFAAkF","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════════\n// HyDE (Hypothetical Document Embeddings) search types\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport type { Lens, HydeTargetCorpus } from '../hyde/lens.inferrer.js';\n\n/** A single lens embedding ready for search. */\nexport interface LensEmbedding {\n /** Free-text lens label (e.g. \"crypto infrastructure VC\"). */\n lens: string;\n /** Which corpus to search. */\n corpus: 'profiles' | 'intents' | 'premises';\n /** 2000-dim embedding vector. */\n embedding: number[];\n}\n\n/** Options for searchWithHydeEmbeddings (index scope, limits, min score). */\nexport interface HydeSearchOptions {\n /** Index IDs to scope the search (members / assigned intents only). */\n indexScope: string[];\n /** Exclude this user ID from results (e.g. source intent owner). */\n excludeUserId?: string;\n /** Max results per lens before merge (default 10). */\n limitPerStrategy?: number;\n /** Max results after merge/rank (default 20). */\n limit?: number;\n /** Minimum cosine similarity for intent searches (default 0.40). */\n minScore?: number;\n}\n\n/** A single candidate from HyDE search (intent or premise), with score and which lens matched. */\nexport interface HydeCandidate {\n type: 'intent' | 'premise';\n id: string;\n userId: string;\n score: number;\n /** Free-text lens label that produced this match. */\n matchedVia: string;\n networkId: string;\n /** Set after merge when user matched via multiple lenses. */\n matchedLenses?: string[];\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// Embedding and vector store\n// ═══════════════════════════════════════════════════════════════════════════════\n\nexport interface EmbeddingGenerateOptions {\n signal?: AbortSignal;\n}\n\nexport interface EmbeddingGenerator {\n generate(text: string | string[], dimensions?: number, options?: EmbeddingGenerateOptions): Promise<number[] | number[][]>;\n}\n\nexport interface VectorSearchResult<T> {\n item: T;\n score: number; // similarity (0-1)\n}\n\nexport type VectorStoreOption<T> = {\n limit?: number;\n // Generic filter object passed to the store implementation\n filter?: Record<string, any>;\n // For stateless store: explicitly provide the candidates to search against\n candidates?: (T & { embedding?: number[] | null })[];\n // Minimum similarity score to include in results\n minScore?: number;\n};\n\nexport interface VectorStore {\n /**\n * Search for similar items in the vector store.\n *\n * @param queryVector - The embedding vector to search for\n * @param collection - The logical name of the collection (e.g., 'profiles', 'intents')\n * @param options - generic options including limit, filter, and candidates\n */\n search<T>(\n queryVector: number[],\n collection: string,\n options?: VectorStoreOption<T>\n ): Promise<VectorSearchResult<T>[]>;\n}\n\n/**\n * Embedder: generate embeddings and run vector / HyDE search.\n * Implementations: OpenAI/OpenRouter for generate, pgvector for search.\n */\nexport interface Embedder extends EmbeddingGenerator, VectorStore {\n /**\n * Multi-lens HyDE search: run one vector search per lens embedding,\n * then merge, deduplicate by userId, and rank (boost for multiple lens matches).\n *\n * @param lensEmbeddings - Array of lens embeddings to search with\n * @param options - indexScope, excludeUserId, limits, minScore\n * @returns Deduplicated, ranked candidates (intent or premise) with scores\n */\n searchWithHydeEmbeddings(\n lensEmbeddings: LensEmbedding[],\n options: HydeSearchOptions\n ): Promise<HydeCandidate[]>;\n\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrichment.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"enrichment.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/enrichment.interface.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,4CAA4C;AAC5C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,SAAS,EAAE;QACT,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,EAAE,CAAC;QACjB,SAAS,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,OAAO,EAAE;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACjF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enrichment.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"enrichment.interface.js","sourceRoot":"/","sources":["shared/interfaces/enrichment.interface.ts"],"names":[],"mappings":"","sourcesContent":["/** Request to enrich a user profile from external data sources. */\nexport interface EnrichmentRequest {\n name?: string;\n email?: string;\n linkedin?: string;\n twitter?: string;\n github?: string;\n telegram?: string;\n websites?: string[];\n}\n\n/** Structured profile enrichment result. */\nexport interface EnrichmentResult {\n identity: {\n name: string;\n bio: string;\n location: string;\n };\n narrative: {\n context: string;\n };\n attributes: {\n skills: string[];\n interests: string[];\n };\n socials: {\n linkedin?: string;\n twitter?: string;\n github?: string;\n telegram?: string;\n websites?: string[];\n };\n confidentMatch: boolean;\n isHuman: boolean;\n}\n\n/**\n * Profile enrichment adapter for resolving user identity from external sources.\n * Consumers provide a concrete implementation (e.g. backed by Parallel Chat API).\n */\nexport interface ProfileEnricher {\n enrichUserProfile(request: EnrichmentRequest): Promise<EnrichmentResult | null>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"integration.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/integration.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5B,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IACpH,QAAQ,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,UAAU,CAAC,EAAE;gBAAE,gBAAgB,CAAC,EAAE;oBAAE,EAAE,EAAE,MAAM,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAC3H;AAED,mDAAmD;AACnD,MAAM,WAAW,yBAAyB;IACxC,iBAAiB,CAAC,EAAE,OAAO,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEhG;;;;;;OAMG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE5G;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAElE;;;;;;OAMG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEpG;;;OAGG;IACH,UAAU,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CACvE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"integration.interface.js","sourceRoot":"/","sources":["shared/interfaces/integration.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Session for interacting with an external integration platform.\n * Provides access to tools, OAuth authorization, and toolkit discovery.\n */\nexport interface IntegrationSession {\n tools(): Promise<unknown[]>;\n authorize(toolkit: string): Promise<{ redirectUrl: string; waitForConnection(timeout?: number): Promise<unknown> }>;\n toolkits(): Promise<{ items: Array<{ slug: string; name: string; connection?: { connectedAccount?: { id: string } } }> }>;\n}\n\n/** Options for creating an integration session. */\nexport interface IntegrationSessionOptions {\n manageConnections?: boolean | { callbackUrl?: string };\n /** Toolkit slug → auth config ID mapping to pin existing auth configs. */\n authConfigs?: Record<string, string>;\n}\n\n/** Response from executing a tool action on the integration platform. */\nexport interface ToolActionResponse {\n successful: boolean;\n error?: string;\n data?: Record<string, unknown>;\n}\n\n/** A connected integration account for a user. */\nexport interface IntegrationConnection {\n id: string;\n toolkit: string;\n status: string;\n createdAt: string;\n}\n\n/**\n * Adapter for external integration platforms (OAuth sessions, tool execution).\n *\n * @remarks\n * Implementations wrap a specific platform SDK (e.g. Composio) and expose\n * a platform-agnostic API for creating user sessions and executing tool actions.\n */\nexport interface IntegrationAdapter {\n /**\n * Create an authenticated session for a user.\n * @param userId - User ID for the session\n * @param options - Session configuration (e.g. connection management)\n * @returns A session object for interacting with the platform\n */\n createSession(userId: string, options?: IntegrationSessionOptions): Promise<IntegrationSession>;\n\n /**\n * Execute a named tool action on behalf of a user.\n * @param slug - Tool action identifier (e.g. 'GMAIL_GET_CONTACTS')\n * @param userId - User to execute the action for\n * @param args - Arguments to pass to the tool action\n * @returns The tool execution response\n */\n executeToolAction(slug: string, userId: string, args: Record<string, unknown>): Promise<ToolActionResponse>;\n\n /**\n * List all connected accounts for a user.\n * @param userId - User to list connections for\n * @returns Array of connected integration accounts\n */\n listConnections(userId: string): Promise<IntegrationConnection[]>;\n\n /**\n * Get an OAuth authorization URL to connect a toolkit.\n * @param userId - User to authorize\n * @param toolkit - Toolkit slug (e.g. 'gmail')\n * @param callbackUrl - URL to redirect to after OAuth\n * @returns The redirect URL for OAuth\n */\n getAuthUrl(userId: string, toolkit: string, callbackUrl?: string): Promise<{ redirectUrl: string }>;\n\n /**\n * Disconnect (delete) a connected account.\n * @param connectedAccountId - The connected account ID to remove\n */\n disconnect(connectedAccountId: string): Promise<{ success: boolean }>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation-events.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"negotiation-events.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/negotiation-events.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;;;OAMG;IACH,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5F;;;OAGG;IACH,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation-events.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"negotiation-events.interface.js","sourceRoot":"/","sources":["shared/interfaces/negotiation-events.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG","sourcesContent":["/**\n * Interfaces for negotiation yield/resume support.\n * Used by the negotiation graph and dispatcher to manage timeouts\n * for external agents that haven't responded yet.\n */\n\n/**\n * Manages delayed timeout jobs for negotiations waiting on external agents.\n * When a negotiation yields, a timeout is enqueued. If the external agent\n * responds before the timeout, the job is cancelled.\n */\nexport interface NegotiationTimeoutQueue {\n /**\n * Enqueue a delayed timeout job.\n * @param negotiationId - The negotiation task ID\n * @param turnNumber - Current turn number (used to detect stale jobs)\n * @param delayMs - Delay in milliseconds before the timeout fires\n * @returns The BullMQ job ID for cancellation\n */\n enqueueTimeout(negotiationId: string, turnNumber: number, delayMs: number): Promise<string>;\n\n /**\n * Cancel a pending timeout job for a negotiation.\n * @param negotiationId - The negotiation task ID\n */\n cancelTimeout(negotiationId: string): Promise<void>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation-summary.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"negotiation-summary.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/negotiation-summary.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAC;AAE1F,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;OASG;IACH,SAAS,CACP,WAAW,EAAE,oBAAoB,EACjC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAAC;CAC/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"negotiation-summary.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"negotiation-summary.interface.js","sourceRoot":"/","sources":["shared/interfaces/negotiation-summary.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Protocol-side contract for summarizing discovery negotiations into compact\n * digests. The protocol layer only sees this shape; the LLM implementation\n * (NegotiationSummarizer) is injected through dependency wiring.\n *\n * Pattern mirrors ChatSummaryReader: protocol defines the read shape, the\n * backend (or any consumer) provides the implementation.\n */\nimport type { DiscoveryNegotiation } from \"../../opportunity/question.prompt.js\";\nimport type { DiscoveryNegotiationDigest } from \"../schemas/negotiation-digest.schema.js\";\n\nexport interface NegotiationSummaryReader {\n /**\n * Summarize a single negotiation into a compact digest.\n *\n * @param negotiation The raw negotiation to compress.\n * @param options.signal Optional AbortSignal. When aborted (deadline reached or\n * upstream cancel) the in-flight LLM call is cancelled and `null` is returned —\n * callers fall back to a deterministic digest so question generation can\n * still proceed.\n * @returns the digest, or `null` when summarization fails or is aborted.\n */\n summarize(\n negotiation: DiscoveryNegotiation,\n options?: { signal?: AbortSignal },\n ): Promise<DiscoveryNegotiationDigest | null>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"question-generator.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"question-generator.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/question-generator.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAE9E,MAAM,WAAW,uBAAuB;IACtC;;;;;;;;;;OAUG;IACH,QAAQ,CACN,KAAK,EAAE,sBAAsB,EAC7B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACjC,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC;CAC7C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"question-generator.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"question-generator.interface.js","sourceRoot":"/","sources":["shared/interfaces/question-generator.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * @deprecated Use QuestionerAgent instead. Will be removed in a future version.\n *\n * Protocol-level read contract for decision-question generation. Implementations\n * live in the backend (see `QuestionGeneratorService`) and are injected into the\n * protocol via `ProtocolDeps`/`ToolContext`. The protocol module never constructs\n * its own LLM-bound `QuestionGenerator` — callers inject one (or `undefined` to\n * opt out).\n */\nimport type { DiscoveryQuestionInput } from \"../../opportunity/question.prompt.js\";\nimport type { QuestionGenerationResult } from \"../schemas/question.schema.js\";\n\nexport interface QuestionGeneratorReader {\n /**\n * Run the question generator over a single discovery turn.\n *\n * @param input Discovery turn payload (query + negotiation digests + chat context).\n * @param options.signal Optional AbortSignal. When aborted (deadline reached or\n * upstream cancel) the in-flight LLM call is cancelled and `null` is returned —\n * discovery still emits its response, just without questions.\n * @returns The structured result, or `null` when generation failed,\n * guardrails dropped all candidates, the underlying LLM threw, or\n * the call was aborted.\n */\n generate(\n input: DiscoveryQuestionInput,\n options?: { signal?: AbortSignal },\n ): Promise<QuestionGenerationResult | null>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questioner.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"questioner.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/questioner.interface.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACf,MAAM,+BAA+B,CAAC;AAEvC,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,EAAE,QAAQ,CAAC;IAClB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,0FAA0F;AAC1F,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,iBAAiB,CAAC;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,OAAO,EAAE,QAAQ,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC;iDAC6C;IAC7C,OAAO,CAAC,SAAS,EAAE,mBAAmB,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7D,6EAA6E;IAC7E,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAErF;;0FAEsF;IACtF,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAErF;;0FAEsF;IACtF,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"questioner.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"questioner.interface.js","sourceRoot":"/","sources":["shared/interfaces/questioner.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Protocol-level persistence contract for structured questions generated by\n * the QuestionerAgent. Implementations live in the backend and are injected\n * into ProtocolDeps.\n */\nimport type {\n Question,\n QuestionMode,\n QuestionStrategy,\n QuestionDetection,\n QuestionActor,\n QuestionAnswer,\n} from \"../schemas/question.schema.js\";\n\n/** Shape accepted by `persist()` — everything needed to insert a question row. */\nexport interface PersistableQuestion {\n detection: QuestionDetection;\n actors: QuestionActor[];\n payload: Question;\n strategy: QuestionStrategy;\n /** Conversation ID — set when the question originates from a chat session. */\n conversationId?: string;\n}\n\n/** Shape returned by `findPending()` — a persisted question with its DB id and status. */\nexport interface PersistedQuestion {\n id: string;\n detection: QuestionDetection;\n actors: QuestionActor[];\n payload: Question;\n status: \"pending\" | \"answered\" | \"dismissed\";\n answer: QuestionAnswer | null;\n createdAt: string;\n}\n\n/** Optional filters for `findPending()`. */\nexport interface QuestionFilters {\n mode?: QuestionMode;\n sourceType?: string;\n sourceId?: string;\n}\n\nexport interface QuestionerDatabase {\n /** Persist a batch of generated questions (up to 3 per generation).\n * @returns The IDs of the inserted rows. */\n persist(questions: PersistableQuestion[]): Promise<string[]>;\n\n /** Find pending questions for a user, optionally filtered by mode/source. */\n findPending(userId: string, filters?: QuestionFilters): Promise<PersistedQuestion[]>;\n\n /** Record an answer for a question. Sets status to \"answered\".\n * Only succeeds if the user is an actor on a pending question.\n * @returns `true` if updated, `false` if not found, not pending, or unauthorized. */\n answer(questionId: string, userId: string, answer: QuestionAnswer): Promise<boolean>;\n\n /** Dismiss a question. Sets status to \"dismissed\".\n * Only succeeds if the user is an actor on a pending question.\n * @returns `true` if updated, `false` if not found, not pending, or unauthorized. */\n dismiss(questionId: string, userId: string): Promise<boolean>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"queue.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/queue.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1G,gBAAgB,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAChE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"queue.interface.js","sourceRoot":"/","sources":["shared/interfaces/queue.interface.ts"],"names":[],"mappings":"AAAA;;GAEG","sourcesContent":["/**\n * Queue types for protocol layer.\n */\n\n/**\n * Operations the Intent Graph needs to enqueue follow-up work (e.g. HyDE generation/deletion).\n * Implemented by the intent queue; protocol layer depends only on this interface.\n */\nexport interface IntentGraphQueue {\n addGenerateHydeJob(data: { intentId: string; userId: string; networkScopeId?: string }): Promise<unknown>;\n addDeleteHydeJob(data: { intentId: string }): Promise<unknown>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scraper.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"scraper.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/scraper.interface.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAErC;;;;;;OAMG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC5F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scraper.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"scraper.interface.js","sourceRoot":"/","sources":["shared/interfaces/scraper.interface.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Options for URL content extraction (e.g. to tailor output for intent vs profile).\n */\nexport interface ExtractUrlContentOptions {\n /**\n * Optional natural-language objective describing why we're scraping.\n * Examples: \"User wants to create an intent from this link (project/repo).\",\n * \"User wants to update their profile from this page.\", or omit for generic extraction.\n */\n objective?: string;\n /** Optional cancellation signal for caller/client disconnect or runtime deadline. */\n signal?: AbortSignal;\n}\n\n/**\n * Interface for scraping web content.\n */\nexport interface Scraper {\n /**\n * Scrapes the content from the given URL.\n * @param url The URL to scrape.\n * @returns The scraped text content.\n */\n scrape(url: string): Promise<string>;\n\n /**\n * Extracts content from a URL. When `options.objective` is provided, extraction\n * may be tailored for that use (e.g. intent-focused vs profile-focused content).\n * @param url The URL to extract content from.\n * @param options Optional. Pass `objective` to get content better suited for intent creation or profile update.\n * @returns The extracted content as a string, or null if extraction failed.\n */\n extractUrlContent(url: string, options?: ExtractUrlContentOptions): Promise<string | null>;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.interface.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"storage.interface.d.ts","sourceRoot":"/","sources":["shared/interfaces/storage.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,OAAO;IACtB;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhF;;;;;;;OAOG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEtG;;;;;;;OAOG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1G;;;;;OAKG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzE;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.interface.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"storage.interface.js","sourceRoot":"/","sources":["shared/interfaces/storage.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * Storage interface for protocol layer (file uploads, avatars).\n * Implementations live in src/adapters (e.g. S3).\n */\n\nexport interface Storage {\n /**\n * Upload a buffer to storage.\n * @param buffer - The file contents\n * @param key - The storage object key (path)\n * @param contentType - The MIME type\n * @returns The URL to access the file\n */\n uploadBuffer(buffer: Buffer, key: string, contentType: string): Promise<string>;\n\n /**\n * Upload an avatar image to storage.\n * @param buffer - The image buffer\n * @param userId - The user's ID\n * @param extension - File extension (e.g., \"png\", \"jpg\")\n * @param contentType - The MIME type\n * @returns The URL to access the avatar\n */\n uploadAvatar(buffer: Buffer, userId: string, extension: string, contentType: string): Promise<string>;\n\n /**\n * Upload an index (network) image to storage.\n * @param buffer - The image buffer\n * @param userId - The user's ID\n * @param extension - File extension (e.g., \"png\", \"jpg\")\n * @param contentType - The MIME type\n * @returns The URL to access the image\n */\n uploadIndexImage(buffer: Buffer, userId: string, extension: string, contentType: string): Promise<string>;\n\n /**\n * Upload a base64-encoded image to storage.\n * @param base64Image - The base64 string (can include data URI prefix)\n * @param folder - The folder path in the bucket (default: \"feedback\")\n * @returns The URL to access the image\n */\n uploadBase64Image(base64Image: string, folder?: string): Promise<string>;\n\n /**\n * Generate the URL for a given storage key.\n * @param key - The storage object key\n * @returns The URL to access the file\n */\n getUrl(key: string): string;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.renderer.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"metadata.renderer.d.ts","sourceRoot":"/","sources":["shared/network/metadata.renderer.ts"],"names":[],"mappings":"AAAA,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAmBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAQzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadata.renderer.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"metadata.renderer.js","sourceRoot":"/","sources":["shared/network/metadata.renderer.ts"],"names":[],"mappings":"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","sourcesContent":["interface NetworkForRendering {\n type: string;\n title: string;\n prompt?: string | null;\n metadata: Record<string, unknown>;\n}\n\ninterface EventMetadata {\n startDate?: string;\n endDate?: string;\n timezone?: string;\n location?: string;\n themes?: string[];\n events?: Array<{\n externalId: string;\n title: string;\n startTime: string;\n endTime: string;\n location?: string;\n description?: string;\n tags?: string[];\n }>;\n}\n\n/**\n * Render a network's metadata as structured markdown for LLM context.\n *\n * @param network - The network to render, with type, title, optional prompt, and metadata.\n * @returns Markdown string suitable for injection into an LLM prompt.\n */\nexport function renderNetworkContext(network: NetworkForRendering): string {\n switch (network.type) {\n case 'event':\n return renderEventNetwork(network);\n case 'community':\n default:\n return renderCommunityNetwork(network);\n }\n}\n\nfunction renderCommunityNetwork(network: NetworkForRendering): string {\n const lines: string[] = [`## ${network.title}`];\n if (network.prompt) {\n lines.push('', network.prompt);\n }\n return lines.join('\\n');\n}\n\nfunction renderEventNetwork(network: NetworkForRendering): string {\n const meta = network.metadata;\n const startDate = typeof meta.startDate === 'string' ? meta.startDate : undefined;\n const endDate = typeof meta.endDate === 'string' ? meta.endDate : undefined;\n const location = typeof meta.location === 'string' ? meta.location : undefined;\n const timezone = typeof meta.timezone === 'string' ? meta.timezone : undefined;\n const themes = Array.isArray(meta.themes) ? meta.themes.filter((t: unknown): t is string => typeof t === 'string') : [];\n const events = Array.isArray(meta.events) ? normalizeEvents(meta.events) : [];\n const lines: string[] = [`## ${network.title}`];\n\n if (network.prompt) {\n lines.push('', network.prompt);\n }\n\n lines.push('');\n lines.push('- **Type:** Event');\n\n const dateRange = startDate && endDate ? formatDateRange(startDate, endDate) : undefined;\n if (dateRange) {\n lines.push(`- **Dates:** ${dateRange}`);\n }\n if (location) {\n lines.push(`- **Location:** ${location}`);\n }\n if (timezone) {\n lines.push(`- **Timezone:** ${timezone}`);\n }\n if (themes.length > 0) {\n lines.push(`- **Themes:** ${themes.join(', ')}`);\n }\n\n lines.push('');\n const upcoming = getUpcomingEvents(events, 7);\n if (upcoming.length === 0) {\n lines.push('No upcoming events in the next 7 days.');\n } else {\n lines.push('### Upcoming Events (next 7 days)');\n lines.push('| Time | Event | Location |');\n lines.push('|------|-------|----------|');\n for (const evt of upcoming) {\n const time = formatEventTime(evt.startTime);\n const loc = escapeTableCell(evt.location ?? '');\n const title = escapeTableCell(evt.title);\n lines.push(`| ${time} | ${title} | ${loc} |`);\n }\n }\n\n return lines.join('\\n');\n}\n\nfunction formatDateRange(start: string, end: string): string | undefined {\n const s = new Date(start);\n const e = new Date(end);\n if (isNaN(s.getTime()) || isNaN(e.getTime())) return undefined;\n const opts: Intl.DateTimeFormatOptions = { month: 'long', day: 'numeric', year: 'numeric', timeZone: 'UTC' };\n return `${s.toLocaleDateString('en-US', opts)} – ${e.toLocaleDateString('en-US', opts)}`;\n}\n\nfunction formatEventTime(iso: string): string {\n const d = new Date(iso);\n if (isNaN(d.getTime())) return iso;\n return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', timeZone: 'UTC' }) +\n ', ' +\n d.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', timeZone: 'UTC' });\n}\n\nfunction escapeTableCell(value: string): string {\n return value.replace(/\\|/g, '\\\\|').replace(/\\n/g, ' ');\n}\n\nfunction normalizeEvents(raw: unknown[]): NonNullable<EventMetadata['events']> {\n return raw.filter((e): e is NonNullable<EventMetadata['events']>[number] => {\n if (typeof e !== 'object' || e === null) return false;\n const obj = e as Record<string, unknown>;\n return typeof obj.title === 'string' && typeof obj.startTime === 'string' && typeof obj.endTime === 'string';\n });\n}\n\nfunction getUpcomingEvents(\n events: NonNullable<EventMetadata['events']>,\n windowDays: number,\n): NonNullable<EventMetadata['events']> {\n const now = Date.now();\n const windowEnd = now + windowDays * 24 * 60 * 60 * 1000;\n return events\n .map((e) => ({ e, t: new Date(e.startTime).getTime() }))\n .filter(({ t }) => !isNaN(t) && t >= now && t <= windowEnd)\n .sort((a, b) => a.t - b.t)\n .map(({ e }) => e);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-meta.sanitizer.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"debug-meta.sanitizer.d.ts","sourceRoot":"/","sources":["shared/observability/debug-meta.sanitizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,kEAAkE;AAClE,eAAO,MAAM,8BAA8B,yBAAyB,CAAC;AAwDrE;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,OAAO,EACZ,eAAe,GAAE,MAAkC,GAClD,OAAO,CAOT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-meta.sanitizer.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"debug-meta.sanitizer.js","sourceRoot":"/","sources":["shared/observability/debug-meta.sanitizer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Sanitizes objects for inclusion in chat debug meta.\n * Strips embeddings, truncates long strings, and handles circular refs.\n */\n\nconst BLOCKLIST_KEYS = new Set([\n \"embedding\",\n \"embeddingVector\",\n \"vector\",\n]);\nconst BLOCKLIST_SUFFIXES = [\"Embedding\", \"Vector\"];\nconst EMBEDDING_ARRAY_THRESHOLD = 100;\nconst DEFAULT_MAX_STRING_LENGTH = 2048;\n/** Exported for tests that assert on circular-ref placeholder. */\nexport const SANITIZATION_ERROR_PLACEHOLDER = \"[sanitization error]\";\n\nfunction isBlocklistedKey(key: string): boolean {\n if (BLOCKLIST_KEYS.has(key)) return true;\n return BLOCKLIST_SUFFIXES.some((s) => key.endsWith(s));\n}\n\nfunction isNumberArray(arr: unknown): arr is number[] {\n return Array.isArray(arr) && arr.length > 0 && typeof arr[0] === \"number\";\n}\n\nfunction truncateString(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return `[truncated, ${str.length} chars]`;\n}\n\nfunction sanitizeValue(\n value: unknown,\n maxStringLength: number,\n seen: WeakSet<object>,\n): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value === \"number\" || typeof value === \"boolean\") return value;\n if (typeof value === \"string\")\n return truncateString(value, maxStringLength);\n\n if (typeof value === \"object\") {\n if (seen.has(value as object)) return SANITIZATION_ERROR_PLACEHOLDER;\n seen.add(value as object);\n\n if (Array.isArray(value)) {\n if (isNumberArray(value) && value.length > EMBEDDING_ARRAY_THRESHOLD)\n return `[embedding, length ${value.length}]`;\n return value.map((item) => sanitizeValue(item, maxStringLength, seen));\n }\n\n const obj = value as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n if (isBlocklistedKey(k)) {\n if (Array.isArray(v) && isNumberArray(v))\n out[k] = `[embedding, length ${v.length}]`;\n else if (Array.isArray(v))\n out[k] = `[array, length ${v.length}]`;\n else\n out[k] = \"[redacted]\";\n } else {\n out[k] = sanitizeValue(v, maxStringLength, seen);\n }\n }\n return out;\n }\n\n return value;\n}\n\n/**\n * Sanitizes an object for safe inclusion in debug meta.\n * - Replaces embedding/vector keys and long number arrays with placeholders.\n * - Truncates strings over maxStringLength.\n * - On circular reference or error, returns a placeholder string.\n *\n * @param obj - Value to sanitize (object, array, or primitive)\n * @param maxStringLength - Max string length before truncation (default 2048)\n * @returns Sanitized copy or \"[sanitization error]\" on failure\n */\nexport function sanitizeForDebugMeta(\n obj: unknown,\n maxStringLength: number = DEFAULT_MAX_STRING_LENGTH,\n): unknown {\n try {\n const seen = new WeakSet<object>();\n return sanitizeValue(obj, maxStringLength, seen);\n } catch {\n return SANITIZATION_ERROR_PLACEHOLDER;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"/","sources":["shared/observability/log.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,KAAK,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAE3E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC;AAEhE,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAyBvE,KAAK,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,gBAAgB,CAAC;AAC3E,KAAK,UAAU,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;AAK9C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,UAAU,QAG7E;AAMD,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEtD;AAQD;;;;;;;;;GASG;AACH,eAAO,MAAM,GAAG;;uBAdG,MAAM;;;uBAAN,MAAM;;;uBAAN,MAAM;;;uBAAN,MAAM;;CAmBxB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.js","sourceRoot":"","sources":["
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"/","sources":["shared/observability/log.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoBH,kFAAkF;AAClF,yBAAyB;AACzB,kFAAkF;AAElF,SAAS,mBAAmB,CAAC,QAAgB,EAAE,MAAc;IAC3D,MAAM,MAAM,GAAG,IAAI,MAAM,GAAG,CAAC;IAC7B,OAAO;QACL,OAAO,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3E,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzE,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvE,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACvE,KAAK,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC1E,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,KAAK,CAAC;AACf,CAAC;AASD,IAAI,cAAc,GAAkB,mBAAmB,CAAC;AACxD,IAAI,UAAU,GAAe,eAAe,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAsB,EAAE,QAAqB;IAC5E,cAAc,GAAG,OAAO,CAAC;IACzB,IAAI,QAAQ;QAAE,UAAU,GAAG,QAAQ,CAAC;AACtC,CAAC;AAED,kFAAkF;AAClF,aAAa;AACb,kFAAkF;AAElF,wFAAwF;AACxF,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO;QACL,IAAI,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1D,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC;IACjC,GAAG,EAAE,WAAW,CAAC,KAAK,CAAC;IACvB,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC;IAC3B,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC;CAC5B,CAAC","sourcesContent":["/**\n * Protocol-internal logging module.\n *\n * Self-contained — no imports from outside the protocol library.\n * Ships with a minimal console-based default. The host application can\n * call `setLoggerFactory()` at startup to wire in a richer implementation\n * (e.g. the project-wide `log` utility with ANSI colors, context filtering,\n * and embedding redaction).\n */\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// TYPES\n// ═══════════════════════════════════════════════════════════════════════════════\n\ntype LogMethod = (message: string, meta?: Record<string, unknown>) => void;\n\nexport type LoggerWithSource = {\n verbose: LogMethod;\n debug: LogMethod;\n info: LogMethod;\n warn: LogMethod;\n error: LogMethod;\n};\n\nexport type LogContext = 'protocol' | 'lib' | 'agent' | 'graph';\n\nexport type LogLevel = 'verbose' | 'debug' | 'info' | 'warn' | 'error';\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// DEFAULT IMPLEMENTATION\n// ═══════════════════════════════════════════════════════════════════════════════\n\nfunction defaultCreateLogger(_context: string, source: string): LoggerWithSource {\n const prefix = `[${source}]`;\n return {\n verbose: (msg, meta) => console.debug(prefix, msg, ...(meta ? [meta] : [])),\n debug: (msg, meta) => console.debug(prefix, msg, ...(meta ? [meta] : [])),\n info: (msg, meta) => console.info(prefix, msg, ...(meta ? [meta] : [])),\n warn: (msg, meta) => console.warn(prefix, msg, ...(meta ? [meta] : [])),\n error: (msg, meta) => console.error(prefix, msg, ...(meta ? [meta] : [])),\n };\n}\n\nfunction defaultSanitize(value: unknown): unknown {\n return value;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// PLUGGABLE FACTORY\n// ═══════════════════════════════════════════════════════════════════════════════\n\ntype LoggerFactory = (context: string, source: string) => LoggerWithSource;\ntype SanitizeFn = (value: unknown) => unknown;\n\nlet createLoggerFn: LoggerFactory = defaultCreateLogger;\nlet sanitizeFn: SanitizeFn = defaultSanitize;\n\n/**\n * Override the logger factory used by all protocol-internal logging.\n * Call this at application startup to wire in your project's logger.\n *\n * @example\n * ```ts\n * import { log, sanitizeForLog } from \"./lib/log.js\";\n * import { setLoggerFactory } from \"./lib/protocol/support/log.js\";\n *\n * setLoggerFactory(\n * (context, source) => log.withContext(context as LogContext, source),\n * sanitizeForLog,\n * );\n * ```\n */\nexport function setLoggerFactory(factory: LoggerFactory, sanitize?: SanitizeFn) {\n createLoggerFn = factory;\n if (sanitize) sanitizeFn = sanitize;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════════\n// PUBLIC API\n// ═══════════════════════════════════════════════════════════════════════════════\n\n/** Sanitize an object for logging (redacts embeddings when host logger is wired in). */\nexport function sanitizeForLog(value: unknown): unknown {\n return sanitizeFn(value);\n}\n\nfunction lazyContext(context: string) {\n return {\n from: (source: string) => createLoggerFn(context, source),\n };\n}\n\n/**\n * Logger with pre-bound context. Usage:\n * ```ts\n * const logger = log.protocol.from('MyComponent');\n * logger.info('started');\n * ```\n *\n * Logger creation is deferred to call time so `setLoggerFactory()` can be\n * called at app startup and all subsequent `.from()` calls use the new factory.\n */\nexport const log = {\n protocol: lazyContext('protocol'),\n lib: lazyContext('lib'),\n agent: lazyContext('agent'),\n graph: lazyContext('graph'),\n};\n"]}
|