@memberjunction/ai-agents 5.43.0 → 5.45.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 +8 -0
- package/dist/AgentRunner.d.ts +20 -0
- package/dist/AgentRunner.d.ts.map +1 -1
- package/dist/AgentRunner.js +62 -0
- package/dist/AgentRunner.js.map +1 -1
- 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/loop-agent-response-type.d.ts +23 -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 +34 -1
- package/dist/agent-types/loop-agent-type.js.map +1 -1
- package/dist/base-agent.d.ts +434 -12
- package/dist/base-agent.d.ts.map +1 -1
- package/dist/base-agent.js +1215 -89
- package/dist/base-agent.js.map +1 -1
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -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/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 +114 -6
- package/dist/realtime/realtime-client-session-service.d.ts.map +1 -1
- package/dist/realtime/realtime-client-session-service.js +289 -30
- package/dist/realtime/realtime-client-session-service.js.map +1 -1
- package/dist/realtime/realtime-coagent-config.d.ts +82 -3
- package/dist/realtime/realtime-coagent-config.d.ts.map +1 -1
- package/dist/realtime/realtime-coagent-config.js +147 -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/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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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-side channel plugin for the **headless** Client Context channel — the live
|
|
3
|
+
* wire that streams the user's app context (where they are, what they see, the available client-tool
|
|
4
|
+
* and agent manifest) to the realtime co-agent, and through which the model's single stable
|
|
5
|
+
* `ContextTool` proxy drives in-app actions.
|
|
6
|
+
*
|
|
7
|
+
* Paired with the browser's `ClientContextChannel` client plugin through the seeded
|
|
8
|
+
* `MJ: AI Agent Channels` row (`Name: 'ClientContextChannel'`, `IsHeadless: 1`,
|
|
9
|
+
* `ServerPluginClass: 'ClientContextChannelServer'`, `ClientPluginClass: 'ClientContextChannel'`).
|
|
10
|
+
*
|
|
11
|
+
* **Why the server half is intentionally thin.** This channel is *headless* (it never mounts a tab)
|
|
12
|
+
* and *ephemeral* (it persists no state of record — it is a live wire, not a document like the
|
|
13
|
+
* whiteboard). In the client-direct topology the work lives in the browser: the client plugin
|
|
14
|
+
* publishes context deltas via the provider's `SendContextNote` and executes `ContextTool` calls
|
|
15
|
+
* locally through the unified client-tool resolver (`ResolveClientTools` in
|
|
16
|
+
* `@memberjunction/ai-core-plus`) with no server round-trip. The server half exists to (a) complete
|
|
17
|
+
* the channel registry pairing so the channel is discoverable/loadable like every other channel, and
|
|
18
|
+
* (b) be the home for any *future* server-side context tooling. It contributes no server tools today
|
|
19
|
+
* and saves no state — both base defaults, made explicit here.
|
|
20
|
+
*
|
|
21
|
+
* @module @memberjunction/ai-agents
|
|
22
|
+
* @author MemberJunction.com
|
|
23
|
+
*/
|
|
24
|
+
import { BaseRealtimeChannelServer, RealtimeToolDefinition } from '@memberjunction/ai';
|
|
25
|
+
/** The stable channel name, matching the seeded `MJ: AI Agent Channels` row. */
|
|
26
|
+
export declare const CLIENT_CONTEXT_CHANNEL_NAME = "ClientContextChannel";
|
|
27
|
+
/**
|
|
28
|
+
* Server half of the headless Client Context channel. One instance per realtime session (created by
|
|
29
|
+
* `RealtimeChannelServerHost` from the channel registry — never construct directly).
|
|
30
|
+
*
|
|
31
|
+
* Contributes **no server tools** ({@link GetServerToolDefinitions} returns `[]`) — the channel's
|
|
32
|
+
* `ContextTool` and client tools execute client-side — and persists **no state of record**
|
|
33
|
+
* ({@link OnChannelStateSave} returns `null`, the "keep nothing / live-only" posture), so a session
|
|
34
|
+
* resume never tries to rehydrate it.
|
|
35
|
+
*/
|
|
36
|
+
export declare class ClientContextChannelServer extends BaseRealtimeChannelServer {
|
|
37
|
+
/** Matches the seeded `MJ: AI Agent Channels` row's `Name`. */
|
|
38
|
+
get ChannelName(): string;
|
|
39
|
+
/**
|
|
40
|
+
* No server-executed tools: the channel's stable `ContextTool` proxy and all surface client tools
|
|
41
|
+
* execute in the browser via the unified client-tool resolver. Explicit `[]` documents the intent.
|
|
42
|
+
*/
|
|
43
|
+
GetServerToolDefinitions(): RealtimeToolDefinition[];
|
|
44
|
+
/**
|
|
45
|
+
* Live-only channel: it carries no state of record (it is a wire, not a document), so a landed
|
|
46
|
+
* state save is intentionally not persisted. Returning `null` keeps nothing — a session resume
|
|
47
|
+
* never rehydrates this channel.
|
|
48
|
+
*
|
|
49
|
+
* @returns `null` — never persist.
|
|
50
|
+
*/
|
|
51
|
+
OnChannelStateSave(): Promise<string | null>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Tree-shaking prevention for {@link ClientContextChannelServer}'s `@RegisterClass` registration.
|
|
55
|
+
* Called from a static code path in the server host so the registration always executes — mirroring
|
|
56
|
+
* every other `Load...()` in the realtime stack.
|
|
57
|
+
*/
|
|
58
|
+
export declare function LoadClientContextChannelServer(): void;
|
|
59
|
+
//# sourceMappingURL=client-context-channel-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-context-channel-server.d.ts","sourceRoot":"","sources":["../../src/realtime/client-context-channel-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGvF,gFAAgF;AAChF,eAAO,MAAM,2BAA2B,yBAAyB,CAAC;AAElE;;;;;;;;GAQG;AACH,qBACa,0BAA2B,SAAQ,yBAAyB;IACrE,+DAA+D;IAC/D,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED;;;OAGG;IACa,wBAAwB,IAAI,sBAAsB,EAAE;IAIpE;;;;;;OAMG;IACmB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAGrE;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAErD"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-side channel plugin for the **headless** Client Context channel — the live
|
|
3
|
+
* wire that streams the user's app context (where they are, what they see, the available client-tool
|
|
4
|
+
* and agent manifest) to the realtime co-agent, and through which the model's single stable
|
|
5
|
+
* `ContextTool` proxy drives in-app actions.
|
|
6
|
+
*
|
|
7
|
+
* Paired with the browser's `ClientContextChannel` client plugin through the seeded
|
|
8
|
+
* `MJ: AI Agent Channels` row (`Name: 'ClientContextChannel'`, `IsHeadless: 1`,
|
|
9
|
+
* `ServerPluginClass: 'ClientContextChannelServer'`, `ClientPluginClass: 'ClientContextChannel'`).
|
|
10
|
+
*
|
|
11
|
+
* **Why the server half is intentionally thin.** This channel is *headless* (it never mounts a tab)
|
|
12
|
+
* and *ephemeral* (it persists no state of record — it is a live wire, not a document like the
|
|
13
|
+
* whiteboard). In the client-direct topology the work lives in the browser: the client plugin
|
|
14
|
+
* publishes context deltas via the provider's `SendContextNote` and executes `ContextTool` calls
|
|
15
|
+
* locally through the unified client-tool resolver (`ResolveClientTools` in
|
|
16
|
+
* `@memberjunction/ai-core-plus`) with no server round-trip. The server half exists to (a) complete
|
|
17
|
+
* the channel registry pairing so the channel is discoverable/loadable like every other channel, and
|
|
18
|
+
* (b) be the home for any *future* server-side context tooling. It contributes no server tools today
|
|
19
|
+
* and saves no state — both base defaults, made explicit here.
|
|
20
|
+
*
|
|
21
|
+
* @module @memberjunction/ai-agents
|
|
22
|
+
* @author MemberJunction.com
|
|
23
|
+
*/
|
|
24
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
25
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
26
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
27
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
28
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
29
|
+
};
|
|
30
|
+
import { BaseRealtimeChannelServer } from '@memberjunction/ai';
|
|
31
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
32
|
+
/** The stable channel name, matching the seeded `MJ: AI Agent Channels` row. */
|
|
33
|
+
export const CLIENT_CONTEXT_CHANNEL_NAME = 'ClientContextChannel';
|
|
34
|
+
/**
|
|
35
|
+
* Server half of the headless Client Context channel. One instance per realtime session (created by
|
|
36
|
+
* `RealtimeChannelServerHost` from the channel registry — never construct directly).
|
|
37
|
+
*
|
|
38
|
+
* Contributes **no server tools** ({@link GetServerToolDefinitions} returns `[]`) — the channel's
|
|
39
|
+
* `ContextTool` and client tools execute client-side — and persists **no state of record**
|
|
40
|
+
* ({@link OnChannelStateSave} returns `null`, the "keep nothing / live-only" posture), so a session
|
|
41
|
+
* resume never tries to rehydrate it.
|
|
42
|
+
*/
|
|
43
|
+
let ClientContextChannelServer = class ClientContextChannelServer extends BaseRealtimeChannelServer {
|
|
44
|
+
/** Matches the seeded `MJ: AI Agent Channels` row's `Name`. */
|
|
45
|
+
get ChannelName() {
|
|
46
|
+
return CLIENT_CONTEXT_CHANNEL_NAME;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* No server-executed tools: the channel's stable `ContextTool` proxy and all surface client tools
|
|
50
|
+
* execute in the browser via the unified client-tool resolver. Explicit `[]` documents the intent.
|
|
51
|
+
*/
|
|
52
|
+
GetServerToolDefinitions() {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Live-only channel: it carries no state of record (it is a wire, not a document), so a landed
|
|
57
|
+
* state save is intentionally not persisted. Returning `null` keeps nothing — a session resume
|
|
58
|
+
* never rehydrates this channel.
|
|
59
|
+
*
|
|
60
|
+
* @returns `null` — never persist.
|
|
61
|
+
*/
|
|
62
|
+
async OnChannelStateSave() {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
ClientContextChannelServer = __decorate([
|
|
67
|
+
RegisterClass(BaseRealtimeChannelServer, 'ClientContextChannelServer')
|
|
68
|
+
], ClientContextChannelServer);
|
|
69
|
+
export { ClientContextChannelServer };
|
|
70
|
+
/**
|
|
71
|
+
* Tree-shaking prevention for {@link ClientContextChannelServer}'s `@RegisterClass` registration.
|
|
72
|
+
* Called from a static code path in the server host so the registration always executes — mirroring
|
|
73
|
+
* every other `Load...()` in the realtime stack.
|
|
74
|
+
*/
|
|
75
|
+
export function LoadClientContextChannelServer() {
|
|
76
|
+
// no-op — the import + call create a static reference bundlers cannot eliminate
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=client-context-channel-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-context-channel-server.js","sourceRoot":"","sources":["../../src/realtime/client-context-channel-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;;;;;AAEH,OAAO,EAAE,yBAAyB,EAA0B,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,gFAAgF;AAChF,MAAM,CAAC,MAAM,2BAA2B,GAAG,sBAAsB,CAAC;AAElE;;;;;;;;GAQG;AAEI,IAAM,0BAA0B,GAAhC,MAAM,0BAA2B,SAAQ,yBAAyB;IACrE,+DAA+D;IAC/D,IAAW,WAAW;QAClB,OAAO,2BAA2B,CAAC;IACvC,CAAC;IAED;;;OAGG;IACa,wBAAwB;QACpC,OAAO,EAAE,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACa,KAAK,CAAC,kBAAkB;QACpC,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ,CAAA;AAxBY,0BAA0B;IADtC,aAAa,CAAC,yBAAyB,EAAE,4BAA4B,CAAC;GAC1D,0BAA0B,CAwBtC;;AAED;;;;GAIG;AACH,MAAM,UAAU,8BAA8B;IAC1C,gFAAgF;AACpF,CAAC"}
|