@memberjunction/conversations-runtime 0.0.1 → 5.41.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.
Files changed (50) hide show
  1. package/README.md +99 -43
  2. package/dist/ConversationsRuntime.d.ts +193 -0
  3. package/dist/ConversationsRuntime.d.ts.map +1 -0
  4. package/dist/ConversationsRuntime.js +268 -0
  5. package/dist/ConversationsRuntime.js.map +1 -0
  6. package/dist/adapters/IActiveTaskTracker.d.ts +49 -0
  7. package/dist/adapters/IActiveTaskTracker.d.ts.map +1 -0
  8. package/dist/adapters/IActiveTaskTracker.js +26 -0
  9. package/dist/adapters/IActiveTaskTracker.js.map +1 -0
  10. package/dist/adapters/INotificationAdapter.d.ts +60 -0
  11. package/dist/adapters/INotificationAdapter.d.ts.map +1 -0
  12. package/dist/adapters/INotificationAdapter.js +45 -0
  13. package/dist/adapters/INotificationAdapter.js.map +1 -0
  14. package/dist/adapters/ISessionsAdapter.d.ts +124 -0
  15. package/dist/adapters/ISessionsAdapter.d.ts.map +1 -0
  16. package/dist/adapters/ISessionsAdapter.js +44 -0
  17. package/dist/adapters/ISessionsAdapter.js.map +1 -0
  18. package/dist/agent-runner/ConversationAgentRunner.d.ts +121 -0
  19. package/dist/agent-runner/ConversationAgentRunner.d.ts.map +1 -0
  20. package/dist/agent-runner/ConversationAgentRunner.js +191 -0
  21. package/dist/agent-runner/ConversationAgentRunner.js.map +1 -0
  22. package/dist/bridge/ConversationBridge.d.ts +93 -0
  23. package/dist/bridge/ConversationBridge.d.ts.map +1 -0
  24. package/dist/bridge/ConversationBridge.js +105 -0
  25. package/dist/bridge/ConversationBridge.js.map +1 -0
  26. package/dist/context/IConversationsRuntimeContext.d.ts +29 -0
  27. package/dist/context/IConversationsRuntimeContext.d.ts.map +1 -0
  28. package/dist/context/IConversationsRuntimeContext.js +21 -0
  29. package/dist/context/IConversationsRuntimeContext.js.map +1 -0
  30. package/dist/default-agent/DefaultAgentResolver.d.ts +87 -0
  31. package/dist/default-agent/DefaultAgentResolver.d.ts.map +1 -0
  32. package/dist/default-agent/DefaultAgentResolver.js +103 -0
  33. package/dist/default-agent/DefaultAgentResolver.js.map +1 -0
  34. package/dist/index.d.ts +22 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +28 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/mentions/MentionParser.d.ts +109 -0
  39. package/dist/mentions/MentionParser.d.ts.map +1 -0
  40. package/dist/mentions/MentionParser.js +276 -0
  41. package/dist/mentions/MentionParser.js.map +1 -0
  42. package/dist/sessions/SessionsObserver.d.ts +87 -0
  43. package/dist/sessions/SessionsObserver.d.ts.map +1 -0
  44. package/dist/sessions/SessionsObserver.js +103 -0
  45. package/dist/sessions/SessionsObserver.js.map +1 -0
  46. package/dist/streaming/ConversationStreaming.d.ts +169 -0
  47. package/dist/streaming/ConversationStreaming.d.ts.map +1 -0
  48. package/dist/streaming/ConversationStreaming.js +355 -0
  49. package/dist/streaming/ConversationStreaming.js.map +1 -0
  50. package/package.json +33 -7
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @fileoverview Default-agent resolution chain.
3
+ *
4
+ * Replaces the hardcoded `Agents.find(a => a.Name === 'Sage')` lookup that previously lived
5
+ * in three places inside `@memberjunction/ng-conversations` with a metadata-driven chain
6
+ * routed through `MJ: Application Settings`.
7
+ *
8
+ * Resolution order on every {@link DefaultAgentResolver.resolve} call:
9
+ *
10
+ * 1. **Explicit `explicitAgentId`** on the call (matches the widget's `[DefaultAgentId]`
11
+ * `@Input` — already works today, preserved here for layering).
12
+ * 2. **App-scoped `MJ: Application Settings`** row (`ApplicationID = <current app>`,
13
+ * `Name = 'Conversations.DefaultAgentID'`, `Value = <agent ID>`).
14
+ * 3. **Global `MJ: Application Settings`** row (`ApplicationID IS NULL`, same name).
15
+ * Ships as a metadata seed pointing at Sage on a fresh install.
16
+ * 4. **Code-const fallback** — `Agents.find(a => a.Name === 'Sage')`. Safety net for
17
+ * installs where the seed was skipped; preserves today's behavior so the system never
18
+ * silently fails to route a turn.
19
+ *
20
+ * Steps 2 and 3 are handled by `ApplicationSettingEngine.GetSetting` in one call — that API
21
+ * already does app-scoped-first / global-fallback resolution internally.
22
+ *
23
+ * @module @memberjunction/conversations-runtime
24
+ */
25
+ import { UUIDsEqual } from '@memberjunction/global';
26
+ import { AIEngineBase } from '@memberjunction/ai-engine-base';
27
+ import { ApplicationSettingEngine } from '@memberjunction/core-entities';
28
+ /**
29
+ * Resolves the default agent for a conversation turn.
30
+ *
31
+ * Usually accessed via `ConversationsRuntime.Instance.DefaultAgent`. Stateless beyond
32
+ * lazy delegation to `ApplicationSettingEngine` and `AIEngineBase`.
33
+ */
34
+ export class DefaultAgentResolver {
35
+ /** Application Setting key consulted in steps 2 and 3. */
36
+ static { this.SETTING_NAME = 'Conversations.DefaultAgentID'; }
37
+ /**
38
+ * Last-resort fallback agent name (step 4). Kept as a constant rather than another
39
+ * setting so the system has a hard floor even if metadata sync has never run on a
40
+ * fresh install — preserves today's "Sage is the default" behavior unconditionally.
41
+ */
42
+ static { this.FALLBACK_AGENT_NAME = 'Sage'; }
43
+ /**
44
+ * Resolve the default agent for this turn. Walks the 4-step chain; throws a descriptive
45
+ * error if every step misses (vs. the previous code path's silent `null` return, which
46
+ * made misconfigurations hard to spot at the call site).
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const agent = await runtime.DefaultAgent.resolve({
51
+ * explicitAgentId: widgetInput.DefaultAgentId, // wins if non-null and matches
52
+ * applicationId: currentAppId, // scopes the settings lookup
53
+ * contextUser: this.ProviderToUse.CurrentUser,
54
+ * provider: this.ProviderToUse,
55
+ * });
56
+ * ```
57
+ */
58
+ async resolve(options = {}) {
59
+ const { explicitAgentId, applicationId, contextUser, provider } = options;
60
+ // Lazy-config the engines we depend on. Both `Config(false, ...)` calls are
61
+ // idempotent — first caller pays the load cost, others are cache hits.
62
+ await AIEngineBase.Instance.Config(false, contextUser, provider);
63
+ await ApplicationSettingEngine.Instance.Config(false, contextUser, provider);
64
+ // Step 1: explicit ID wins if it resolves to a real agent.
65
+ if (explicitAgentId) {
66
+ const explicit = this.findAgentById(explicitAgentId);
67
+ if (explicit)
68
+ return explicit;
69
+ // If an explicit ID was supplied but doesn't resolve, fall through — this is
70
+ // surprising enough to warrant a warning but not surprising enough to throw
71
+ // (the rest of the chain may still produce a sensible default).
72
+ console.warn(`DefaultAgentResolver: explicitAgentId "${explicitAgentId}" did not match any known agent — falling through to settings chain.`);
73
+ }
74
+ // Steps 2 + 3: Application Setting resolution. `GetSetting` already does
75
+ // app-scoped-first / global-fallback in one call.
76
+ const settingValue = ApplicationSettingEngine.Instance.GetSetting(DefaultAgentResolver.SETTING_NAME, applicationId ?? undefined);
77
+ if (settingValue) {
78
+ const fromSetting = this.findAgentById(settingValue);
79
+ if (fromSetting)
80
+ return fromSetting;
81
+ console.warn(`DefaultAgentResolver: Application Setting "${DefaultAgentResolver.SETTING_NAME}" resolved to "${settingValue}" but no matching agent was found — falling through to code-const fallback.`);
82
+ }
83
+ // Step 4: code-const fallback. Find the agent named `Sage` and return it.
84
+ const fallback = AIEngineBase.Instance.Agents.find((a) => a.Name === DefaultAgentResolver.FALLBACK_AGENT_NAME);
85
+ if (fallback)
86
+ return fallback;
87
+ // No agent at any layer — descriptive error so the call site sees the misconfiguration.
88
+ throw new Error(`DefaultAgentResolver: could not resolve a default conversation manager agent. ` +
89
+ `Tried (1) explicitAgentId=${explicitAgentId ?? 'null'}, ` +
90
+ `(2)+(3) Application Setting "${DefaultAgentResolver.SETTING_NAME}" (applicationId=${applicationId ?? 'null'}) = "${settingValue ?? 'undefined'}", ` +
91
+ `(4) code-const fallback agent name = "${DefaultAgentResolver.FALLBACK_AGENT_NAME}". ` +
92
+ `Configure the Application Setting or seed the fallback agent.`);
93
+ }
94
+ /**
95
+ * Find an agent by ID from the AIEngineBase cache. Returns `undefined` if not found.
96
+ * Uses {@link UUIDsEqual} per the standing rule about comparing UUIDs across
97
+ * SQL Server / Postgres (case differences would silently miss).
98
+ */
99
+ findAgentById(id) {
100
+ return AIEngineBase.Instance.Agents.find((a) => UUIDsEqual(a.ID, id));
101
+ }
102
+ }
103
+ //# sourceMappingURL=DefaultAgentResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultAgentResolver.js","sourceRoot":"","sources":["../../src/default-agent/DefaultAgentResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAE9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AA4BzE;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IAC7B,0DAA0D;aACnC,iBAAY,GAAG,8BAA8B,CAAC;IAErE;;;;OAIG;aACoB,wBAAmB,GAAG,MAAM,CAAC;IAEpD;;;;;;;;;;;;;;OAcG;IACI,KAAK,CAAC,OAAO,CAAC,UAAsC,EAAE;QACzD,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAE1E,4EAA4E;QAC5E,uEAAuE;QACvE,MAAM,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QACjE,MAAM,wBAAwB,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAE7E,2DAA2D;QAC3D,IAAI,eAAe,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;YACrD,IAAI,QAAQ;gBAAE,OAAO,QAAQ,CAAC;YAC9B,6EAA6E;YAC7E,4EAA4E;YAC5E,gEAAgE;YAChE,OAAO,CAAC,IAAI,CACR,0CAA0C,eAAe,sEAAsE,CAClI,CAAC;QACN,CAAC;QAED,yEAAyE;QACzE,kDAAkD;QAClD,MAAM,YAAY,GAAG,wBAAwB,CAAC,QAAQ,CAAC,UAAU,CAC7D,oBAAoB,CAAC,YAAY,EACjC,aAAa,IAAI,SAAS,CAC7B,CAAC;QACF,IAAI,YAAY,EAAE,CAAC;YACf,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YACrD,IAAI,WAAW;gBAAE,OAAO,WAAW,CAAC;YACpC,OAAO,CAAC,IAAI,CACR,8CAA8C,oBAAoB,CAAC,YAAY,kBAAkB,YAAY,6EAA6E,CAC7L,CAAC;QACN,CAAC;QAED,0EAA0E;QAC1E,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAC9C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,oBAAoB,CAAC,mBAAmB,CAC7D,CAAC;QACF,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAE9B,wFAAwF;QACxF,MAAM,IAAI,KAAK,CACX,gFAAgF;YAC5E,6BAA6B,eAAe,IAAI,MAAM,IAAI;YAC1D,gCAAgC,oBAAoB,CAAC,YAAY,oBAAoB,aAAa,IAAI,MAAM,QAAQ,YAAY,IAAI,WAAW,KAAK;YACpJ,yCAAyC,oBAAoB,CAAC,mBAAmB,KAAK;YACtF,+DAA+D,CACtE,CAAC;IACN,CAAC;IAED;;;;OAIG;IACK,aAAa,CAAC,EAAU;QAC5B,OAAO,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview Public entry point for `@memberjunction/conversations-runtime`.
3
+ *
4
+ * Pure-TypeScript, framework-agnostic runtime for MemberJunction conversational AI
5
+ * experiences. Consumable from browser (Angular widget, React, Vue, Node-side workers)
6
+ * or server (Node tests, CLI tools).
7
+ *
8
+ * @module @memberjunction/conversations-runtime
9
+ */
10
+ export { ConversationsRuntime } from './ConversationsRuntime.js';
11
+ export { MentionParser, type Mention, type MentionParseResult } from './mentions/MentionParser.js';
12
+ export { ConversationBridge, type ConversationSwitchEvent, type ConversationDeepLink, } from './bridge/ConversationBridge.js';
13
+ export { DefaultAgentResolver, type DefaultAgentResolveOptions, } from './default-agent/DefaultAgentResolver.js';
14
+ export { SessionsObserver, type SessionLifecycleEvent, type SessionChannelState, type SessionEndReason, } from './sessions/SessionsObserver.js';
15
+ export { ConversationStreaming, type CompletionEvent, type MessageProgressUpdate, type MessageProgressMetadata, type MessageProgressCallback, type StreamingConnectionStatus, } from './streaming/ConversationStreaming.js';
16
+ export { ConversationAgentRunner, type ProcessMessageInput, } from './agent-runner/ConversationAgentRunner.js';
17
+ export { type INotificationAdapter, type NotificationLevel, ConsoleNotificationAdapter, } from './adapters/INotificationAdapter.js';
18
+ export { type IActiveTaskTracker, NoOpActiveTaskTracker, } from './adapters/IActiveTaskTracker.js';
19
+ export { type ISessionsAdapter, NoOpSessionsAdapter, } from './adapters/ISessionsAdapter.js';
20
+ export type { IConversationsRuntimeContext } from './context/IConversationsRuntimeContext.js';
21
+ export { ClientToolRegistry, type ClientToolDefinition, type ClientToolHandler, } from '@memberjunction/ai-agent-client';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,KAAK,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EACH,kBAAkB,EAClB,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,GAC5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACH,oBAAoB,EACpB,KAAK,0BAA0B,GAClC,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACH,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACxB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACH,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,GACjC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACH,uBAAuB,EACvB,KAAK,mBAAmB,GAC3B,MAAM,wCAAwC,CAAC;AAGhD,OAAO,EACH,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,0BAA0B,GAC7B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACH,KAAK,kBAAkB,EACvB,qBAAqB,GACxB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACH,KAAK,gBAAgB,EACrB,mBAAmB,GACtB,MAAM,6BAA6B,CAAC;AAIrC,YAAY,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AAM3F,OAAO,EACH,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACzB,MAAM,iCAAiC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @fileoverview Public entry point for `@memberjunction/conversations-runtime`.
3
+ *
4
+ * Pure-TypeScript, framework-agnostic runtime for MemberJunction conversational AI
5
+ * experiences. Consumable from browser (Angular widget, React, Vue, Node-side workers)
6
+ * or server (Node tests, CLI tools).
7
+ *
8
+ * @module @memberjunction/conversations-runtime
9
+ */
10
+ // Top-level runtime singleton
11
+ export { ConversationsRuntime } from './ConversationsRuntime.js';
12
+ // Sub-components and their public types
13
+ export { MentionParser } from './mentions/MentionParser.js';
14
+ export { ConversationBridge, } from './bridge/ConversationBridge.js';
15
+ export { DefaultAgentResolver, } from './default-agent/DefaultAgentResolver.js';
16
+ export { SessionsObserver, } from './sessions/SessionsObserver.js';
17
+ export { ConversationStreaming, } from './streaming/ConversationStreaming.js';
18
+ export { ConversationAgentRunner, } from './agent-runner/ConversationAgentRunner.js';
19
+ // Adapter interfaces + defaults
20
+ export { ConsoleNotificationAdapter, } from './adapters/INotificationAdapter.js';
21
+ export { NoOpActiveTaskTracker, } from './adapters/IActiveTaskTracker.js';
22
+ export { NoOpSessionsAdapter, } from './adapters/ISessionsAdapter.js';
23
+ // Re-export `ClientToolRegistry` from `@memberjunction/ai-agent-client` so consumers
24
+ // can use the runtime's tool layer (`runtime.Tools`) without importing a second package
25
+ // just to know the type. The class itself is owned by `ai-agent-client` — we are NOT
26
+ // reimplementing it, just exposing the established surface here.
27
+ export { ClientToolRegistry, } from '@memberjunction/ai-agent-client';
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8BAA8B;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,wCAAwC;AACxC,OAAO,EAAE,aAAa,EAAyC,MAAM,0BAA0B,CAAC;AAChG,OAAO,EACH,kBAAkB,GAGrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACH,oBAAoB,GAEvB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACH,gBAAgB,GAInB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACH,qBAAqB,GAMxB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACH,uBAAuB,GAE1B,MAAM,wCAAwC,CAAC;AAEhD,gCAAgC;AAChC,OAAO,EAGH,0BAA0B,GAC7B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEH,qBAAqB,GACxB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEH,mBAAmB,GACtB,MAAM,6BAA6B,CAAC;AAMrC,qFAAqF;AACrF,wFAAwF;AACxF,qFAAqF;AACrF,iEAAiE;AACjE,OAAO,EACH,kBAAkB,GAGrB,MAAM,iCAAiC,CAAC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @fileoverview Pure-TypeScript mention parser for conversation message text.
3
+ *
4
+ * Ported from `@memberjunction/ng-conversations/src/lib/services/mention-parser.service.ts`
5
+ * — the original was already pure string + regex logic, the only Angular bit was the
6
+ * `@Injectable()` decorator. Stripped that, kept everything else identical.
7
+ *
8
+ * Supports both formats currently in use in MJ conversations:
9
+ * - **JSON format** (new): `@{"type":"agent","id":"<uuid>","name":"Sage","configId":"<uuid>"}`
10
+ * - **Legacy text format**: `@AgentName` or `@"Agent Name With Spaces"`
11
+ *
12
+ * @module @memberjunction/conversations-runtime
13
+ */
14
+ import { MJAIAgentEntityExtended } from '@memberjunction/ai-core-plus';
15
+ import { UserInfo } from '@memberjunction/core';
16
+ /** A single parsed mention. */
17
+ export interface Mention {
18
+ type: 'agent' | 'user' | 'entity';
19
+ id: string;
20
+ name: string;
21
+ /** Configuration preset ID — agent mentions only. */
22
+ configurationId?: string;
23
+ }
24
+ /** Result of parsing all mentions out of a message. */
25
+ export interface MentionParseResult {
26
+ /** All mentions, in order of appearance. */
27
+ mentions: Mention[];
28
+ /** First agent mention (if any). Conventionally the routing target. */
29
+ agentMention: Mention | null;
30
+ /** All user mentions. */
31
+ userMentions: Mention[];
32
+ /** All entity mentions (`#Entity` / `@{"type":"entity",…}`). */
33
+ entityMentions: Mention[];
34
+ }
35
+ /**
36
+ * Parses `@`-mentions out of conversation message text.
37
+ *
38
+ * Pure logic — no framework deps, no I/O, no observable state. Safe to call from
39
+ * browser, Node, tests, or anywhere TypeScript runs.
40
+ *
41
+ * Consumers usually access this via `ConversationsRuntime.Instance.Mentions`.
42
+ */
43
+ export declare class MentionParser {
44
+ /** Matches JSON-encoded mentions like `@{"type":"agent","id":"…","name":"…"}`. */
45
+ private readonly JSON_MENTION_REGEX;
46
+ /** Matches legacy text mentions — quoted names with spaces or unquoted names. */
47
+ private readonly LEGACY_MENTION_REGEX;
48
+ /**
49
+ * Parse every mention out of the supplied text.
50
+ *
51
+ * Tries JSON format first; if no JSON mentions are present, falls back to the legacy
52
+ * text format and resolves names against `availableAgents` / `availableUsers`.
53
+ *
54
+ * @param text Message text to parse
55
+ * @param availableAgents Agents to resolve legacy `@Name` references against
56
+ * @param availableUsers Optional users to resolve legacy `@Name` references against
57
+ * @returns Parsed mentions with agent/user separation
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const result = parser.parseMentions(
62
+ * '@Sage help me with this',
63
+ * AIEngineBase.Instance.Agents
64
+ * );
65
+ * if (result.agentMention) {
66
+ * // Route the message to result.agentMention.id
67
+ * }
68
+ * ```
69
+ */
70
+ parseMentions(text: string, availableAgents: MJAIAgentEntityExtended[], availableUsers?: UserInfo[]): MentionParseResult;
71
+ /**
72
+ * Validate every mention in `text`. Returns an array of mention names that could not be
73
+ * resolved to a known agent or user.
74
+ */
75
+ validateMentions(text: string, availableAgents: MJAIAgentEntityExtended[], availableUsers?: UserInfo[]): string[];
76
+ /**
77
+ * Extract every raw mention name from `text` (no resolution against agents/users).
78
+ */
79
+ extractMentionNames(text: string): string[];
80
+ /**
81
+ * Rewrite mentions in `text` to a canonical `@Name` format using the proper casing
82
+ * from `mentions`. Useful when normalizing user-typed mentions before storage or display.
83
+ */
84
+ formatMentions(text: string, mentions: Mention[]): string;
85
+ /**
86
+ * Convert a message containing JSON-encoded mentions to plain text — `@{…}` blocks
87
+ * become simple `@Name` strings. Delegates to
88
+ * {@link ConversationUtility.ToPlainText} which is the canonical implementation.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * // Input: '@{"type":"agent","id":"123","name":"Sage"} help me'
93
+ * // Output: '@Sage help me'
94
+ * ```
95
+ */
96
+ toPlainText(text: string, agents?: MJAIAgentEntityExtended[], users?: UserInfo[]): string;
97
+ /**
98
+ * Find an agent by name (case-insensitive). Tries exact match first, then starts-with.
99
+ * Explicitly does NOT do a contains-match — that would be ambiguous when multiple agent
100
+ * names share a substring (`@Agent` matching `Marketing Agent`, `Data Agent`, …).
101
+ */
102
+ private findAgent;
103
+ /**
104
+ * Find a user by name (case-insensitive). Tries exact name, email, then starts-with name.
105
+ * Same no-contains-match rule as {@link findAgent} for consistency.
106
+ */
107
+ private findUser;
108
+ }
109
+ //# sourceMappingURL=MentionParser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentionParser.d.ts","sourceRoot":"","sources":["../../src/mentions/MentionParser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,uBAAuB,EAAuB,MAAM,8BAA8B,CAAC;AAC5F,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,+BAA+B;AAC/B,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,uDAAuD;AACvD,MAAM,WAAW,kBAAkB;IAC/B,4CAA4C;IAC5C,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,uEAAuE;IACvE,YAAY,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,yBAAyB;IACzB,YAAY,EAAE,OAAO,EAAE,CAAC;IACxB,gEAAgE;IAChE,cAAc,EAAE,OAAO,EAAE,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,qBAAa,aAAa;IACtB,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAiB;IAEpD,iFAAiF;IACjF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAwB;IAE7D;;;;;;;;;;;;;;;;;;;;;OAqBG;IACI,aAAa,CAChB,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,uBAAuB,EAAE,EAC1C,cAAc,CAAC,EAAE,QAAQ,EAAE,GAC5B,kBAAkB;IA6ErB;;;OAGG;IACI,gBAAgB,CACnB,IAAI,EAAE,MAAM,EACZ,eAAe,EAAE,uBAAuB,EAAE,EAC1C,cAAc,CAAC,EAAE,QAAQ,EAAE,GAC5B,MAAM,EAAE;IAoDX;;OAEG;IACI,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAsBlD;;;OAGG;IACI,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM;IAkBhE;;;;;;;;;;OAUG;IACI,WAAW,CACd,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,uBAAuB,EAAE,EAClC,KAAK,CAAC,EAAE,QAAQ,EAAE,GACnB,MAAM;IAkBT;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAiBjB;;;OAGG;IACH,OAAO,CAAC,QAAQ;CAenB"}
@@ -0,0 +1,276 @@
1
+ /**
2
+ * @fileoverview Pure-TypeScript mention parser for conversation message text.
3
+ *
4
+ * Ported from `@memberjunction/ng-conversations/src/lib/services/mention-parser.service.ts`
5
+ * — the original was already pure string + regex logic, the only Angular bit was the
6
+ * `@Injectable()` decorator. Stripped that, kept everything else identical.
7
+ *
8
+ * Supports both formats currently in use in MJ conversations:
9
+ * - **JSON format** (new): `@{"type":"agent","id":"<uuid>","name":"Sage","configId":"<uuid>"}`
10
+ * - **Legacy text format**: `@AgentName` or `@"Agent Name With Spaces"`
11
+ *
12
+ * @module @memberjunction/conversations-runtime
13
+ */
14
+ import { ConversationUtility } from '@memberjunction/ai-core-plus';
15
+ /**
16
+ * Parses `@`-mentions out of conversation message text.
17
+ *
18
+ * Pure logic — no framework deps, no I/O, no observable state. Safe to call from
19
+ * browser, Node, tests, or anywhere TypeScript runs.
20
+ *
21
+ * Consumers usually access this via `ConversationsRuntime.Instance.Mentions`.
22
+ */
23
+ export class MentionParser {
24
+ constructor() {
25
+ /** Matches JSON-encoded mentions like `@{"type":"agent","id":"…","name":"…"}`. */
26
+ this.JSON_MENTION_REGEX = /@\{[^}]+\}/g;
27
+ /** Matches legacy text mentions — quoted names with spaces or unquoted names. */
28
+ this.LEGACY_MENTION_REGEX = /@"([^"]+)"|@(\S+)/g;
29
+ }
30
+ /**
31
+ * Parse every mention out of the supplied text.
32
+ *
33
+ * Tries JSON format first; if no JSON mentions are present, falls back to the legacy
34
+ * text format and resolves names against `availableAgents` / `availableUsers`.
35
+ *
36
+ * @param text Message text to parse
37
+ * @param availableAgents Agents to resolve legacy `@Name` references against
38
+ * @param availableUsers Optional users to resolve legacy `@Name` references against
39
+ * @returns Parsed mentions with agent/user separation
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const result = parser.parseMentions(
44
+ * '@Sage help me with this',
45
+ * AIEngineBase.Instance.Agents
46
+ * );
47
+ * if (result.agentMention) {
48
+ * // Route the message to result.agentMention.id
49
+ * }
50
+ * ```
51
+ */
52
+ parseMentions(text, availableAgents, availableUsers) {
53
+ const mentions = [];
54
+ // First, try to parse JSON mentions (new format)
55
+ const jsonMatches = Array.from(text.matchAll(this.JSON_MENTION_REGEX));
56
+ for (const match of jsonMatches) {
57
+ try {
58
+ // Extract JSON string (remove @ prefix)
59
+ const jsonStr = match[0].substring(1);
60
+ const mentionData = JSON.parse(jsonStr);
61
+ // Validate required fields
62
+ if (mentionData.type && mentionData.id && mentionData.name) {
63
+ const mention = {
64
+ type: mentionData.type,
65
+ id: mentionData.id,
66
+ name: mentionData.name,
67
+ };
68
+ // Add configuration if present (for agents)
69
+ if (mentionData.configId) {
70
+ mention.configurationId = mentionData.configId;
71
+ }
72
+ mentions.push(mention);
73
+ }
74
+ }
75
+ catch (error) {
76
+ console.warn('MentionParser: failed to parse JSON mention:', match[0], error);
77
+ // Continue to next match
78
+ }
79
+ }
80
+ // If no JSON mentions found, fall back to legacy text format
81
+ if (mentions.length === 0) {
82
+ const legacyMatches = Array.from(text.matchAll(this.LEGACY_MENTION_REGEX));
83
+ for (const match of legacyMatches) {
84
+ // Extract the mention name (either quoted or unquoted)
85
+ const mentionName = match[1] || match[2];
86
+ if (!mentionName)
87
+ continue;
88
+ // Try to match against agents first
89
+ const agent = this.findAgent(mentionName, availableAgents);
90
+ if (agent) {
91
+ mentions.push({
92
+ type: 'agent',
93
+ id: agent.ID,
94
+ name: agent.Name || 'Unknown',
95
+ });
96
+ continue;
97
+ }
98
+ // Try to match against users
99
+ if (availableUsers) {
100
+ const user = this.findUser(mentionName, availableUsers);
101
+ if (user) {
102
+ mentions.push({
103
+ type: 'user',
104
+ id: user.ID,
105
+ name: user.Name,
106
+ });
107
+ }
108
+ }
109
+ }
110
+ }
111
+ // Extract first agent mention, all user mentions, and all entity mentions.
112
+ // Entity mentions arrive as JSON (`@{"type":"entity",…}`) from the editor and are
113
+ // resolved against the target entity downstream (e.g. Skip's EntityMentionResolver).
114
+ const agentMention = mentions.find((m) => m.type === 'agent') || null;
115
+ const userMentions = mentions.filter((m) => m.type === 'user');
116
+ const entityMentions = mentions.filter((m) => m.type === 'entity');
117
+ return { mentions, agentMention, userMentions, entityMentions };
118
+ }
119
+ /**
120
+ * Validate every mention in `text`. Returns an array of mention names that could not be
121
+ * resolved to a known agent or user.
122
+ */
123
+ validateMentions(text, availableAgents, availableUsers) {
124
+ const invalidMentions = [];
125
+ // Check JSON mentions first
126
+ const jsonMatches = Array.from(text.matchAll(this.JSON_MENTION_REGEX));
127
+ if (jsonMatches.length > 0) {
128
+ for (const match of jsonMatches) {
129
+ try {
130
+ const jsonStr = match[0].substring(1);
131
+ const mentionData = JSON.parse(jsonStr);
132
+ const mentionName = mentionData.name;
133
+ if (mentionData.type === 'agent') {
134
+ const isAgent = this.findAgent(mentionName, availableAgents) !== null;
135
+ if (!isAgent) {
136
+ invalidMentions.push(mentionName);
137
+ }
138
+ }
139
+ else if (mentionData.type === 'user') {
140
+ const isUser = availableUsers
141
+ ? this.findUser(mentionName, availableUsers) !== null
142
+ : false;
143
+ if (!isUser) {
144
+ invalidMentions.push(mentionName);
145
+ }
146
+ }
147
+ }
148
+ catch (error) {
149
+ // Invalid JSON mention
150
+ invalidMentions.push(match[0]);
151
+ }
152
+ }
153
+ }
154
+ else {
155
+ // Fall back to legacy format
156
+ const matches = Array.from(text.matchAll(this.LEGACY_MENTION_REGEX));
157
+ for (const match of matches) {
158
+ const mentionName = match[1] || match[2];
159
+ if (!mentionName)
160
+ continue;
161
+ const isAgent = this.findAgent(mentionName, availableAgents) !== null;
162
+ const isUser = availableUsers
163
+ ? this.findUser(mentionName, availableUsers) !== null
164
+ : false;
165
+ if (!isAgent && !isUser) {
166
+ invalidMentions.push(mentionName);
167
+ }
168
+ }
169
+ }
170
+ return invalidMentions;
171
+ }
172
+ /**
173
+ * Extract every raw mention name from `text` (no resolution against agents/users).
174
+ */
175
+ extractMentionNames(text) {
176
+ // Check JSON mentions first
177
+ const jsonMatches = Array.from(text.matchAll(this.JSON_MENTION_REGEX));
178
+ if (jsonMatches.length > 0) {
179
+ return jsonMatches
180
+ .map((match) => {
181
+ try {
182
+ const jsonStr = match[0].substring(1);
183
+ const mentionData = JSON.parse(jsonStr);
184
+ return mentionData.name;
185
+ }
186
+ catch (error) {
187
+ return '';
188
+ }
189
+ })
190
+ .filter(Boolean);
191
+ }
192
+ // Fall back to legacy format
193
+ const matches = Array.from(text.matchAll(this.LEGACY_MENTION_REGEX));
194
+ return matches.map((match) => match[1] || match[2]).filter(Boolean);
195
+ }
196
+ /**
197
+ * Rewrite mentions in `text` to a canonical `@Name` format using the proper casing
198
+ * from `mentions`. Useful when normalizing user-typed mentions before storage or display.
199
+ */
200
+ formatMentions(text, mentions) {
201
+ let formattedText = text;
202
+ for (const mention of mentions) {
203
+ // Find the mention in the text and replace with proper name
204
+ const patterns = [
205
+ new RegExp(`@"${mention.name}"`, 'gi'),
206
+ new RegExp(`@${mention.name.replace(/\s+/g, '\\s*')}`, 'gi'),
207
+ ];
208
+ for (const pattern of patterns) {
209
+ formattedText = formattedText.replace(pattern, `@${mention.name}`);
210
+ }
211
+ }
212
+ return formattedText;
213
+ }
214
+ /**
215
+ * Convert a message containing JSON-encoded mentions to plain text — `@{…}` blocks
216
+ * become simple `@Name` strings. Delegates to
217
+ * {@link ConversationUtility.ToPlainText} which is the canonical implementation.
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * // Input: '@{"type":"agent","id":"123","name":"Sage"} help me'
222
+ * // Output: '@Sage help me'
223
+ * ```
224
+ */
225
+ toPlainText(text, agents, users) {
226
+ if (!text)
227
+ return '';
228
+ // Convert agents to the AgentInfo format expected by ConversationUtility
229
+ const agentInfos = agents?.map((a) => ({
230
+ ID: a.ID,
231
+ Name: a.Name || 'Unknown',
232
+ }));
233
+ // Convert users to the UserInfo format expected by ConversationUtility
234
+ const userInfos = users?.map((u) => ({
235
+ ID: u.ID,
236
+ Name: u.Name,
237
+ }));
238
+ return ConversationUtility.ToPlainText(text, agentInfos, userInfos);
239
+ }
240
+ /**
241
+ * Find an agent by name (case-insensitive). Tries exact match first, then starts-with.
242
+ * Explicitly does NOT do a contains-match — that would be ambiguous when multiple agent
243
+ * names share a substring (`@Agent` matching `Marketing Agent`, `Data Agent`, …).
244
+ */
245
+ findAgent(name, agents) {
246
+ // Remove trailing punctuation and trim
247
+ const cleanName = name.replace(/[.,;!?]+$/, '').trim();
248
+ const lowerName = cleanName.toLowerCase();
249
+ // Try exact match first
250
+ let agent = agents.find((a) => (a.Name?.toLowerCase() || '') === lowerName);
251
+ if (agent)
252
+ return agent;
253
+ // Try starts-with match
254
+ agent = agents.find((a) => (a.Name?.toLowerCase() || '').startsWith(lowerName));
255
+ return agent ?? null;
256
+ }
257
+ /**
258
+ * Find a user by name (case-insensitive). Tries exact name, email, then starts-with name.
259
+ * Same no-contains-match rule as {@link findAgent} for consistency.
260
+ */
261
+ findUser(name, users) {
262
+ const lowerName = name.toLowerCase().trim();
263
+ // Try exact match first
264
+ let user = users.find((u) => u.Name.toLowerCase() === lowerName);
265
+ if (user)
266
+ return user;
267
+ // Try email match
268
+ user = users.find((u) => u.Email?.toLowerCase() === lowerName);
269
+ if (user)
270
+ return user;
271
+ // Try starts-with match
272
+ user = users.find((u) => u.Name.toLowerCase().startsWith(lowerName));
273
+ return user ?? null;
274
+ }
275
+ }
276
+ //# sourceMappingURL=MentionParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentionParser.js","sourceRoot":"","sources":["../../src/mentions/MentionParser.ts"],"names":[],"mappings":"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"}