@memberjunction/ai-agents 5.42.0 → 5.44.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/README.md +10 -0
- package/dist/DuplicateReasoningAgentProvider.d.ts +35 -0
- package/dist/DuplicateReasoningAgentProvider.d.ts.map +1 -0
- package/dist/DuplicateReasoningAgentProvider.js +95 -0
- package/dist/DuplicateReasoningAgentProvider.js.map +1 -0
- package/dist/MJAIAgentRequestEntityServer.d.ts +7 -0
- package/dist/MJAIAgentRequestEntityServer.d.ts.map +1 -1
- package/dist/MJAIAgentRequestEntityServer.js +28 -1
- package/dist/MJAIAgentRequestEntityServer.js.map +1 -1
- package/dist/SkillImportExportService.d.ts +63 -0
- package/dist/SkillImportExportService.d.ts.map +1 -0
- package/dist/SkillImportExportService.js +148 -0
- package/dist/SkillImportExportService.js.map +1 -0
- package/dist/SkillMarkdownConverter.d.ts +82 -0
- package/dist/SkillMarkdownConverter.d.ts.map +1 -0
- package/dist/SkillMarkdownConverter.js +145 -0
- package/dist/SkillMarkdownConverter.js.map +1 -0
- package/dist/agent-types/flow-agent-type.d.ts.map +1 -1
- package/dist/agent-types/flow-agent-type.js +10 -2
- package/dist/agent-types/flow-agent-type.js.map +1 -1
- package/dist/agent-types/loop-agent-response-type.d.ts +17 -2
- package/dist/agent-types/loop-agent-response-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-response-type.js.map +1 -1
- package/dist/agent-types/loop-agent-type.d.ts.map +1 -1
- package/dist/agent-types/loop-agent-type.js +33 -1
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/base-agent.d.ts +373 -12
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +1019 -78
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/memory-manager-agent.d.ts +39 -0
- package/dist/memory-manager-agent.d.ts.map +1 -1
- package/dist/memory-manager-agent.js +118 -5
- package/dist/memory-manager-agent.js.map +1 -1
- package/dist/operations/AISkillMarkdownOperations.d.ts +11 -0
- package/dist/operations/AISkillMarkdownOperations.d.ts.map +1 -0
- package/dist/operations/AISkillMarkdownOperations.js +57 -0
- package/dist/operations/AISkillMarkdownOperations.js.map +1 -0
- package/dist/prompt-component-resolver.d.ts +73 -0
- package/dist/prompt-component-resolver.d.ts.map +1 -0
- package/dist/prompt-component-resolver.js +166 -0
- package/dist/prompt-component-resolver.js.map +1 -0
- package/dist/realtime/agent-media-library.d.ts +65 -0
- package/dist/realtime/agent-media-library.d.ts.map +1 -0
- package/dist/realtime/agent-media-library.js +160 -0
- package/dist/realtime/agent-media-library.js.map +1 -0
- package/dist/realtime/bridge-room-transcript-sink.d.ts +5 -0
- package/dist/realtime/bridge-room-transcript-sink.d.ts.map +1 -1
- package/dist/realtime/bridge-room-transcript-sink.js +25 -1
- package/dist/realtime/bridge-room-transcript-sink.js.map +1 -1
- package/dist/realtime/client-context-channel-server.d.ts +59 -0
- package/dist/realtime/client-context-channel-server.d.ts.map +1 -0
- package/dist/realtime/client-context-channel-server.js +78 -0
- package/dist/realtime/client-context-channel-server.js.map +1 -0
- package/dist/realtime/media-channel-server.d.ts +73 -0
- package/dist/realtime/media-channel-server.d.ts.map +1 -0
- package/dist/realtime/media-channel-server.js +145 -0
- package/dist/realtime/media-channel-server.js.map +1 -0
- package/dist/realtime/realtime-channel-server-data-context.d.ts +42 -0
- package/dist/realtime/realtime-channel-server-data-context.d.ts.map +1 -0
- package/dist/realtime/realtime-channel-server-data-context.js +29 -0
- package/dist/realtime/realtime-channel-server-data-context.js.map +1 -0
- package/dist/realtime/realtime-channel-server-host.d.ts.map +1 -1
- package/dist/realtime/realtime-channel-server-host.js +8 -2
- package/dist/realtime/realtime-channel-server-host.js.map +1 -1
- package/dist/realtime/realtime-client-session-service.d.ts +85 -5
- package/dist/realtime/realtime-client-session-service.d.ts.map +1 -1
- package/dist/realtime/realtime-client-session-service.js +234 -25
- package/dist/realtime/realtime-client-session-service.js.map +1 -1
- package/dist/realtime/realtime-coagent-config.d.ts +161 -3
- package/dist/realtime/realtime-coagent-config.d.ts.map +1 -1
- package/dist/realtime/realtime-coagent-config.js +241 -6
- package/dist/realtime/realtime-coagent-config.js.map +1 -1
- package/dist/realtime/realtime-recording-capture.d.ts +125 -0
- package/dist/realtime/realtime-recording-capture.d.ts.map +1 -0
- package/dist/realtime/realtime-recording-capture.js +317 -0
- package/dist/realtime/realtime-recording-capture.js.map +1 -0
- package/dist/realtime/realtime-recording-store.d.ts +105 -0
- package/dist/realtime/realtime-recording-store.d.ts.map +1 -0
- package/dist/realtime/realtime-recording-store.js +216 -0
- package/dist/realtime/realtime-recording-store.js.map +1 -0
- package/dist/realtime/realtime-session-runner.d.ts +33 -2
- package/dist/realtime/realtime-session-runner.d.ts.map +1 -1
- package/dist/realtime/realtime-session-runner.js +45 -2
- package/dist/realtime/realtime-session-runner.js.map +1 -1
- package/dist/realtime/realtime-tool-broker.d.ts +41 -3
- package/dist/realtime/realtime-tool-broker.d.ts.map +1 -1
- package/dist/realtime/realtime-tool-broker.js +67 -3
- package/dist/realtime/realtime-tool-broker.js.map +1 -1
- package/dist/realtime/realtime-turn-moderator.d.ts +103 -0
- package/dist/realtime/realtime-turn-moderator.d.ts.map +1 -0
- package/dist/realtime/realtime-turn-moderator.js +266 -0
- package/dist/realtime/realtime-turn-moderator.js.map +1 -0
- package/package.json +18 -17
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { MJScopedPromptPartEntity } from "@memberjunction/core-entities";
|
|
2
|
+
import { ChatMessage, ChatMessageRole } from "@memberjunction/ai";
|
|
3
|
+
import { SecondaryScopeValue } from "@memberjunction/ai-core-plus";
|
|
4
|
+
/**
|
|
5
|
+
* The scope a prompt-component resolution runs in. Mirrors the polymorphic scope the agent
|
|
6
|
+
* runtime already carries for memory (PrimaryScopeEntity/Record + SecondaryScopes).
|
|
7
|
+
*/
|
|
8
|
+
export interface PromptComponentScope {
|
|
9
|
+
primaryScopeEntityId?: string;
|
|
10
|
+
primaryScopeRecordId?: string;
|
|
11
|
+
secondaryScopes?: Record<string, SecondaryScopeValue>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* PromptComponentResolver — decides which `MJ: Scoped Prompt Parts` are included for a given
|
|
15
|
+
* prompt under a given scope, and assembles them into a role-faithful `ChatMessage[]`.
|
|
16
|
+
*
|
|
17
|
+
* **Pluggable (ClassFactory) + metadata-driven (template method).**
|
|
18
|
+
* The public {@link Resolve} / {@link AssembleMessages} fix the orchestration; the protected hooks
|
|
19
|
+
* ({@link getCandidates}, {@link isInScope}, {@link score}, {@link selectIncluded}, {@link order})
|
|
20
|
+
* are the extension points. MJ core obtains the resolver via
|
|
21
|
+
* `MJGlobal.Instance.ClassFactory.CreateInstance(PromptComponentResolver)`, which returns this base
|
|
22
|
+
* by default (no registration ⇒ base instance) or the highest-priority registered subclass. So any
|
|
23
|
+
* downstream consumer can plug in custom inclusion logic with **no core change**:
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* @RegisterClass(PromptComponentResolver) // priority auto-increments by import order
|
|
27
|
+
* export class MyResolver extends PromptComponentResolver {
|
|
28
|
+
* protected override score(p, scope) { ... } // custom ranking
|
|
29
|
+
* protected override selectIncluded(parts, scope) { ... } // custom merge rules
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Base (metadata-driven) defaults:
|
|
34
|
+
* - **Additive across part `Name`s** — distinct names all survive.
|
|
35
|
+
* - **Within a `Name`**, the row's `MergeBehavior` decides: `'Override'` (default) ⇒ the
|
|
36
|
+
* most-specific part wins (replace), `'Append'` ⇒ all in-scope same-named parts are included.
|
|
37
|
+
* - Specificity (the override ranking): SecondaryScopes match (+4) > PrimaryScopeRecord (+2) >
|
|
38
|
+
* Global (+1), tie-broken by `Priority`.
|
|
39
|
+
* - Final order: `Sort` ASC, then `Priority` DESC.
|
|
40
|
+
* - Roles are preserved (System/User/Assistant) so the assembled messages drive the model directly.
|
|
41
|
+
*/
|
|
42
|
+
export declare class PromptComponentResolver {
|
|
43
|
+
/** Resolve the included, ordered parts for `promptID` under `scope`. */
|
|
44
|
+
Resolve(promptID: string, scope: PromptComponentScope): MJScopedPromptPartEntity[];
|
|
45
|
+
/** Assemble resolved parts into role-faithful messages, coalescing adjacent same-role. */
|
|
46
|
+
AssembleMessages(parts: MJScopedPromptPartEntity[]): ChatMessage[];
|
|
47
|
+
/** Candidate parts for a prompt: same PromptID + resolvable Status. Override to widen/narrow. */
|
|
48
|
+
protected getCandidates(promptID: string): MJScopedPromptPartEntity[];
|
|
49
|
+
/** Is this part compatible with the run scope? (cascading: a part may only require dims the run has) */
|
|
50
|
+
protected isInScope(p: MJScopedPromptPartEntity, scope: PromptComponentScope): boolean;
|
|
51
|
+
/** Specificity score: SecondaryScopes match (+4) > PrimaryScopeRecord (+2) > Global (+1). */
|
|
52
|
+
protected score(p: MJScopedPromptPartEntity): number;
|
|
53
|
+
/**
|
|
54
|
+
* From in-scope candidates, decide inclusion per `Name`:
|
|
55
|
+
* - rank a Name's parts by specificity (score) then `Priority`;
|
|
56
|
+
* - the top part's `MergeBehavior` governs the group — `'Override'` keeps only the top,
|
|
57
|
+
* `'Append'` keeps all (additive within the Name).
|
|
58
|
+
* Distinct names always coexist (additive across names).
|
|
59
|
+
*/
|
|
60
|
+
protected selectIncluded(candidates: MJScopedPromptPartEntity[], _scope: PromptComponentScope): MJScopedPromptPartEntity[];
|
|
61
|
+
/** Final assembly order: Sort ASC, then Priority DESC, then Name. */
|
|
62
|
+
protected order(parts: MJScopedPromptPartEntity[]): MJScopedPromptPartEntity[];
|
|
63
|
+
protected parseScopes(raw: string | null): Record<string, unknown>;
|
|
64
|
+
protected coerceRole(raw: string | null): ChatMessageRole;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Convenience used by the agent runtime: obtain the (possibly overridden) resolver via the
|
|
68
|
+
* class factory, resolve + assemble for `promptID`/`scope`, and unshift the role-faithful messages
|
|
69
|
+
* onto the front of `conversationMessages` (mirroring how memory/RAG inject). No-op when nothing
|
|
70
|
+
* resolves. Returns the included parts (for observability).
|
|
71
|
+
*/
|
|
72
|
+
export declare function InjectScopedPromptParts(resolver: PromptComponentResolver, promptID: string, scope: PromptComponentScope, conversationMessages: ChatMessage[]): MJScopedPromptPartEntity[];
|
|
73
|
+
//# sourceMappingURL=prompt-component-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-component-resolver.d.ts","sourceRoot":"","sources":["../src/prompt-component-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CACzD;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,uBAAuB;IAGhC,wEAAwE;IACjE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,wBAAwB,EAAE;IAMzF,0FAA0F;IACnF,gBAAgB,CAAC,KAAK,EAAE,wBAAwB,EAAE,GAAG,WAAW,EAAE;IAkBzE,iGAAiG;IACjG,SAAS,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,wBAAwB,EAAE;IAMrE,wGAAwG;IACxG,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,wBAAwB,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO;IA0BtF,6FAA6F;IAC7F,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,GAAG,MAAM;IAOpD;;;;;;OAMG;IACH,SAAS,CAAC,cAAc,CACpB,UAAU,EAAE,wBAAwB,EAAE,EACtC,MAAM,EAAE,oBAAoB,GAC7B,wBAAwB,EAAE;IAmB7B,qEAAqE;IACrE,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,wBAAwB,EAAE,GAAG,wBAAwB,EAAE;IAQ9E,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAUlE,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,eAAe;CAM5D;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACnC,QAAQ,EAAE,uBAAuB,EACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,oBAAoB,EAC3B,oBAAoB,EAAE,WAAW,EAAE,GACpC,wBAAwB,EAAE,CAW5B"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { LogStatus } from "@memberjunction/core";
|
|
2
|
+
import { UUIDsEqual } from "@memberjunction/global";
|
|
3
|
+
import { AIEngine } from "@memberjunction/aiengine";
|
|
4
|
+
/** Statuses eligible for resolution. Archived parts are excluded. */
|
|
5
|
+
const RESOLVABLE_STATUSES = new Set(["Active", "Provisional"]);
|
|
6
|
+
/**
|
|
7
|
+
* PromptComponentResolver — decides which `MJ: Scoped Prompt Parts` are included for a given
|
|
8
|
+
* prompt under a given scope, and assembles them into a role-faithful `ChatMessage[]`.
|
|
9
|
+
*
|
|
10
|
+
* **Pluggable (ClassFactory) + metadata-driven (template method).**
|
|
11
|
+
* The public {@link Resolve} / {@link AssembleMessages} fix the orchestration; the protected hooks
|
|
12
|
+
* ({@link getCandidates}, {@link isInScope}, {@link score}, {@link selectIncluded}, {@link order})
|
|
13
|
+
* are the extension points. MJ core obtains the resolver via
|
|
14
|
+
* `MJGlobal.Instance.ClassFactory.CreateInstance(PromptComponentResolver)`, which returns this base
|
|
15
|
+
* by default (no registration ⇒ base instance) or the highest-priority registered subclass. So any
|
|
16
|
+
* downstream consumer can plug in custom inclusion logic with **no core change**:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* @RegisterClass(PromptComponentResolver) // priority auto-increments by import order
|
|
20
|
+
* export class MyResolver extends PromptComponentResolver {
|
|
21
|
+
* protected override score(p, scope) { ... } // custom ranking
|
|
22
|
+
* protected override selectIncluded(parts, scope) { ... } // custom merge rules
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* Base (metadata-driven) defaults:
|
|
27
|
+
* - **Additive across part `Name`s** — distinct names all survive.
|
|
28
|
+
* - **Within a `Name`**, the row's `MergeBehavior` decides: `'Override'` (default) ⇒ the
|
|
29
|
+
* most-specific part wins (replace), `'Append'` ⇒ all in-scope same-named parts are included.
|
|
30
|
+
* - Specificity (the override ranking): SecondaryScopes match (+4) > PrimaryScopeRecord (+2) >
|
|
31
|
+
* Global (+1), tie-broken by `Priority`.
|
|
32
|
+
* - Final order: `Sort` ASC, then `Priority` DESC.
|
|
33
|
+
* - Roles are preserved (System/User/Assistant) so the assembled messages drive the model directly.
|
|
34
|
+
*/
|
|
35
|
+
export class PromptComponentResolver {
|
|
36
|
+
// ── Public template methods ────────────────────────────────────────────────
|
|
37
|
+
/** Resolve the included, ordered parts for `promptID` under `scope`. */
|
|
38
|
+
Resolve(promptID, scope) {
|
|
39
|
+
const inScope = this.getCandidates(promptID).filter((p) => this.isInScope(p, scope));
|
|
40
|
+
const included = this.selectIncluded(inScope, scope);
|
|
41
|
+
return this.order(included);
|
|
42
|
+
}
|
|
43
|
+
/** Assemble resolved parts into role-faithful messages, coalescing adjacent same-role. */
|
|
44
|
+
AssembleMessages(parts) {
|
|
45
|
+
const out = [];
|
|
46
|
+
for (const p of parts) {
|
|
47
|
+
const content = (p.Text ?? "").trim();
|
|
48
|
+
if (!content)
|
|
49
|
+
continue;
|
|
50
|
+
const role = this.coerceRole(p.Role);
|
|
51
|
+
const last = out[out.length - 1];
|
|
52
|
+
if (last && last.role === role) {
|
|
53
|
+
last.content = `${last.content}\n\n${content}`;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
out.push({ role, content });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
// ── Protected hooks (override points) ──────────────────────────────────────
|
|
62
|
+
/** Candidate parts for a prompt: same PromptID + resolvable Status. Override to widen/narrow. */
|
|
63
|
+
getCandidates(promptID) {
|
|
64
|
+
return AIEngine.Instance.ScopedPromptParts.filter((p) => UUIDsEqual(p.PromptID, promptID) && RESOLVABLE_STATUSES.has(p.Status));
|
|
65
|
+
}
|
|
66
|
+
/** Is this part compatible with the run scope? (cascading: a part may only require dims the run has) */
|
|
67
|
+
isInScope(p, scope) {
|
|
68
|
+
if (p.PrimaryScopeRecordID) {
|
|
69
|
+
if (!scope.primaryScopeRecordId ||
|
|
70
|
+
p.PrimaryScopeRecordID.toLowerCase() !== scope.primaryScopeRecordId.toLowerCase()) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (p.PrimaryScopeEntityID &&
|
|
74
|
+
scope.primaryScopeEntityId &&
|
|
75
|
+
!UUIDsEqual(p.PrimaryScopeEntityID, scope.primaryScopeEntityId)) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const partScopes = this.parseScopes(p.SecondaryScopes);
|
|
80
|
+
for (const key of Object.keys(partScopes)) {
|
|
81
|
+
const runValue = scope.secondaryScopes?.[key];
|
|
82
|
+
if (runValue === undefined || String(runValue) !== String(partScopes[key])) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
/** Specificity score: SecondaryScopes match (+4) > PrimaryScopeRecord (+2) > Global (+1). */
|
|
89
|
+
score(p) {
|
|
90
|
+
let s = 1;
|
|
91
|
+
if (p.PrimaryScopeRecordID)
|
|
92
|
+
s += 2;
|
|
93
|
+
if (Object.keys(this.parseScopes(p.SecondaryScopes)).length > 0)
|
|
94
|
+
s += 4;
|
|
95
|
+
return s;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* From in-scope candidates, decide inclusion per `Name`:
|
|
99
|
+
* - rank a Name's parts by specificity (score) then `Priority`;
|
|
100
|
+
* - the top part's `MergeBehavior` governs the group — `'Override'` keeps only the top,
|
|
101
|
+
* `'Append'` keeps all (additive within the Name).
|
|
102
|
+
* Distinct names always coexist (additive across names).
|
|
103
|
+
*/
|
|
104
|
+
selectIncluded(candidates, _scope) {
|
|
105
|
+
const byName = new Map();
|
|
106
|
+
for (const p of candidates) {
|
|
107
|
+
const arr = byName.get(p.Name) ?? [];
|
|
108
|
+
arr.push(p);
|
|
109
|
+
byName.set(p.Name, arr);
|
|
110
|
+
}
|
|
111
|
+
const result = [];
|
|
112
|
+
for (const group of byName.values()) {
|
|
113
|
+
group.sort((a, b) => this.score(b) - this.score(a) || b.Priority - a.Priority);
|
|
114
|
+
if (group[0].MergeBehavior === "Append") {
|
|
115
|
+
result.push(...group);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
result.push(group[0]);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
/** Final assembly order: Sort ASC, then Priority DESC, then Name. */
|
|
124
|
+
order(parts) {
|
|
125
|
+
return [...parts].sort((a, b) => a.Sort - b.Sort || b.Priority - a.Priority || a.Name.localeCompare(b.Name));
|
|
126
|
+
}
|
|
127
|
+
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
128
|
+
parseScopes(raw) {
|
|
129
|
+
if (!raw)
|
|
130
|
+
return {};
|
|
131
|
+
try {
|
|
132
|
+
const o = JSON.parse(raw);
|
|
133
|
+
return o && typeof o === "object" ? o : {};
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return {};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
coerceRole(raw) {
|
|
140
|
+
const lower = typeof raw === "string" ? raw.toLowerCase() : "";
|
|
141
|
+
if (lower === "user")
|
|
142
|
+
return "user";
|
|
143
|
+
if (lower === "assistant")
|
|
144
|
+
return "assistant";
|
|
145
|
+
return "system";
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Convenience used by the agent runtime: obtain the (possibly overridden) resolver via the
|
|
150
|
+
* class factory, resolve + assemble for `promptID`/`scope`, and unshift the role-faithful messages
|
|
151
|
+
* onto the front of `conversationMessages` (mirroring how memory/RAG inject). No-op when nothing
|
|
152
|
+
* resolves. Returns the included parts (for observability).
|
|
153
|
+
*/
|
|
154
|
+
export function InjectScopedPromptParts(resolver, promptID, scope, conversationMessages) {
|
|
155
|
+
const parts = resolver.Resolve(promptID, scope);
|
|
156
|
+
if (parts.length === 0)
|
|
157
|
+
return [];
|
|
158
|
+
const messages = resolver.AssembleMessages(parts);
|
|
159
|
+
if (messages.length === 0)
|
|
160
|
+
return [];
|
|
161
|
+
conversationMessages.unshift(...messages);
|
|
162
|
+
LogStatus(`PromptComponentResolver: injected ${messages.length} message(s) from ${parts.length} ` +
|
|
163
|
+
`part(s) for prompt ${promptID} (scope record=${scope.primaryScopeRecordId ?? "global"})`);
|
|
164
|
+
return parts;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=prompt-component-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-component-resolver.js","sourceRoot":"","sources":["../src/prompt-component-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Resolves an agent's curated **media kit** — a `MJ: Collections` of `MJ: Artifacts`
|
|
3
|
+
* bound to the agent (or supplied as a per-session override) — into a compact, model-readable
|
|
4
|
+
* manifest the realtime agent reasons over to decide what to show on the Media channel.
|
|
5
|
+
*
|
|
6
|
+
* Design: a Collection IS the kit; each `MJ: Collection Artifacts` membership row carries the
|
|
7
|
+
* per-kit `Sequence` (priority), `ContextDescription` (agent "when to show it") and `Preload`
|
|
8
|
+
* (eager hint). The artifact's current version supplies the actual media (`FileID` -> `MJ: Files`,
|
|
9
|
+
* `MimeType`, display name). We add NO new top-level entity — the agent reuses the existing
|
|
10
|
+
* `Media_ShowMedia({ fileId, mediaType, displayName })` client tool to surface a chosen item, which
|
|
11
|
+
* streams through the authenticated `/media` route. Nothing here duplicates `MJ: Files`.
|
|
12
|
+
*
|
|
13
|
+
* Pure helpers ({@link mediaTypeFromMimeType}, {@link formatAgentMediaManifest}) are exported for
|
|
14
|
+
* unit testing; the DB-touching resolvers accept an explicit `provider` + `contextUser` so they are
|
|
15
|
+
* multi-provider safe and mockable.
|
|
16
|
+
*
|
|
17
|
+
* @module @memberjunction/ai-agents
|
|
18
|
+
* @author MemberJunction.com
|
|
19
|
+
*/
|
|
20
|
+
import { IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
21
|
+
/** The media kinds the realtime Media channel can render (mirrors the client `Media_ShowMedia` enum). */
|
|
22
|
+
export type AgentMediaKind = 'image' | 'video' | 'audio' | 'pdf' | 'web';
|
|
23
|
+
/** One resolved, model-readable media item in an agent's kit (ordered by its membership `Sequence`). */
|
|
24
|
+
export interface AgentMediaManifestItem {
|
|
25
|
+
/** The `MJ: Collection Artifacts` membership id (stable per kit). */
|
|
26
|
+
ResourceID: string;
|
|
27
|
+
/** The `MJ: Files` id to show — streamed securely via the `/media` route by `Media_ShowMedia`. */
|
|
28
|
+
FileID: string;
|
|
29
|
+
/** The media kind derived from the artifact version's MIME type. */
|
|
30
|
+
MediaType: AgentMediaKind;
|
|
31
|
+
/** Short label for the item's tab (the artifact version's name). */
|
|
32
|
+
DisplayName: string;
|
|
33
|
+
/** Agent-facing "what this is / when to show it" (membership override, else the version description). */
|
|
34
|
+
ContextDescription: string | null;
|
|
35
|
+
/** When true, the agent is told to show this at session start rather than waiting for relevance. */
|
|
36
|
+
Preload: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Maps an artifact version's MIME type to a Media-channel kind. Returns `null` for types the Media
|
|
40
|
+
* surface can't render as media (so the caller drops the item from the kit).
|
|
41
|
+
*/
|
|
42
|
+
export declare function mediaTypeFromMimeType(mimeType: string | null | undefined): AgentMediaKind | null;
|
|
43
|
+
/**
|
|
44
|
+
* Resolves the Collection id that is the agent's media kit for this session:
|
|
45
|
+
* `override > AIAgent.DefaultMediaCollectionID > null`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveAgentMediaCollectionID(provider: IMetadataProvider, contextUser: UserInfo, agentID: string, overrideCollectionID?: string | null): Promise<string | null>;
|
|
48
|
+
/**
|
|
49
|
+
* Loads a Collection's artifacts (ordered by membership `Sequence`) and resolves each to a media
|
|
50
|
+
* manifest item, dropping memberships whose current version has no `FileID` or a non-media MIME type.
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveAgentMediaManifest(provider: IMetadataProvider, contextUser: UserInfo, collectionID: string): Promise<AgentMediaManifestItem[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Formats a media manifest into a single background context note for the realtime agent. Lists each
|
|
55
|
+
* item with its `fileId`, media type, display name and when-to-show guidance, and instructs the agent
|
|
56
|
+
* to surface items with the existing `Media_ShowMedia` tool. Returns `null` for an empty manifest.
|
|
57
|
+
*/
|
|
58
|
+
export declare function formatAgentMediaManifest(items: AgentMediaManifestItem[]): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* End-to-end: resolves the agent's media kit (override > agent default) and returns the formatted
|
|
61
|
+
* agent context note, or `null` when there is no kit / no showable items. Best-effort: logs and
|
|
62
|
+
* returns `null` on any failure so it can never break session start.
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildAgentMediaContextNote(provider: IMetadataProvider, contextUser: UserInfo, agentID: string, overrideCollectionID?: string | null): Promise<string | null>;
|
|
65
|
+
//# sourceMappingURL=agent-media-library.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-media-library.d.ts","sourceRoot":"","sources":["../../src/realtime/agent-media-library.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,iBAAiB,EAAW,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAItF,yGAAyG;AACzG,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,CAAC;AAEzE,wGAAwG;AACxG,MAAM,WAAW,sBAAsB;IACnC,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,kGAAkG;IAClG,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,SAAS,EAAE,cAAc,CAAC;IAC1B,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,yGAAyG;IACzG,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,oGAAoG;IACpG,OAAO,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,GAAG,IAAI,CAQhG;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CAC/C,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,QAAQ,EACrB,OAAO,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,GACrC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuBxB;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC3C,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,QAAQ,EACrB,YAAY,EAAE,MAAM,GACrB,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAwBnC;AAgDD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,sBAAsB,EAAE,GAAG,MAAM,GAAG,IAAI,CAevF;AAED;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC5C,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,QAAQ,EACrB,OAAO,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,GACrC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Resolves an agent's curated **media kit** — a `MJ: Collections` of `MJ: Artifacts`
|
|
3
|
+
* bound to the agent (or supplied as a per-session override) — into a compact, model-readable
|
|
4
|
+
* manifest the realtime agent reasons over to decide what to show on the Media channel.
|
|
5
|
+
*
|
|
6
|
+
* Design: a Collection IS the kit; each `MJ: Collection Artifacts` membership row carries the
|
|
7
|
+
* per-kit `Sequence` (priority), `ContextDescription` (agent "when to show it") and `Preload`
|
|
8
|
+
* (eager hint). The artifact's current version supplies the actual media (`FileID` -> `MJ: Files`,
|
|
9
|
+
* `MimeType`, display name). We add NO new top-level entity — the agent reuses the existing
|
|
10
|
+
* `Media_ShowMedia({ fileId, mediaType, displayName })` client tool to surface a chosen item, which
|
|
11
|
+
* streams through the authenticated `/media` route. Nothing here duplicates `MJ: Files`.
|
|
12
|
+
*
|
|
13
|
+
* Pure helpers ({@link mediaTypeFromMimeType}, {@link formatAgentMediaManifest}) are exported for
|
|
14
|
+
* unit testing; the DB-touching resolvers accept an explicit `provider` + `contextUser` so they are
|
|
15
|
+
* multi-provider safe and mockable.
|
|
16
|
+
*
|
|
17
|
+
* @module @memberjunction/ai-agents
|
|
18
|
+
* @author MemberJunction.com
|
|
19
|
+
*/
|
|
20
|
+
import { RunView, LogError } from '@memberjunction/core';
|
|
21
|
+
import { IsValidUUID } from '@memberjunction/global';
|
|
22
|
+
/**
|
|
23
|
+
* Maps an artifact version's MIME type to a Media-channel kind. Returns `null` for types the Media
|
|
24
|
+
* surface can't render as media (so the caller drops the item from the kit).
|
|
25
|
+
*/
|
|
26
|
+
export function mediaTypeFromMimeType(mimeType) {
|
|
27
|
+
const mime = (mimeType ?? '').trim().toLowerCase();
|
|
28
|
+
if (mime.startsWith('image/'))
|
|
29
|
+
return 'image';
|
|
30
|
+
if (mime.startsWith('video/'))
|
|
31
|
+
return 'video';
|
|
32
|
+
if (mime.startsWith('audio/'))
|
|
33
|
+
return 'audio';
|
|
34
|
+
if (mime === 'application/pdf')
|
|
35
|
+
return 'pdf';
|
|
36
|
+
if (mime === 'text/html' || mime === 'application/xhtml+xml')
|
|
37
|
+
return 'web';
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolves the Collection id that is the agent's media kit for this session:
|
|
42
|
+
* `override > AIAgent.DefaultMediaCollectionID > null`.
|
|
43
|
+
*/
|
|
44
|
+
export async function resolveAgentMediaCollectionID(provider, contextUser, agentID, overrideCollectionID) {
|
|
45
|
+
if (overrideCollectionID) {
|
|
46
|
+
// The override may come from a calling app / per-session input, so validate it as a UUID before it
|
|
47
|
+
// ever reaches a filter. A malformed override is ignored (logged) and resolution falls back to the
|
|
48
|
+
// agent default — never a broken or injected query.
|
|
49
|
+
const trimmed = overrideCollectionID.trim();
|
|
50
|
+
if (IsValidUUID(trimmed)) {
|
|
51
|
+
return trimmed;
|
|
52
|
+
}
|
|
53
|
+
LogError(`[agent-media-library] Ignoring malformed overrideCollectionID '${overrideCollectionID}' — ` +
|
|
54
|
+
'falling back to the agent default media kit.');
|
|
55
|
+
}
|
|
56
|
+
const rv = RunView.FromMetadataProvider(provider);
|
|
57
|
+
const result = await rv.RunView({ EntityName: 'AI Agents', ExtraFilter: `ID='${agentID}'`, ResultType: 'entity_object' }, contextUser);
|
|
58
|
+
if (!result.Success || result.Results.length === 0) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return result.Results[0].DefaultMediaCollectionID ?? null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Loads a Collection's artifacts (ordered by membership `Sequence`) and resolves each to a media
|
|
65
|
+
* manifest item, dropping memberships whose current version has no `FileID` or a non-media MIME type.
|
|
66
|
+
*/
|
|
67
|
+
export async function resolveAgentMediaManifest(provider, contextUser, collectionID) {
|
|
68
|
+
const rv = RunView.FromMetadataProvider(provider);
|
|
69
|
+
const memberships = await rv.RunView({
|
|
70
|
+
EntityName: 'MJ: Collection Artifacts',
|
|
71
|
+
ExtraFilter: `CollectionID='${collectionID}'`,
|
|
72
|
+
OrderBy: 'Sequence ASC',
|
|
73
|
+
ResultType: 'entity_object',
|
|
74
|
+
}, contextUser);
|
|
75
|
+
if (!memberships.Success || memberships.Results.length === 0) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
const versionsByID = await loadArtifactVersions(rv, contextUser, memberships.Results.map((m) => m.ArtifactVersionID));
|
|
79
|
+
const items = [];
|
|
80
|
+
for (const membership of memberships.Results) {
|
|
81
|
+
const item = toManifestItem(membership, versionsByID.get(membership.ArtifactVersionID));
|
|
82
|
+
if (item) {
|
|
83
|
+
items.push(item);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return items;
|
|
87
|
+
}
|
|
88
|
+
/** Loads the artifact versions referenced by a kit's memberships, keyed by id. */
|
|
89
|
+
async function loadArtifactVersions(rv, contextUser, versionIDs) {
|
|
90
|
+
const byID = new Map();
|
|
91
|
+
const uniqueIDs = [...new Set(versionIDs.filter((id) => !!id))];
|
|
92
|
+
if (uniqueIDs.length === 0) {
|
|
93
|
+
return byID;
|
|
94
|
+
}
|
|
95
|
+
const inList = uniqueIDs.map((id) => `'${id}'`).join(',');
|
|
96
|
+
const result = await rv.RunView({ EntityName: 'MJ: Artifact Versions', ExtraFilter: `ID IN (${inList})`, ResultType: 'entity_object' }, contextUser);
|
|
97
|
+
if (result.Success) {
|
|
98
|
+
for (const version of result.Results) {
|
|
99
|
+
byID.set(version.ID, version);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return byID;
|
|
103
|
+
}
|
|
104
|
+
/** Resolves one membership + its artifact version to a manifest item, or `null` if not showable. */
|
|
105
|
+
function toManifestItem(membership, version) {
|
|
106
|
+
if (!version || !version.FileID) {
|
|
107
|
+
return null; // text-only / unresolved versions can't be shown as media
|
|
108
|
+
}
|
|
109
|
+
const mediaType = mediaTypeFromMimeType(version.MimeType);
|
|
110
|
+
if (!mediaType) {
|
|
111
|
+
return null; // non-media MIME type — drop from the kit
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
ResourceID: membership.ID,
|
|
115
|
+
FileID: version.FileID,
|
|
116
|
+
MediaType: mediaType,
|
|
117
|
+
DisplayName: version.Name?.trim() || 'Media',
|
|
118
|
+
ContextDescription: membership.ContextDescription?.trim() || version.Description?.trim() || null,
|
|
119
|
+
Preload: !!membership.Preload,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Formats a media manifest into a single background context note for the realtime agent. Lists each
|
|
124
|
+
* item with its `fileId`, media type, display name and when-to-show guidance, and instructs the agent
|
|
125
|
+
* to surface items with the existing `Media_ShowMedia` tool. Returns `null` for an empty manifest.
|
|
126
|
+
*/
|
|
127
|
+
export function formatAgentMediaManifest(items) {
|
|
128
|
+
if (items.length === 0) {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
const lines = items.map((item, index) => {
|
|
132
|
+
const when = item.ContextDescription ? ` — ${item.ContextDescription}` : '';
|
|
133
|
+
const preload = item.Preload ? ' [PRELOAD: show at the start of the call]' : '';
|
|
134
|
+
return `${index + 1}. "${item.DisplayName}" (${item.MediaType})${when} fileId: ${item.FileID}${preload}`;
|
|
135
|
+
});
|
|
136
|
+
return ('[media-library] You have a curated media kit you can show on the shared Media surface during this call. ' +
|
|
137
|
+
'To show an item, call Media_ShowMedia with its fileId, mediaType and displayName. Show an item only when ' +
|
|
138
|
+
'it is relevant (or now, if it is marked PRELOAD). Do NOT read this list aloud. Available items, in priority order:\n' +
|
|
139
|
+
lines.join('\n'));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* End-to-end: resolves the agent's media kit (override > agent default) and returns the formatted
|
|
143
|
+
* agent context note, or `null` when there is no kit / no showable items. Best-effort: logs and
|
|
144
|
+
* returns `null` on any failure so it can never break session start.
|
|
145
|
+
*/
|
|
146
|
+
export async function buildAgentMediaContextNote(provider, contextUser, agentID, overrideCollectionID) {
|
|
147
|
+
try {
|
|
148
|
+
const collectionID = await resolveAgentMediaCollectionID(provider, contextUser, agentID, overrideCollectionID);
|
|
149
|
+
if (!collectionID) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
const items = await resolveAgentMediaManifest(provider, contextUser, collectionID);
|
|
153
|
+
return formatAgentMediaManifest(items);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
LogError(`[agent-media-library] Failed to build media manifest for agent ${agentID}: ${error instanceof Error ? error.message : String(error)}`);
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=agent-media-library.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-media-library.js","sourceRoot":"","sources":["../../src/realtime/agent-media-library.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,11 @@ export interface BridgeRoomTranscriptSinkOptions {
|
|
|
24
24
|
ApplicationScope?: ConversationApplicationScope;
|
|
25
25
|
/** Optional owning application id (e.g. the Meet app) so its surface can list its rooms. */
|
|
26
26
|
ApplicationID?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Optional owning application NAME (e.g. `'Meet'`) — resolved to an id lazily on first use (cached), so
|
|
29
|
+
* the binding site doesn't hardcode a seed GUID. Ignored when {@link ApplicationID} is supplied.
|
|
30
|
+
*/
|
|
31
|
+
ApplicationName?: string;
|
|
27
32
|
}
|
|
28
33
|
/**
|
|
29
34
|
* One transcript line the engine emits (structurally matches `BridgeTranscriptLine` in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-room-transcript-sink.d.ts","sourceRoot":"","sources":["../../src/realtime/bridge-room-transcript-sink.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAgC,MAAM,sBAAsB,CAAC;AAGjG,+HAA+H;AAC/H,MAAM,MAAM,4BAA4B,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;AAE7E,2GAA2G;AAC3G,MAAM,WAAW,+BAA+B;IAC5C,+GAA+G;IAC/G,gBAAgB,EAAE,MAAM,CAAC;IACzB,qHAAqH;IACrH,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;IAChD,4FAA4F;IAC5F,aAAa,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"bridge-room-transcript-sink.d.ts","sourceRoot":"","sources":["../../src/realtime/bridge-room-transcript-sink.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAgC,MAAM,sBAAsB,CAAC;AAGjG,+HAA+H;AAC/H,MAAM,MAAM,4BAA4B,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;AAE7E,2GAA2G;AAC3G,MAAM,WAAW,+BAA+B;IAC5C,+GAA+G;IAC/G,gBAAgB,EAAE,MAAM,CAAC;IACzB,qHAAqH;IACrH,gBAAgB,CAAC,EAAE,4BAA4B,CAAC;IAChD,4FAA4F;IAC5F,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACtC,6FAA6F;IAC7F,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,cAAc,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,aAAa,EAAE,OAAO,CAAC;IACvB,sGAAsG;IACtG,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,MAAM,wBAAwB,GAAG,CACnC,IAAI,EAAE,yBAAyB,EAC/B,WAAW,CAAC,EAAE,QAAQ,EACtB,QAAQ,CAAC,EAAE,iBAAiB,KAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;AAKnB;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,+BAA+B,GAAG,wBAAwB,CA8BjH"}
|
|
@@ -26,6 +26,9 @@ const CONVERSATION_DETAIL_ENTITY = 'MJ: Conversation Details';
|
|
|
26
26
|
*/
|
|
27
27
|
export function CreateBridgeRoomTranscriptSink(options) {
|
|
28
28
|
const scope = options.ApplicationScope ?? 'Application';
|
|
29
|
+
/** Lazily-resolved owning application id (explicit id wins; else resolved-by-name once and cached). */
|
|
30
|
+
let resolvedApplicationID = options.ApplicationID;
|
|
31
|
+
let applicationResolved = !!options.ApplicationID || !options.ApplicationName;
|
|
29
32
|
/** roomKey(lower) → resolved ConversationID (populated once get-or-create settles). */
|
|
30
33
|
const roomToConversation = new Map();
|
|
31
34
|
/** roomKey(lower) → in-flight get-or-create promise (dedupes concurrent first lines for a room). */
|
|
@@ -36,7 +39,12 @@ export function CreateBridgeRoomTranscriptSink(options) {
|
|
|
36
39
|
if (!contextUser || !provider) {
|
|
37
40
|
return; // a server-side write needs a user + provider; nothing to do without them
|
|
38
41
|
}
|
|
39
|
-
|
|
42
|
+
// Resolve the owning application by name once (e.g. 'Meet' → its id) so its surface can list the rooms.
|
|
43
|
+
if (!applicationResolved) {
|
|
44
|
+
applicationResolved = true; // attempt once; a miss just leaves it unlinked (still scoped-out of chat)
|
|
45
|
+
resolvedApplicationID = (await resolveApplicationIdByName(options.ApplicationName, contextUser, provider)) ?? undefined;
|
|
46
|
+
}
|
|
47
|
+
const conversationID = await ensureRoomConversation(line.RoomKey, options.ConversationType, scope, resolvedApplicationID, roomToConversation, ensureInFlight, contextUser, provider);
|
|
40
48
|
if (!conversationID) {
|
|
41
49
|
return;
|
|
42
50
|
}
|
|
@@ -120,6 +128,22 @@ async function writeTranscriptDetail(conversationID, line, contextUser, provider
|
|
|
120
128
|
LogError(`CreateBridgeRoomTranscriptSink: failed to write transcript detail: ${detail.LatestResult?.CompleteMessage ?? 'unknown error'}`);
|
|
121
129
|
}
|
|
122
130
|
}
|
|
131
|
+
/** Resolves an `MJ: Applications` id by Name (e.g. `'Meet'`). Returns `null` if absent (room stays unlinked). */
|
|
132
|
+
async function resolveApplicationIdByName(name, contextUser, provider) {
|
|
133
|
+
const rv = new RunView();
|
|
134
|
+
const result = await rv.RunView({
|
|
135
|
+
EntityName: 'MJ: Applications',
|
|
136
|
+
ExtraFilter: `Name='${escapeSql(name)}'`,
|
|
137
|
+
Fields: ['ID'],
|
|
138
|
+
MaxRows: 1,
|
|
139
|
+
ResultType: 'simple',
|
|
140
|
+
}, contextUser);
|
|
141
|
+
if (result.Success && result.Results.length > 0) {
|
|
142
|
+
return result.Results[0].ID;
|
|
143
|
+
}
|
|
144
|
+
LogStatus(`CreateBridgeRoomTranscriptSink: application '${name}' not found — room transcripts stay unlinked (still scoped out of normal chat).`);
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
123
147
|
/** Escapes single quotes for safe embedding in an `ExtraFilter` literal. */
|
|
124
148
|
function escapeSql(value) {
|
|
125
149
|
return value.replace(/'/g, "''");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge-room-transcript-sink.js","sourceRoot":"","sources":["../../src/realtime/bridge-room-transcript-sink.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAA+B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"bridge-room-transcript-sink.js","sourceRoot":"","sources":["../../src/realtime/bridge-room-transcript-sink.ts"],"names":[],"mappings":"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"}
|