@indexnetwork/protocol 0.1.0
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/agents/chat.agent.d.ts +218 -0
- package/dist/agents/chat.agent.d.ts.map +1 -0
- package/dist/agents/chat.agent.js +884 -0
- package/dist/agents/chat.agent.js.map +1 -0
- package/dist/agents/chat.prompt.d.ts +18 -0
- package/dist/agents/chat.prompt.d.ts.map +1 -0
- package/dist/agents/chat.prompt.js +372 -0
- package/dist/agents/chat.prompt.js.map +1 -0
- package/dist/agents/chat.prompt.modules.d.ts +61 -0
- package/dist/agents/chat.prompt.modules.d.ts.map +1 -0
- package/dist/agents/chat.prompt.modules.js +366 -0
- package/dist/agents/chat.prompt.modules.js.map +1 -0
- package/dist/agents/chat.title.generator.d.ts +20 -0
- package/dist/agents/chat.title.generator.d.ts.map +1 -0
- package/dist/agents/chat.title.generator.js +66 -0
- package/dist/agents/chat.title.generator.js.map +1 -0
- package/dist/agents/home.categorizer.d.ts +28 -0
- package/dist/agents/home.categorizer.d.ts.map +1 -0
- package/dist/agents/home.categorizer.js +170 -0
- package/dist/agents/home.categorizer.js.map +1 -0
- package/dist/agents/hyde.generator.d.ts +27 -0
- package/dist/agents/hyde.generator.d.ts.map +1 -0
- package/dist/agents/hyde.generator.js +75 -0
- package/dist/agents/hyde.generator.js.map +1 -0
- package/dist/agents/hyde.strategies.d.ts +17 -0
- package/dist/agents/hyde.strategies.d.ts.map +1 -0
- package/dist/agents/hyde.strategies.js +29 -0
- package/dist/agents/hyde.strategies.js.map +1 -0
- package/dist/agents/intent.clarifier.d.ts +29 -0
- package/dist/agents/intent.clarifier.d.ts.map +1 -0
- package/dist/agents/intent.clarifier.js +186 -0
- package/dist/agents/intent.clarifier.js.map +1 -0
- package/dist/agents/intent.indexer.d.ts +77 -0
- package/dist/agents/intent.indexer.d.ts.map +1 -0
- package/dist/agents/intent.indexer.js +164 -0
- package/dist/agents/intent.indexer.js.map +1 -0
- package/dist/agents/intent.inferrer.d.ts +95 -0
- package/dist/agents/intent.inferrer.d.ts.map +1 -0
- package/dist/agents/intent.inferrer.js +238 -0
- package/dist/agents/intent.inferrer.js.map +1 -0
- package/dist/agents/intent.reconciler.d.ts +106 -0
- package/dist/agents/intent.reconciler.d.ts.map +1 -0
- package/dist/agents/intent.reconciler.js +184 -0
- package/dist/agents/intent.reconciler.js.map +1 -0
- package/dist/agents/intent.verifier.d.ts +97 -0
- package/dist/agents/intent.verifier.d.ts.map +1 -0
- package/dist/agents/intent.verifier.js +234 -0
- package/dist/agents/intent.verifier.js.map +1 -0
- package/dist/agents/invite.generator.d.ts +47 -0
- package/dist/agents/invite.generator.d.ts.map +1 -0
- package/dist/agents/invite.generator.js +56 -0
- package/dist/agents/invite.generator.js.map +1 -0
- package/dist/agents/lens.inferrer.d.ts +37 -0
- package/dist/agents/lens.inferrer.d.ts.map +1 -0
- package/dist/agents/lens.inferrer.js +98 -0
- package/dist/agents/lens.inferrer.js.map +1 -0
- package/dist/agents/model.config.d.ts +120 -0
- package/dist/agents/model.config.d.ts.map +1 -0
- package/dist/agents/model.config.js +76 -0
- package/dist/agents/model.config.js.map +1 -0
- package/dist/agents/negotiation.insights.generator.d.ts +32 -0
- package/dist/agents/negotiation.insights.generator.d.ts.map +1 -0
- package/dist/agents/negotiation.insights.generator.js +105 -0
- package/dist/agents/negotiation.insights.generator.js.map +1 -0
- package/dist/agents/negotiation.proposer.d.ts +26 -0
- package/dist/agents/negotiation.proposer.d.ts.map +1 -0
- package/dist/agents/negotiation.proposer.js +67 -0
- package/dist/agents/negotiation.proposer.js.map +1 -0
- package/dist/agents/negotiation.responder.d.ts +26 -0
- package/dist/agents/negotiation.responder.d.ts.map +1 -0
- package/dist/agents/negotiation.responder.js +71 -0
- package/dist/agents/negotiation.responder.js.map +1 -0
- package/dist/agents/opportunity.evaluator.d.ts +253 -0
- package/dist/agents/opportunity.evaluator.d.ts.map +1 -0
- package/dist/agents/opportunity.evaluator.js +413 -0
- package/dist/agents/opportunity.evaluator.js.map +1 -0
- package/dist/agents/opportunity.presenter.d.ts +115 -0
- package/dist/agents/opportunity.presenter.d.ts.map +1 -0
- package/dist/agents/opportunity.presenter.js +524 -0
- package/dist/agents/opportunity.presenter.js.map +1 -0
- package/dist/agents/profile.generator.d.ts +67 -0
- package/dist/agents/profile.generator.d.ts.map +1 -0
- package/dist/agents/profile.generator.js +97 -0
- package/dist/agents/profile.generator.js.map +1 -0
- package/dist/agents/profile.hyde.generator.d.ts +43 -0
- package/dist/agents/profile.hyde.generator.d.ts.map +1 -0
- package/dist/agents/profile.hyde.generator.js +113 -0
- package/dist/agents/profile.hyde.generator.js.map +1 -0
- package/dist/agents/suggestion.generator.d.ts +24 -0
- package/dist/agents/suggestion.generator.d.ts.map +1 -0
- package/dist/agents/suggestion.generator.js +96 -0
- package/dist/agents/suggestion.generator.js.map +1 -0
- package/dist/graphs/chat.graph.d.ts +312 -0
- package/dist/graphs/chat.graph.d.ts.map +1 -0
- package/dist/graphs/chat.graph.js +267 -0
- package/dist/graphs/chat.graph.js.map +1 -0
- package/dist/graphs/home.graph.d.ts +180 -0
- package/dist/graphs/home.graph.d.ts.map +1 -0
- package/dist/graphs/home.graph.js +598 -0
- package/dist/graphs/home.graph.js.map +1 -0
- package/dist/graphs/hyde.graph.d.ts +110 -0
- package/dist/graphs/hyde.graph.d.ts.map +1 -0
- package/dist/graphs/hyde.graph.js +235 -0
- package/dist/graphs/hyde.graph.js.map +1 -0
- package/dist/graphs/index.graph.d.ts +620 -0
- package/dist/graphs/index.graph.d.ts.map +1 -0
- package/dist/graphs/index.graph.js +226 -0
- package/dist/graphs/index.graph.js.map +1 -0
- package/dist/graphs/index_membership.graph.d.ts +250 -0
- package/dist/graphs/index_membership.graph.d.ts.map +1 -0
- package/dist/graphs/index_membership.graph.js +204 -0
- package/dist/graphs/index_membership.graph.js.map +1 -0
- package/dist/graphs/intent.graph.d.ts +490 -0
- package/dist/graphs/intent.graph.d.ts.map +1 -0
- package/dist/graphs/intent.graph.js +787 -0
- package/dist/graphs/intent.graph.js.map +1 -0
- package/dist/graphs/intent_index.graph.d.ts +396 -0
- package/dist/graphs/intent_index.graph.d.ts.map +1 -0
- package/dist/graphs/intent_index.graph.js +331 -0
- package/dist/graphs/intent_index.graph.js.map +1 -0
- package/dist/graphs/maintenance.graph.d.ts +177 -0
- package/dist/graphs/maintenance.graph.d.ts.map +1 -0
- package/dist/graphs/maintenance.graph.js +173 -0
- package/dist/graphs/maintenance.graph.js.map +1 -0
- package/dist/graphs/negotiation.graph.d.ts +819 -0
- package/dist/graphs/negotiation.graph.d.ts.map +1 -0
- package/dist/graphs/negotiation.graph.js +255 -0
- package/dist/graphs/negotiation.graph.js.map +1 -0
- package/dist/graphs/opportunity.graph.d.ts +1082 -0
- package/dist/graphs/opportunity.graph.d.ts.map +1 -0
- package/dist/graphs/opportunity.graph.js +2534 -0
- package/dist/graphs/opportunity.graph.js.map +1 -0
- package/dist/graphs/profile.graph.d.ts +617 -0
- package/dist/graphs/profile.graph.d.ts.map +1 -0
- package/dist/graphs/profile.graph.js +839 -0
- package/dist/graphs/profile.graph.js.map +1 -0
- package/dist/graphs/tests/chat.graph.mocks.d.ts +104 -0
- package/dist/graphs/tests/chat.graph.mocks.d.ts.map +1 -0
- package/dist/graphs/tests/chat.graph.mocks.js +225 -0
- package/dist/graphs/tests/chat.graph.mocks.js.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/auth.interface.d.ts +15 -0
- package/dist/interfaces/auth.interface.d.ts.map +1 -0
- package/dist/interfaces/auth.interface.js +2 -0
- package/dist/interfaces/auth.interface.js.map +1 -0
- package/dist/interfaces/cache.interface.d.ts +43 -0
- package/dist/interfaces/cache.interface.d.ts.map +1 -0
- package/dist/interfaces/cache.interface.js +6 -0
- package/dist/interfaces/cache.interface.js.map +1 -0
- package/dist/interfaces/chat-session.interface.d.ts +11 -0
- package/dist/interfaces/chat-session.interface.d.ts.map +1 -0
- package/dist/interfaces/chat-session.interface.js +2 -0
- package/dist/interfaces/chat-session.interface.js.map +1 -0
- package/dist/interfaces/contact.interface.d.ts +48 -0
- package/dist/interfaces/contact.interface.d.ts.map +1 -0
- package/dist/interfaces/contact.interface.js +2 -0
- package/dist/interfaces/contact.interface.js.map +1 -0
- package/dist/interfaces/database.interface.d.ts +1495 -0
- package/dist/interfaces/database.interface.d.ts.map +1 -0
- package/dist/interfaces/database.interface.js +2 -0
- package/dist/interfaces/database.interface.js.map +1 -0
- package/dist/interfaces/embedder.interface.d.ts +85 -0
- package/dist/interfaces/embedder.interface.d.ts.map +1 -0
- package/dist/interfaces/embedder.interface.js +5 -0
- package/dist/interfaces/embedder.interface.js.map +1 -0
- package/dist/interfaces/enrichment.interface.d.ts +40 -0
- package/dist/interfaces/enrichment.interface.d.ts.map +1 -0
- package/dist/interfaces/enrichment.interface.js +2 -0
- package/dist/interfaces/enrichment.interface.js.map +1 -0
- package/dist/interfaces/integration.interface.d.ts +91 -0
- package/dist/interfaces/integration.interface.d.ts.map +1 -0
- package/dist/interfaces/integration.interface.js +2 -0
- package/dist/interfaces/integration.interface.js.map +1 -0
- package/dist/interfaces/queue.interface.d.ts +17 -0
- package/dist/interfaces/queue.interface.d.ts.map +1 -0
- package/dist/interfaces/queue.interface.js +5 -0
- package/dist/interfaces/queue.interface.js.map +1 -0
- package/dist/interfaces/scraper.interface.d.ts +31 -0
- package/dist/interfaces/scraper.interface.d.ts.map +1 -0
- package/dist/interfaces/scraper.interface.js +2 -0
- package/dist/interfaces/scraper.interface.js.map +1 -0
- package/dist/interfaces/storage.interface.d.ts +46 -0
- package/dist/interfaces/storage.interface.d.ts.map +1 -0
- package/dist/interfaces/storage.interface.js +6 -0
- package/dist/interfaces/storage.interface.js.map +1 -0
- package/dist/mcp/mcp.server.d.ts +29 -0
- package/dist/mcp/mcp.server.d.ts.map +1 -0
- package/dist/mcp/mcp.server.js +171 -0
- package/dist/mcp/mcp.server.js.map +1 -0
- package/dist/states/chat.state.d.ts +126 -0
- package/dist/states/chat.state.d.ts.map +1 -0
- package/dist/states/chat.state.js +112 -0
- package/dist/states/chat.state.js.map +1 -0
- package/dist/states/home.state.d.ts +100 -0
- package/dist/states/home.state.d.ts.map +1 -0
- package/dist/states/home.state.js +74 -0
- package/dist/states/home.state.js.map +1 -0
- package/dist/states/hyde.state.d.ts +54 -0
- package/dist/states/hyde.state.d.ts.map +1 -0
- package/dist/states/hyde.state.js +66 -0
- package/dist/states/hyde.state.js.map +1 -0
- package/dist/states/index.state.d.ts +179 -0
- package/dist/states/index.state.d.ts.map +1 -0
- package/dist/states/index.state.js +56 -0
- package/dist/states/index.state.js.map +1 -0
- package/dist/states/index_membership.state.d.ts +77 -0
- package/dist/states/index_membership.state.d.ts.map +1 -0
- package/dist/states/index_membership.state.js +43 -0
- package/dist/states/index_membership.state.js.map +1 -0
- package/dist/states/intent.state.d.ts +203 -0
- package/dist/states/intent.state.d.ts.map +1 -0
- package/dist/states/intent.state.js +153 -0
- package/dist/states/intent.state.js.map +1 -0
- package/dist/states/intent_index.state.d.ts +148 -0
- package/dist/states/intent_index.state.d.ts.map +1 -0
- package/dist/states/intent_index.state.js +100 -0
- package/dist/states/intent_index.state.js.map +1 -0
- package/dist/states/maintenance.state.d.ts +36 -0
- package/dist/states/maintenance.state.d.ts.map +1 -0
- package/dist/states/maintenance.state.js +56 -0
- package/dist/states/maintenance.state.js.map +1 -0
- package/dist/states/negotiation.state.d.ts +230 -0
- package/dist/states/negotiation.state.d.ts.map +1 -0
- package/dist/states/negotiation.state.js +82 -0
- package/dist/states/negotiation.state.js.map +1 -0
- package/dist/states/opportunity.state.d.ts +300 -0
- package/dist/states/opportunity.state.d.ts.map +1 -0
- package/dist/states/opportunity.state.js +207 -0
- package/dist/states/opportunity.state.js.map +1 -0
- package/dist/states/profile.state.d.ts +172 -0
- package/dist/states/profile.state.d.ts.map +1 -0
- package/dist/states/profile.state.js +133 -0
- package/dist/states/profile.state.js.map +1 -0
- package/dist/streamers/chat.streamer.d.ts +55 -0
- package/dist/streamers/chat.streamer.d.ts.map +1 -0
- package/dist/streamers/chat.streamer.js +186 -0
- package/dist/streamers/chat.streamer.js.map +1 -0
- package/dist/streamers/index.d.ts +3 -0
- package/dist/streamers/index.d.ts.map +1 -0
- package/dist/streamers/index.js +3 -0
- package/dist/streamers/index.js.map +1 -0
- package/dist/streamers/response.streamer.d.ts +36 -0
- package/dist/streamers/response.streamer.d.ts.map +1 -0
- package/dist/streamers/response.streamer.js +46 -0
- package/dist/streamers/response.streamer.js.map +1 -0
- package/dist/support/chat.utils.d.ts +42 -0
- package/dist/support/chat.utils.d.ts.map +1 -0
- package/dist/support/chat.utils.js +89 -0
- package/dist/support/chat.utils.js.map +1 -0
- package/dist/support/debug-meta.sanitizer.d.ts +18 -0
- package/dist/support/debug-meta.sanitizer.d.ts.map +1 -0
- package/dist/support/debug-meta.sanitizer.js +82 -0
- package/dist/support/debug-meta.sanitizer.js.map +1 -0
- package/dist/support/feed.health.d.ts +32 -0
- package/dist/support/feed.health.d.ts.map +1 -0
- package/dist/support/feed.health.js +76 -0
- package/dist/support/feed.health.js.map +1 -0
- package/dist/support/introducer.discovery.d.ts +78 -0
- package/dist/support/introducer.discovery.d.ts.map +1 -0
- package/dist/support/introducer.discovery.js +101 -0
- package/dist/support/introducer.discovery.js.map +1 -0
- package/dist/support/log.d.ts +65 -0
- package/dist/support/log.d.ts.map +1 -0
- package/dist/support/log.js +76 -0
- package/dist/support/log.js.map +1 -0
- package/dist/support/lucide.icon-catalog.d.ts +22 -0
- package/dist/support/lucide.icon-catalog.d.ts.map +1 -0
- package/dist/support/lucide.icon-catalog.js +101 -0
- package/dist/support/lucide.icon-catalog.js.map +1 -0
- package/dist/support/opportunity.card-text.d.ts +39 -0
- package/dist/support/opportunity.card-text.d.ts.map +1 -0
- package/dist/support/opportunity.card-text.js +333 -0
- package/dist/support/opportunity.card-text.js.map +1 -0
- package/dist/support/opportunity.constants.d.ts +9 -0
- package/dist/support/opportunity.constants.d.ts.map +1 -0
- package/dist/support/opportunity.constants.js +11 -0
- package/dist/support/opportunity.constants.js.map +1 -0
- package/dist/support/opportunity.discover.d.ts +144 -0
- package/dist/support/opportunity.discover.d.ts.map +1 -0
- package/dist/support/opportunity.discover.js +610 -0
- package/dist/support/opportunity.discover.js.map +1 -0
- package/dist/support/opportunity.enricher.d.ts +44 -0
- package/dist/support/opportunity.enricher.d.ts.map +1 -0
- package/dist/support/opportunity.enricher.js +245 -0
- package/dist/support/opportunity.enricher.js.map +1 -0
- package/dist/support/opportunity.persist.d.ts +39 -0
- package/dist/support/opportunity.persist.d.ts.map +1 -0
- package/dist/support/opportunity.persist.js +63 -0
- package/dist/support/opportunity.persist.js.map +1 -0
- package/dist/support/opportunity.presentation.d.ts +21 -0
- package/dist/support/opportunity.presentation.d.ts.map +1 -0
- package/dist/support/opportunity.presentation.js +75 -0
- package/dist/support/opportunity.presentation.js.map +1 -0
- package/dist/support/opportunity.sanitize.d.ts +18 -0
- package/dist/support/opportunity.sanitize.d.ts.map +1 -0
- package/dist/support/opportunity.sanitize.js +89 -0
- package/dist/support/opportunity.sanitize.js.map +1 -0
- package/dist/support/opportunity.utils.d.ts +99 -0
- package/dist/support/opportunity.utils.d.ts.map +1 -0
- package/dist/support/opportunity.utils.js +184 -0
- package/dist/support/opportunity.utils.js.map +1 -0
- package/dist/support/performance.d.ts +19 -0
- package/dist/support/performance.d.ts.map +1 -0
- package/dist/support/performance.js +43 -0
- package/dist/support/performance.js.map +1 -0
- package/dist/support/profile.enrichment-display-name.d.ts +16 -0
- package/dist/support/profile.enrichment-display-name.d.ts.map +1 -0
- package/dist/support/profile.enrichment-display-name.js +22 -0
- package/dist/support/profile.enrichment-display-name.js.map +1 -0
- package/dist/support/protocol.logger.d.ts +22 -0
- package/dist/support/protocol.logger.d.ts.map +1 -0
- package/dist/support/protocol.logger.js +44 -0
- package/dist/support/protocol.logger.js.map +1 -0
- package/dist/support/request-context.d.ts +19 -0
- package/dist/support/request-context.d.ts.map +1 -0
- package/dist/support/request-context.js +7 -0
- package/dist/support/request-context.js.map +1 -0
- package/dist/tools/contact.tools.d.ts +7 -0
- package/dist/tools/contact.tools.d.ts.map +1 -0
- package/dist/tools/contact.tools.js +115 -0
- package/dist/tools/contact.tools.js.map +1 -0
- package/dist/tools/index.d.ts +17 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +140 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/index.tools.d.ts +3 -0
- package/dist/tools/index.tools.d.ts.map +1 -0
- package/dist/tools/index.tools.js +423 -0
- package/dist/tools/index.tools.js.map +1 -0
- package/dist/tools/integration.tools.d.ts +13 -0
- package/dist/tools/integration.tools.d.ts.map +1 -0
- package/dist/tools/integration.tools.js +77 -0
- package/dist/tools/integration.tools.js.map +1 -0
- package/dist/tools/intent.tools.d.ts +3 -0
- package/dist/tools/intent.tools.d.ts.map +1 -0
- package/dist/tools/intent.tools.js +458 -0
- package/dist/tools/intent.tools.js.map +1 -0
- package/dist/tools/opportunity.tools.d.ts +44 -0
- package/dist/tools/opportunity.tools.d.ts.map +1 -0
- package/dist/tools/opportunity.tools.js +814 -0
- package/dist/tools/opportunity.tools.js.map +1 -0
- package/dist/tools/profile.tools.d.ts +3 -0
- package/dist/tools/profile.tools.d.ts.map +1 -0
- package/dist/tools/profile.tools.js +513 -0
- package/dist/tools/profile.tools.js.map +1 -0
- package/dist/tools/tool.helpers.d.ts +225 -0
- package/dist/tools/tool.helpers.d.ts.map +1 -0
- package/dist/tools/tool.helpers.js +172 -0
- package/dist/tools/tool.helpers.js.map +1 -0
- package/dist/tools/tool.registry.d.ts +12 -0
- package/dist/tools/tool.registry.d.ts.map +1 -0
- package/dist/tools/tool.registry.js +62 -0
- package/dist/tools/tool.registry.js.map +1 -0
- package/dist/tools/utility.tools.d.ts +3 -0
- package/dist/tools/utility.tools.d.ts.map +1 -0
- package/dist/tools/utility.tools.js +107 -0
- package/dist/tools/utility.tools.js.map +1 -0
- package/dist/types/chat-streaming.types.d.ts +472 -0
- package/dist/types/chat-streaming.types.d.ts.map +1 -0
- package/dist/types/chat-streaming.types.js +260 -0
- package/dist/types/chat-streaming.types.js.map +1 -0
- package/package.json +32 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol-internal logging module.
|
|
3
|
+
*
|
|
4
|
+
* Self-contained — no imports from outside the protocol library.
|
|
5
|
+
* Ships with a minimal console-based default. The host application can
|
|
6
|
+
* call `setLoggerFactory()` at startup to wire in a richer implementation
|
|
7
|
+
* (e.g. the project-wide `log` utility with ANSI colors, context filtering,
|
|
8
|
+
* and embedding redaction).
|
|
9
|
+
*/
|
|
10
|
+
type LogMethod = (message: string, meta?: Record<string, unknown>) => void;
|
|
11
|
+
export type LoggerWithSource = {
|
|
12
|
+
verbose: LogMethod;
|
|
13
|
+
debug: LogMethod;
|
|
14
|
+
info: LogMethod;
|
|
15
|
+
warn: LogMethod;
|
|
16
|
+
error: LogMethod;
|
|
17
|
+
};
|
|
18
|
+
export type LogContext = 'protocol' | 'lib' | 'agent' | 'graph';
|
|
19
|
+
export type LogLevel = 'verbose' | 'debug' | 'info' | 'warn' | 'error';
|
|
20
|
+
type LoggerFactory = (context: string, source: string) => LoggerWithSource;
|
|
21
|
+
type SanitizeFn = (value: unknown) => unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Override the logger factory used by all protocol-internal logging.
|
|
24
|
+
* Call this at application startup to wire in your project's logger.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { log, sanitizeForLog } from "./lib/log.js";
|
|
29
|
+
* import { setLoggerFactory } from "./lib/protocol/support/log.js";
|
|
30
|
+
*
|
|
31
|
+
* setLoggerFactory(
|
|
32
|
+
* (context, source) => log.withContext(context as LogContext, source),
|
|
33
|
+
* sanitizeForLog,
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function setLoggerFactory(factory: LoggerFactory, sanitize?: SanitizeFn): void;
|
|
38
|
+
/** Sanitize an object for logging (redacts embeddings when host logger is wired in). */
|
|
39
|
+
export declare function sanitizeForLog(value: unknown): unknown;
|
|
40
|
+
/**
|
|
41
|
+
* Logger with pre-bound context. Usage:
|
|
42
|
+
* ```ts
|
|
43
|
+
* const logger = log.protocol.from('MyComponent');
|
|
44
|
+
* logger.info('started');
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* Logger creation is deferred to call time so `setLoggerFactory()` can be
|
|
48
|
+
* called at app startup and all subsequent `.from()` calls use the new factory.
|
|
49
|
+
*/
|
|
50
|
+
export declare const log: {
|
|
51
|
+
protocol: {
|
|
52
|
+
from: (source: string) => LoggerWithSource;
|
|
53
|
+
};
|
|
54
|
+
lib: {
|
|
55
|
+
from: (source: string) => LoggerWithSource;
|
|
56
|
+
};
|
|
57
|
+
agent: {
|
|
58
|
+
from: (source: string) => LoggerWithSource;
|
|
59
|
+
};
|
|
60
|
+
graph: {
|
|
61
|
+
from: (source: string) => LoggerWithSource;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/support/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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Protocol-internal logging module.
|
|
3
|
+
*
|
|
4
|
+
* Self-contained — no imports from outside the protocol library.
|
|
5
|
+
* Ships with a minimal console-based default. The host application can
|
|
6
|
+
* call `setLoggerFactory()` at startup to wire in a richer implementation
|
|
7
|
+
* (e.g. the project-wide `log` utility with ANSI colors, context filtering,
|
|
8
|
+
* and embedding redaction).
|
|
9
|
+
*/
|
|
10
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
11
|
+
// DEFAULT IMPLEMENTATION
|
|
12
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
13
|
+
function defaultCreateLogger(_context, source) {
|
|
14
|
+
const prefix = `[${source}]`;
|
|
15
|
+
return {
|
|
16
|
+
verbose: (msg, meta) => console.debug(prefix, msg, ...(meta ? [meta] : [])),
|
|
17
|
+
debug: (msg, meta) => console.debug(prefix, msg, ...(meta ? [meta] : [])),
|
|
18
|
+
info: (msg, meta) => console.info(prefix, msg, ...(meta ? [meta] : [])),
|
|
19
|
+
warn: (msg, meta) => console.warn(prefix, msg, ...(meta ? [meta] : [])),
|
|
20
|
+
error: (msg, meta) => console.error(prefix, msg, ...(meta ? [meta] : [])),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function defaultSanitize(value) {
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
let createLoggerFn = defaultCreateLogger;
|
|
27
|
+
let sanitizeFn = defaultSanitize;
|
|
28
|
+
/**
|
|
29
|
+
* Override the logger factory used by all protocol-internal logging.
|
|
30
|
+
* Call this at application startup to wire in your project's logger.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* import { log, sanitizeForLog } from "./lib/log.js";
|
|
35
|
+
* import { setLoggerFactory } from "./lib/protocol/support/log.js";
|
|
36
|
+
*
|
|
37
|
+
* setLoggerFactory(
|
|
38
|
+
* (context, source) => log.withContext(context as LogContext, source),
|
|
39
|
+
* sanitizeForLog,
|
|
40
|
+
* );
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function setLoggerFactory(factory, sanitize) {
|
|
44
|
+
createLoggerFn = factory;
|
|
45
|
+
if (sanitize)
|
|
46
|
+
sanitizeFn = sanitize;
|
|
47
|
+
}
|
|
48
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
49
|
+
// PUBLIC API
|
|
50
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
51
|
+
/** Sanitize an object for logging (redacts embeddings when host logger is wired in). */
|
|
52
|
+
export function sanitizeForLog(value) {
|
|
53
|
+
return sanitizeFn(value);
|
|
54
|
+
}
|
|
55
|
+
function lazyContext(context) {
|
|
56
|
+
return {
|
|
57
|
+
from: (source) => createLoggerFn(context, source),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Logger with pre-bound context. Usage:
|
|
62
|
+
* ```ts
|
|
63
|
+
* const logger = log.protocol.from('MyComponent');
|
|
64
|
+
* logger.info('started');
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* Logger creation is deferred to call time so `setLoggerFactory()` can be
|
|
68
|
+
* called at app startup and all subsequent `.from()` calls use the new factory.
|
|
69
|
+
*/
|
|
70
|
+
export const log = {
|
|
71
|
+
protocol: lazyContext('protocol'),
|
|
72
|
+
lib: lazyContext('lib'),
|
|
73
|
+
agent: lazyContext('agent'),
|
|
74
|
+
graph: lazyContext('graph'),
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/support/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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lucide icon catalog for home view section headings.
|
|
3
|
+
* Icon names are kebab-case for use with lucide-react DynamicIcon (name prop).
|
|
4
|
+
* Used by home graph LLM to pick an icon per dynamic section.
|
|
5
|
+
*/
|
|
6
|
+
/** Default icon when LLM returns invalid or missing icon name. */
|
|
7
|
+
export declare const DEFAULT_HOME_SECTION_ICON = "hourglass";
|
|
8
|
+
/** Allowed icon names for home sections (subset of Lucide icons). */
|
|
9
|
+
export declare const HOME_SECTION_ICON_NAMES: readonly string[];
|
|
10
|
+
/**
|
|
11
|
+
* Normalize icon name: lowercase, strip spaces (allow kebab-case from LLM).
|
|
12
|
+
*/
|
|
13
|
+
export declare function normalizeIconName(name: string | undefined | null): string;
|
|
14
|
+
/**
|
|
15
|
+
* Validate and return an allowed icon name; fallback to default if unknown.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveHomeSectionIcon(name: string | undefined | null): string;
|
|
18
|
+
/**
|
|
19
|
+
* Return a formatted list of icon names for LLM prompts (comma-separated, truncated if needed).
|
|
20
|
+
*/
|
|
21
|
+
export declare function getIconNamesForPrompt(maxItems?: number): string;
|
|
22
|
+
//# sourceMappingURL=lucide.icon-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lucide.icon-catalog.d.ts","sourceRoot":"","sources":["../../src/support/lucide.icon-catalog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,kEAAkE;AAClE,eAAO,MAAM,yBAAyB,cAAc,CAAC;AAErD,qEAAqE;AACrE,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAiE3C,CAAC;AAIX;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAKzE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAG9E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,SAAK,GAAG,MAAM,CAG3D"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lucide icon catalog for home view section headings.
|
|
3
|
+
* Icon names are kebab-case for use with lucide-react DynamicIcon (name prop).
|
|
4
|
+
* Used by home graph LLM to pick an icon per dynamic section.
|
|
5
|
+
*/
|
|
6
|
+
/** Default icon when LLM returns invalid or missing icon name. */
|
|
7
|
+
export const DEFAULT_HOME_SECTION_ICON = 'hourglass';
|
|
8
|
+
/** Allowed icon names for home sections (subset of Lucide icons). */
|
|
9
|
+
export const HOME_SECTION_ICON_NAMES = [
|
|
10
|
+
'hourglass',
|
|
11
|
+
'telescope',
|
|
12
|
+
'route',
|
|
13
|
+
'bot',
|
|
14
|
+
'user',
|
|
15
|
+
'users',
|
|
16
|
+
'message-circle',
|
|
17
|
+
'sparkles',
|
|
18
|
+
'handshake',
|
|
19
|
+
'target',
|
|
20
|
+
'zap',
|
|
21
|
+
'lightbulb',
|
|
22
|
+
'compass',
|
|
23
|
+
'globe',
|
|
24
|
+
'heart',
|
|
25
|
+
'star',
|
|
26
|
+
'trending-up',
|
|
27
|
+
'briefcase',
|
|
28
|
+
'rocket',
|
|
29
|
+
'search',
|
|
30
|
+
'filter',
|
|
31
|
+
'list',
|
|
32
|
+
'layout-grid',
|
|
33
|
+
'inbox',
|
|
34
|
+
'send',
|
|
35
|
+
'mail',
|
|
36
|
+
'calendar',
|
|
37
|
+
'clock',
|
|
38
|
+
'timer',
|
|
39
|
+
'flag',
|
|
40
|
+
'bookmark',
|
|
41
|
+
'link',
|
|
42
|
+
'share-2',
|
|
43
|
+
'thumbs-up',
|
|
44
|
+
'award',
|
|
45
|
+
'graduation-cap',
|
|
46
|
+
'building-2',
|
|
47
|
+
'network',
|
|
48
|
+
'git-branch',
|
|
49
|
+
'code',
|
|
50
|
+
'palette',
|
|
51
|
+
'pen-tool',
|
|
52
|
+
'folder',
|
|
53
|
+
'file-text',
|
|
54
|
+
'bar-chart',
|
|
55
|
+
'pie-chart',
|
|
56
|
+
'activity',
|
|
57
|
+
'arrow-right',
|
|
58
|
+
'chevron-right',
|
|
59
|
+
'circle-dot',
|
|
60
|
+
'circle-user',
|
|
61
|
+
'user-plus',
|
|
62
|
+
'user-check',
|
|
63
|
+
'users-round',
|
|
64
|
+
'hand',
|
|
65
|
+
'hand-metal',
|
|
66
|
+
'megaphone',
|
|
67
|
+
'bell',
|
|
68
|
+
'eye',
|
|
69
|
+
'eye-off',
|
|
70
|
+
'lock',
|
|
71
|
+
'unlock',
|
|
72
|
+
'shield',
|
|
73
|
+
'shield-check',
|
|
74
|
+
];
|
|
75
|
+
const ALLOWED_SET = new Set(HOME_SECTION_ICON_NAMES);
|
|
76
|
+
/**
|
|
77
|
+
* Normalize icon name: lowercase, strip spaces (allow kebab-case from LLM).
|
|
78
|
+
*/
|
|
79
|
+
export function normalizeIconName(name) {
|
|
80
|
+
if (name == null || typeof name !== 'string')
|
|
81
|
+
return DEFAULT_HOME_SECTION_ICON;
|
|
82
|
+
const normalized = name.trim().toLowerCase().replace(/\s+/g, '-');
|
|
83
|
+
if (!normalized)
|
|
84
|
+
return DEFAULT_HOME_SECTION_ICON;
|
|
85
|
+
return normalized;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Validate and return an allowed icon name; fallback to default if unknown.
|
|
89
|
+
*/
|
|
90
|
+
export function resolveHomeSectionIcon(name) {
|
|
91
|
+
const normalized = normalizeIconName(name);
|
|
92
|
+
return ALLOWED_SET.has(normalized) ? normalized : DEFAULT_HOME_SECTION_ICON;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Return a formatted list of icon names for LLM prompts (comma-separated, truncated if needed).
|
|
96
|
+
*/
|
|
97
|
+
export function getIconNamesForPrompt(maxItems = 60) {
|
|
98
|
+
const list = HOME_SECTION_ICON_NAMES.slice(0, maxItems);
|
|
99
|
+
return list.join(', ');
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=lucide.icon-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lucide.icon-catalog.js","sourceRoot":"","sources":["../../src/support/lucide.icon-catalog.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,kEAAkE;AAClE,MAAM,CAAC,MAAM,yBAAyB,GAAG,WAAW,CAAC;AAErD,qEAAqE;AACrE,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,WAAW;IACX,WAAW;IACX,OAAO;IACP,KAAK;IACL,MAAM;IACN,OAAO;IACP,gBAAgB;IAChB,UAAU;IACV,WAAW;IACX,QAAQ;IACR,KAAK;IACL,WAAW;IACX,SAAS;IACT,OAAO;IACP,OAAO;IACP,MAAM;IACN,aAAa;IACb,WAAW;IACX,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,aAAa;IACb,OAAO;IACP,MAAM;IACN,MAAM;IACN,UAAU;IACV,OAAO;IACP,OAAO;IACP,MAAM;IACN,UAAU;IACV,MAAM;IACN,SAAS;IACT,WAAW;IACX,OAAO;IACP,gBAAgB;IAChB,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,MAAM;IACN,SAAS;IACT,UAAU;IACV,QAAQ;IACR,WAAW;IACX,WAAW;IACX,WAAW;IACX,UAAU;IACV,aAAa;IACb,eAAe;IACf,YAAY;IACZ,aAAa;IACb,WAAW;IACX,YAAY;IACZ,aAAa;IACb,MAAM;IACN,YAAY;IACZ,WAAW;IACX,MAAM;IACN,KAAK;IACL,SAAS;IACT,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,cAAc;CACN,CAAC;AAEX,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS,uBAAuB,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAA+B;IAC/D,IAAI,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,yBAAyB,CAAC;IAC/E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAClE,IAAI,CAAC,UAAU;QAAE,OAAO,yBAAyB,CAAC;IAClD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAA+B;IACpE,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC3C,OAAO,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,yBAAyB,CAAC;AAC9E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAQ,GAAG,EAAE;IACjD,MAAM,IAAI,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACxD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Viewer-centric text for opportunity cards.
|
|
3
|
+
* The card is shown to the viewer (logged-in user) and should introduce the
|
|
4
|
+
* counterpart, not describe the viewer to themselves.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Returns viewer-centric main text for an opportunity card.
|
|
8
|
+
* Prefers the part of the reasoning that describes the counterpart (the person
|
|
9
|
+
* on the card), so the viewer sees an introduction to the counterpart rather
|
|
10
|
+
* than a description of themselves.
|
|
11
|
+
*
|
|
12
|
+
* @param reasoning - Raw interpretation.reasoning (may describe both parties).
|
|
13
|
+
* @param counterpartName - Display name of the suggested connection (e.g. "Alex Chen").
|
|
14
|
+
* @param maxChars - Max length of returned string (default MINIMAL_MAIN_TEXT_MAX_CHARS).
|
|
15
|
+
* @param viewerName - Optional display name of the viewer (signed-in user). When provided, sentences or prefixes describing the viewer are skipped so the card introduces the counterpart, not the viewer.
|
|
16
|
+
* @param introducerName - Optional display name of the introducer. When provided, introducer phrases (e.g., "X introduced you to...") are stripped from the summary to keep the body text focused on match quality.
|
|
17
|
+
* @returns Viewer-centric snippet mentioning the counterpart when possible; if counterpartName is empty, returns reasoning truncated to maxChars. Never null; may be "A suggested connection." when reasoning is empty.
|
|
18
|
+
*/
|
|
19
|
+
export declare function viewerCentricCardSummary(reasoning: string, counterpartName: string, maxChars?: number, viewerName?: string, introducerName?: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Generates a short narrator remark from opportunity reasoning for the narrator chip.
|
|
22
|
+
* Used by the minimal (no-LLM) card path so each card gets a unique remark
|
|
23
|
+
* instead of the same static text.
|
|
24
|
+
*
|
|
25
|
+
* Extracts domain keywords (e.g. "AI", "design", "machine learning") from the
|
|
26
|
+
* reasoning and frames them in a short template like "Shared interest in AI and design."
|
|
27
|
+
*
|
|
28
|
+
* This is a regex-based heuristic — an alternative is OpportunityPresenter.presentHomeCard()
|
|
29
|
+
* which generates narratorRemark via LLM with much higher quality (already used by
|
|
30
|
+
* home.graph.ts and opportunity.discover.ts). See buildMinimalOpportunityCard() in
|
|
31
|
+
* opportunity.tools.ts for the trade-off discussion.
|
|
32
|
+
*
|
|
33
|
+
* @param reasoning - Raw interpretation.reasoning text.
|
|
34
|
+
* @param counterpartName - Display name of the counterpart (stripped from output).
|
|
35
|
+
* @param viewerName - Optional display name of the viewer (stripped from output).
|
|
36
|
+
* @returns A short remark (max ~80 chars) suitable for the narrator chip. Never truncated with "...".
|
|
37
|
+
*/
|
|
38
|
+
export declare function narratorRemarkFromReasoning(reasoning: string, counterpartName: string, viewerName?: string): string;
|
|
39
|
+
//# sourceMappingURL=opportunity.card-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opportunity.card-text.d.ts","sourceRoot":"","sources":["../../src/support/opportunity.card-text.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,QAAQ,GAAE,MAAoC,EAC9C,UAAU,CAAC,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAmGR;AAOD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAiDR"}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Viewer-centric text for opportunity cards.
|
|
3
|
+
* The card is shown to the viewer (logged-in user) and should introduce the
|
|
4
|
+
* counterpart, not describe the viewer to themselves.
|
|
5
|
+
*/
|
|
6
|
+
import { MINIMAL_MAIN_TEXT_MAX_CHARS } from "./opportunity.constants.js";
|
|
7
|
+
import { stripUuids, stripIntroducerMentions } from "./opportunity.sanitize.js";
|
|
8
|
+
/**
|
|
9
|
+
* Splits text into sentences using (?<=[.!?])\s+ (period/exclamation/question followed by whitespace).
|
|
10
|
+
* Note: splits after any such punctuation, including abbreviations like "Dr." or "e.g.".
|
|
11
|
+
*/
|
|
12
|
+
function splitSentences(text) {
|
|
13
|
+
const trimmed = text.trim();
|
|
14
|
+
if (!trimmed)
|
|
15
|
+
return [];
|
|
16
|
+
return trimmed
|
|
17
|
+
.split(/(?<=[.!?])\s+/)
|
|
18
|
+
.map((s) => s.trim())
|
|
19
|
+
.filter(Boolean);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns viewer-centric main text for an opportunity card.
|
|
23
|
+
* Prefers the part of the reasoning that describes the counterpart (the person
|
|
24
|
+
* on the card), so the viewer sees an introduction to the counterpart rather
|
|
25
|
+
* than a description of themselves.
|
|
26
|
+
*
|
|
27
|
+
* @param reasoning - Raw interpretation.reasoning (may describe both parties).
|
|
28
|
+
* @param counterpartName - Display name of the suggested connection (e.g. "Alex Chen").
|
|
29
|
+
* @param maxChars - Max length of returned string (default MINIMAL_MAIN_TEXT_MAX_CHARS).
|
|
30
|
+
* @param viewerName - Optional display name of the viewer (signed-in user). When provided, sentences or prefixes describing the viewer are skipped so the card introduces the counterpart, not the viewer.
|
|
31
|
+
* @param introducerName - Optional display name of the introducer. When provided, introducer phrases (e.g., "X introduced you to...") are stripped from the summary to keep the body text focused on match quality.
|
|
32
|
+
* @returns Viewer-centric snippet mentioning the counterpart when possible; if counterpartName is empty, returns reasoning truncated to maxChars. Never null; may be "A suggested connection." when reasoning is empty.
|
|
33
|
+
*/
|
|
34
|
+
export function viewerCentricCardSummary(reasoning, counterpartName, maxChars = MINIMAL_MAIN_TEXT_MAX_CHARS, viewerName, introducerName) {
|
|
35
|
+
const raw = stripUuids(reasoning);
|
|
36
|
+
if (!raw)
|
|
37
|
+
return "A suggested connection.";
|
|
38
|
+
const name = counterpartName.trim();
|
|
39
|
+
if (!name) {
|
|
40
|
+
let out = raw.length <= maxChars ? raw : raw.slice(0, maxChars) + "...";
|
|
41
|
+
// Strip introducer mentions BEFORE replacing viewer name to avoid "you introduced..." artifacts
|
|
42
|
+
if (introducerName) {
|
|
43
|
+
out = stripIntroducerMentions(out, introducerName);
|
|
44
|
+
}
|
|
45
|
+
out = replaceViewerNameWithYou(out, viewerName);
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
const sentences = splitSentences(raw);
|
|
49
|
+
const nameLower = name.toLowerCase();
|
|
50
|
+
const firstWordOfName = name.split(/\s+/)[0]?.toLowerCase();
|
|
51
|
+
const hasCounterpartName = (s) => s.toLowerCase().includes(nameLower) ||
|
|
52
|
+
(firstWordOfName && firstWordOfName.length > 1 && s.toLowerCase().includes(firstWordOfName));
|
|
53
|
+
const viewer = viewerName?.trim().toLowerCase();
|
|
54
|
+
const viewerFirstWord = viewerName?.trim().split(/\s+/)[0]?.toLowerCase();
|
|
55
|
+
const startsWithViewer = (s) => {
|
|
56
|
+
if (!viewer)
|
|
57
|
+
return false;
|
|
58
|
+
const sl = s.toLowerCase();
|
|
59
|
+
return sl.startsWith(viewer) ||
|
|
60
|
+
(viewerFirstWord && viewerFirstWord.length > 1 && sl.startsWith(viewerFirstWord));
|
|
61
|
+
};
|
|
62
|
+
// When viewerName is provided, prefer sentences that mention the counterpart
|
|
63
|
+
// but do NOT start with the viewer's name.
|
|
64
|
+
if (viewer) {
|
|
65
|
+
// First pass: find a sentence that mentions counterpart and doesn't start with viewer
|
|
66
|
+
const cleanIdx = sentences.findIndex((s) => hasCounterpartName(s) && !startsWithViewer(s));
|
|
67
|
+
if (cleanIdx !== -1) {
|
|
68
|
+
const result = sentences.slice(cleanIdx).join(" ").trim();
|
|
69
|
+
let out = result.length <= maxChars ? result : result.slice(0, maxChars) + "...";
|
|
70
|
+
// Strip introducer mentions BEFORE replacing viewer name to avoid "you introduced..." artifacts
|
|
71
|
+
if (introducerName) {
|
|
72
|
+
out = stripIntroducerMentions(out, introducerName);
|
|
73
|
+
}
|
|
74
|
+
out = replaceViewerNameWithYou(out, viewerName, [name]);
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
// Second pass: sentence mentions counterpart but starts with viewer (compound sentence).
|
|
78
|
+
// Try to extract the counterpart portion after the counterpart's name.
|
|
79
|
+
const compoundIdx = sentences.findIndex((s) => hasCounterpartName(s) && startsWithViewer(s));
|
|
80
|
+
if (compoundIdx !== -1) {
|
|
81
|
+
const sentence = sentences[compoundIdx];
|
|
82
|
+
// Find where the counterpart name appears and extract from there
|
|
83
|
+
// Use case-insensitive Unicode-aware regex so the index is correct
|
|
84
|
+
// even when toLowerCase() changes string length (e.g. Turkish İ→i, German ß→ss).
|
|
85
|
+
const cpMatch = sentence.match(new RegExp(escapeRegex(name), "iu"));
|
|
86
|
+
const cpIdx = cpMatch?.index ?? -1;
|
|
87
|
+
if (cpIdx > 0) {
|
|
88
|
+
const extracted = sentence.slice(cpIdx).trim();
|
|
89
|
+
const rest = sentences.slice(compoundIdx + 1).join(" ").trim();
|
|
90
|
+
const result = rest ? `${extracted} ${rest}` : extracted;
|
|
91
|
+
let out = result.length <= maxChars ? result : result.slice(0, maxChars) + "...";
|
|
92
|
+
// Strip introducer mentions BEFORE replacing viewer name to avoid "you introduced..." artifacts
|
|
93
|
+
if (introducerName) {
|
|
94
|
+
out = stripIntroducerMentions(out, introducerName);
|
|
95
|
+
}
|
|
96
|
+
out = replaceViewerNameWithYou(out, viewerName, [name]);
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Fallback: original logic without viewer awareness
|
|
102
|
+
const idx = sentences.findIndex(hasCounterpartName);
|
|
103
|
+
if (idx === -1) {
|
|
104
|
+
let out = raw.length <= maxChars ? raw : raw.slice(0, maxChars) + "...";
|
|
105
|
+
// Strip introducer mentions BEFORE replacing viewer name to avoid "you introduced..." artifacts
|
|
106
|
+
if (introducerName) {
|
|
107
|
+
out = stripIntroducerMentions(out, introducerName);
|
|
108
|
+
}
|
|
109
|
+
out = replaceViewerNameWithYou(out, viewerName, [name]);
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
const fromCounterpart = sentences.slice(idx).join(" ").trim();
|
|
113
|
+
let out = fromCounterpart.length <= maxChars
|
|
114
|
+
? fromCounterpart
|
|
115
|
+
: fromCounterpart.slice(0, maxChars) + "...";
|
|
116
|
+
// Strip introducer mentions BEFORE replacing viewer name to avoid "you introduced..." artifacts
|
|
117
|
+
if (introducerName) {
|
|
118
|
+
out = stripIntroducerMentions(out, introducerName);
|
|
119
|
+
}
|
|
120
|
+
out = replaceViewerNameWithYou(out, viewerName, [name]);
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
/** Max length for narrator chip text (matches LLM presenter schema). */
|
|
124
|
+
const NARRATOR_MAX_CHARS = 80;
|
|
125
|
+
const FALLBACK_REMARK = "A potential connection worth exploring.";
|
|
126
|
+
/**
|
|
127
|
+
* Generates a short narrator remark from opportunity reasoning for the narrator chip.
|
|
128
|
+
* Used by the minimal (no-LLM) card path so each card gets a unique remark
|
|
129
|
+
* instead of the same static text.
|
|
130
|
+
*
|
|
131
|
+
* Extracts domain keywords (e.g. "AI", "design", "machine learning") from the
|
|
132
|
+
* reasoning and frames them in a short template like "Shared interest in AI and design."
|
|
133
|
+
*
|
|
134
|
+
* This is a regex-based heuristic — an alternative is OpportunityPresenter.presentHomeCard()
|
|
135
|
+
* which generates narratorRemark via LLM with much higher quality (already used by
|
|
136
|
+
* home.graph.ts and opportunity.discover.ts). See buildMinimalOpportunityCard() in
|
|
137
|
+
* opportunity.tools.ts for the trade-off discussion.
|
|
138
|
+
*
|
|
139
|
+
* @param reasoning - Raw interpretation.reasoning text.
|
|
140
|
+
* @param counterpartName - Display name of the counterpart (stripped from output).
|
|
141
|
+
* @param viewerName - Optional display name of the viewer (stripped from output).
|
|
142
|
+
* @returns A short remark (max ~80 chars) suitable for the narrator chip. Never truncated with "...".
|
|
143
|
+
*/
|
|
144
|
+
export function narratorRemarkFromReasoning(reasoning, counterpartName, viewerName) {
|
|
145
|
+
const raw = stripUuids(reasoning).trim();
|
|
146
|
+
if (!raw)
|
|
147
|
+
return FALLBACK_REMARK;
|
|
148
|
+
// Strip all person names from the text so we work only with topics.
|
|
149
|
+
let cleaned = raw;
|
|
150
|
+
for (const name of [counterpartName, viewerName]) {
|
|
151
|
+
if (!name?.trim())
|
|
152
|
+
continue;
|
|
153
|
+
const full = name.trim();
|
|
154
|
+
cleaned = cleaned.replace(new RegExp(escapeRegex(full), "gi"), "").trim();
|
|
155
|
+
const first = full.split(/\s+/)[0];
|
|
156
|
+
if (first && first.length > 1) {
|
|
157
|
+
cleaned = cleaned.replace(new RegExp(`\\b${escapeRegex(first)}\\b`, "gi"), "").trim();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Extract domain/topic noun phrases from the cleaned text.
|
|
161
|
+
// Match multi-word capitalized phrases (e.g. "AI operations toolkit") and
|
|
162
|
+
// known domain terms.
|
|
163
|
+
const domainTerms = extractDomainTerms(cleaned);
|
|
164
|
+
if (domainTerms.length > 0) {
|
|
165
|
+
// Build "Shared interest in X and Y." or "Overlap in X, Y, and Z."
|
|
166
|
+
const prefixes = [
|
|
167
|
+
"Shared interest in",
|
|
168
|
+
"Overlap in",
|
|
169
|
+
"Common ground in",
|
|
170
|
+
"Aligned on",
|
|
171
|
+
"Mutual interest in",
|
|
172
|
+
];
|
|
173
|
+
// Pick prefix deterministically based on first term's char code
|
|
174
|
+
const prefixIdx = domainTerms[0].charCodeAt(0) % prefixes.length;
|
|
175
|
+
const prefix = prefixes[prefixIdx];
|
|
176
|
+
const joined = joinTerms(domainTerms, NARRATOR_MAX_CHARS - prefix.length - 2); // -2 for " " and "."
|
|
177
|
+
const remark = `${prefix} ${joined}.`;
|
|
178
|
+
if (remark.length <= NARRATOR_MAX_CHARS)
|
|
179
|
+
return remark;
|
|
180
|
+
}
|
|
181
|
+
// Fallback: try to extract a short relationship phrase
|
|
182
|
+
const relationshipMatch = cleaned.match(/\b(complementary skills|shared expertise|overlapping intents|similar interests|strong match|mutual fit|potential collaboration|looking for (?:a |an )?[\w\s]{3,20})\b/i);
|
|
183
|
+
if (relationshipMatch) {
|
|
184
|
+
const phrase = relationshipMatch[0];
|
|
185
|
+
const remark = `Spotted ${phrase.toLowerCase()}.`;
|
|
186
|
+
if (remark.length <= NARRATOR_MAX_CHARS)
|
|
187
|
+
return remark;
|
|
188
|
+
}
|
|
189
|
+
return FALLBACK_REMARK;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Extracts domain/topic terms from text by matching known patterns:
|
|
193
|
+
* - Acronyms (AI, ML, UX, API)
|
|
194
|
+
* - Multi-word domain phrases (machine learning, game development)
|
|
195
|
+
* - Capitalized proper nouns that look like topics
|
|
196
|
+
*/
|
|
197
|
+
function extractDomainTerms(text) {
|
|
198
|
+
const seen = new Set();
|
|
199
|
+
const terms = [];
|
|
200
|
+
// Known domain phrases (order matters — longer first)
|
|
201
|
+
const knownPhrases = [
|
|
202
|
+
/\b(machine learning|artificial intelligence|software development|game development|web development|data science|deep learning|natural language processing|computer vision|cloud computing|mobile development|product design|user experience|graphic design|character design|frontend development|backend development|full[- ]stack|smart contracts|visual art|creative writing|content creation|digital marketing|venture capital|angel invest(?:ing|ment)|open source|blockchain|cryptocurrency|decentralized finance|social impact|community building|music production|film(?:making| production)|photography|illustration|animation|3D modeling|startup|co-?founding|entrepreneurship|research|consulting|mentoring|freelanc(?:e|ing))\b/gi,
|
|
203
|
+
/\b(AI|ML|UX|UI|API|NLP|SaaS|DeFi|DevOps|DeSci|NFT|DAO|React|Node|Python|TypeScript|JavaScript|Rust|Solidity|Go|Swift|Kotlin|Figma|Blender|Unity|Unreal)\b/g,
|
|
204
|
+
];
|
|
205
|
+
for (const pattern of knownPhrases) {
|
|
206
|
+
for (const match of text.matchAll(pattern)) {
|
|
207
|
+
const term = match[1] ?? match[0];
|
|
208
|
+
const key = term.toLowerCase();
|
|
209
|
+
if (!seen.has(key)) {
|
|
210
|
+
seen.add(key);
|
|
211
|
+
// Preserve case for short acronyms/proper nouns; lowercase multi-word phrases
|
|
212
|
+
if (term.length <= 5 && /^[A-Z]/.test(term)) {
|
|
213
|
+
terms.push(term); // Keep React, AI, ML, etc. as-is
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
terms.push(key);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// If no known phrases found, look for capitalized multi-word phrases
|
|
222
|
+
// that look like explicit topic references (e.g. "Visual Art", "Smart Contracts").
|
|
223
|
+
// Only accept capitalized words to avoid grabbing meta-language from evaluator reasoning
|
|
224
|
+
// (e.g. "discoverer", "explicitly", "states" which are about the matching process, not topics).
|
|
225
|
+
if (terms.length === 0) {
|
|
226
|
+
// Multi-word capitalized phrases first (e.g. "Visual Art", "Creative Writing")
|
|
227
|
+
const multiWordPattern = /\b([A-Z][a-z]+(?:\s+[A-Z][a-z]+)+)\b/g;
|
|
228
|
+
for (const match of text.matchAll(multiWordPattern)) {
|
|
229
|
+
const term = match[1];
|
|
230
|
+
const key = term.toLowerCase();
|
|
231
|
+
if (!seen.has(key)) {
|
|
232
|
+
seen.add(key);
|
|
233
|
+
terms.push(key);
|
|
234
|
+
if (terms.length >= 3)
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Single capitalized words as last resort (skip common sentence-starters and meta-words)
|
|
239
|
+
if (terms.length === 0) {
|
|
240
|
+
const skipCapitalized = new Set([
|
|
241
|
+
// Articles / conjunctions / prepositions (capitalized at sentence start)
|
|
242
|
+
"the", "and", "but", "for", "from", "with", "without", "between",
|
|
243
|
+
"into", "about", "after", "before", "over", "under", "through",
|
|
244
|
+
// Common sentence starters / pronouns / determiners
|
|
245
|
+
"both", "their", "they", "this", "that", "these", "those",
|
|
246
|
+
"here", "there", "would", "could", "should", "also", "very",
|
|
247
|
+
"one", "another", "other", "each", "some", "many", "most",
|
|
248
|
+
"such", "clear", "high", "good", "well", "just", "even",
|
|
249
|
+
// Generic matching/relationship language
|
|
250
|
+
"strong", "match", "based", "making", "looking", "seeking",
|
|
251
|
+
"connection", "relationship", "opportunity", "overlap",
|
|
252
|
+
"complementary", "potential", "interested", "collaborate",
|
|
253
|
+
// Evaluator meta-language (about the matching process, not topics)
|
|
254
|
+
"intent", "intents", "profile", "user", "users", "person",
|
|
255
|
+
"discoverer", "explicitly", "states", "expressed", "mentioned",
|
|
256
|
+
"indicates", "suggests", "demonstrates", "describes", "involves",
|
|
257
|
+
"inference", "preparatory", "sincerity", "evaluator", "classifier",
|
|
258
|
+
"semantic", "pragmatic", "verification", "reconciliation",
|
|
259
|
+
"assertive", "commissive", "directive", "illocutionary",
|
|
260
|
+
"felicity", "utterance", "detected", "analysis", "confirmed",
|
|
261
|
+
"genuine", "conditions", "determined",
|
|
262
|
+
// Discourse markers
|
|
263
|
+
"particularly", "specifically", "especially", "primarily",
|
|
264
|
+
"overall", "furthermore", "however", "therefore", "moreover",
|
|
265
|
+
]);
|
|
266
|
+
const capWords = text.match(/\b[A-Z][a-z]{2,}\b/g) ?? [];
|
|
267
|
+
for (const w of capWords) {
|
|
268
|
+
const key = w.toLowerCase();
|
|
269
|
+
if (!skipCapitalized.has(key) && !seen.has(key)) {
|
|
270
|
+
seen.add(key);
|
|
271
|
+
terms.push(key);
|
|
272
|
+
if (terms.length >= 3)
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return terms.slice(0, 3); // Max 3 terms
|
|
279
|
+
}
|
|
280
|
+
/** Joins terms into "X, Y, and Z" form, dropping terms if too long. */
|
|
281
|
+
function joinTerms(terms, maxLen) {
|
|
282
|
+
if (terms.length === 1)
|
|
283
|
+
return terms[0];
|
|
284
|
+
// Try all terms first
|
|
285
|
+
for (let count = terms.length; count >= 1; count--) {
|
|
286
|
+
const subset = terms.slice(0, count);
|
|
287
|
+
let joined;
|
|
288
|
+
if (subset.length === 1) {
|
|
289
|
+
joined = subset[0];
|
|
290
|
+
}
|
|
291
|
+
else if (subset.length === 2) {
|
|
292
|
+
joined = `${subset[0]} and ${subset[1]}`;
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
joined = `${subset.slice(0, -1).join(", ")}, and ${subset[subset.length - 1]}`;
|
|
296
|
+
}
|
|
297
|
+
if (joined.length <= maxLen)
|
|
298
|
+
return joined;
|
|
299
|
+
}
|
|
300
|
+
return terms[0].slice(0, maxLen);
|
|
301
|
+
}
|
|
302
|
+
function escapeRegex(s) {
|
|
303
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Replaces viewer's name with "you"/"your" so the card addresses the viewer in second person.
|
|
307
|
+
* Applied to mainText when viewerName is provided.
|
|
308
|
+
* @param otherNames - Other actor names in the card; first-name replacement is
|
|
309
|
+
* skipped when the viewer's first name matches any other actor's first name.
|
|
310
|
+
*/
|
|
311
|
+
function replaceViewerNameWithYou(text, viewerName, otherNames) {
|
|
312
|
+
if (!viewerName?.trim())
|
|
313
|
+
return text;
|
|
314
|
+
const full = viewerName.trim();
|
|
315
|
+
const first = full.split(/\s+/)[0];
|
|
316
|
+
let out = text;
|
|
317
|
+
// Possessive: "Yankı's" → "your", "Yankı Ekin Yüksel's" → "your"
|
|
318
|
+
out = out.replace(new RegExp(`\\b${escapeRegex(full)}'s\\b`, "gi"), "your");
|
|
319
|
+
const otherFirstNames = (otherNames ?? [])
|
|
320
|
+
.map(n => n.trim().split(/\s+/)[0]?.toLowerCase())
|
|
321
|
+
.filter(Boolean);
|
|
322
|
+
const firstNameCollides = first && otherFirstNames.includes(first.toLowerCase());
|
|
323
|
+
if (first && first.length > 1 && !firstNameCollides) {
|
|
324
|
+
out = out.replace(new RegExp(`\\b${escapeRegex(first)}'s\\b`, "gi"), "your");
|
|
325
|
+
}
|
|
326
|
+
// Standalone: full name then first name so we don't break "Yankı Ekin Yüksel"
|
|
327
|
+
out = out.replace(new RegExp(`\\b${escapeRegex(full)}\\b`, "gi"), "you");
|
|
328
|
+
if (first && first.length > 1 && !firstNameCollides) {
|
|
329
|
+
out = out.replace(new RegExp(`\\b${escapeRegex(first)}\\b`, "gi"), "you");
|
|
330
|
+
}
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
//# sourceMappingURL=opportunity.card-text.js.map
|