@memberjunction/ng-agent-client 5.22.0 → 5.24.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 ADDED
@@ -0,0 +1,113 @@
1
+ # @memberjunction/ng-agent-client
2
+
3
+ Thin Angular wrapper around [`@memberjunction/ai-agent-client`](../../../AI/AgentsClient/README.md). Provides Angular dependency injection and automatic lifecycle cleanup -- nothing more.
4
+
5
+ ## What This Package Does
6
+
7
+ - **`AgentClientService`** -- An `@Injectable({ providedIn: 'root' })` singleton that owns an `AgentClientSession` internally.
8
+ - **Pass-through API** -- Every public method and observable on `AgentClientSession` is exposed directly. No transformation, no added logic.
9
+ - **Lifecycle management** -- Calls `session.Dispose()` in `ngOnDestroy` to prevent memory leaks.
10
+
11
+ ## What This Package Does NOT Do
12
+
13
+ - No business logic
14
+ - No tool handlers -- the consuming application registers tools
15
+ - No GraphQL code -- that lives in the core SDK
16
+ - No WebSocket code -- removed; transport is handled by `GraphQLDataProvider`
17
+
18
+ ## Usage
19
+
20
+ ```typescript
21
+ import { Component, inject, OnInit, OnDestroy } from '@angular/core';
22
+ import { AgentClientService } from '@memberjunction/ng-agent-client';
23
+ import { Subject, takeUntil } from 'rxjs';
24
+
25
+ @Component({ ... })
26
+ export class MyChatComponent implements OnInit, OnDestroy {
27
+ private agentClient = inject(AgentClientService);
28
+ private destroy$ = new Subject<void>();
29
+
30
+ ngOnInit(): void {
31
+ // Register tools
32
+ this.agentClient.RegisterTool({
33
+ Name: 'NavigateToRecord',
34
+ Description: 'Open an entity record',
35
+ ParameterSchema: { type: 'object', properties: { EntityName: { type: 'string' } } },
36
+ Handler: async (params) => {
37
+ // app-specific logic
38
+ return { Success: true, Data: 'done' };
39
+ },
40
+ });
41
+
42
+ // Listen for events
43
+ this.agentClient.ToolRequested$
44
+ .pipe(takeUntil(this.destroy$))
45
+ .subscribe(event => console.log('Tool requested:', event.Request.ToolName));
46
+
47
+ // Start session
48
+ this.agentClient.StartSession('session-id');
49
+ }
50
+
51
+ async SendMessage(text: string): Promise<void> {
52
+ const result = await this.agentClient.RunAgent({
53
+ AgentId: 'agent-uuid',
54
+ Messages: [{ role: 'user', content: text }],
55
+ });
56
+ console.log('Agent result:', result.Success);
57
+ }
58
+
59
+ ngOnDestroy(): void {
60
+ this.destroy$.next();
61
+ this.destroy$.complete();
62
+ // AgentClientService.ngOnDestroy() calls session.Dispose() automatically
63
+ }
64
+ }
65
+ ```
66
+
67
+ ## API
68
+
69
+ All methods and observables mirror `AgentClientSession` from the core SDK:
70
+
71
+ | Member | Type | Description |
72
+ |---|---|---|
73
+ | `ToolRequested$` | `Observable` | Emitted before tool execution |
74
+ | `ToolExecuted$` | `Observable` | Emitted after tool execution |
75
+ | `AgentProgress$` | `Observable` | Agent progress updates |
76
+ | `SessionActive$` | `Observable` | Session state changes |
77
+ | `Error$` | `Observable` | Errors during communication or execution |
78
+ | `SessionId` | `string \| null` | Current session ID |
79
+ | `IsActive` | `boolean` | Whether a session is active |
80
+ | `RegisterTool(tool)` | method | Register a client-side tool handler |
81
+ | `UnregisterTool(name)` | method | Remove a tool |
82
+ | `GetRegisteredTools()` | method | List all registered tools |
83
+ | `StartSession(id)` | method | Start listening for tool requests |
84
+ | `StopSession()` | method | Stop and clean up |
85
+ | `RunAgent(params)` | method | Execute an agent |
86
+ | `RunAgentFromConversationDetail(params)` | method | Execute from conversation detail |
87
+
88
+ ## Using the Core SDK Directly
89
+
90
+ This Angular wrapper is a convenience, not a requirement. The core SDK (`@memberjunction/ai-agent-client`) already provides RxJS observables and requires no Angular-specific APIs. If you run into issues with Angular's `providedIn: 'root'` singleton pattern — such as duplicate instances from multiple module imports or npm hoisting conflicts — you can use `AgentClientSession` directly:
91
+
92
+ ```typescript
93
+ import { AgentClientSession } from '@memberjunction/ai-agent-client';
94
+
95
+ // Create and manage the session yourself
96
+ const session = new AgentClientSession();
97
+ session.RegisterTool({ Name: 'MyTool', ... });
98
+ session.StartSession('session-id');
99
+
100
+ // Same observables, same API — no Angular DI involved
101
+ session.ToolRequested$.subscribe(event => { ... });
102
+ await session.RunAgent({ AgentId: 'sage-id', Messages: [...] });
103
+
104
+ // Clean up when done
105
+ session.Dispose();
106
+ ```
107
+
108
+ This is particularly useful in non-standard Angular setups (micro-frontends, lazy-loaded feature modules with their own injectors, or hybrid apps).
109
+
110
+ ## Further Reading
111
+
112
+ - **Core SDK**: [`@memberjunction/ai-agent-client` README](../../../AI/AgentsClient/README.md) -- full architecture, types, and examples
113
+ - **Client Tools Protocol**: [CLIENT_TOOLS_GUIDE.md](../../../AI/Agents/docs/CLIENT_TOOLS_GUIDE.md) -- how tools are defined, dispatched, and resolved
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-client-service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-client-service.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/agent-client-service.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,148 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ /**
3
+ * Tests for AgentClientService — verifies pass-through delegation to AgentClientSession.
4
+ */
5
+ vi.mock('@angular/core', () => ({
6
+ Injectable: () => (target) => target,
7
+ OnDestroy: class {
8
+ },
9
+ }));
10
+ // Track the mock session created by the constructor
11
+ let createdSession;
12
+ vi.mock('@memberjunction/ai-agent-client', () => {
13
+ // Factory runs at module load — must define mock inside
14
+ function MockAgentClientSession() {
15
+ const session = {
16
+ ToolRequested$: { subscribe: () => { } },
17
+ ToolExecuted$: { subscribe: () => { } },
18
+ AgentProgress$: { subscribe: () => { } },
19
+ SessionActive$: { subscribe: () => { } },
20
+ Error$: { subscribe: () => { } },
21
+ SessionId: null,
22
+ IsActive: false,
23
+ RegisterTool: vi.fn(),
24
+ UnregisterTool: vi.fn(),
25
+ GetRegisteredTools: vi.fn().mockReturnValue([]),
26
+ RegisterToolDecorator: vi.fn(),
27
+ SetDecoratorContext: vi.fn(),
28
+ DecorateAndSendTools: vi.fn().mockResolvedValue(undefined),
29
+ StartSession: vi.fn(),
30
+ StopSession: vi.fn(),
31
+ RunAgent: vi.fn().mockResolvedValue({ Success: true }),
32
+ RunAgentFromConversationDetail: vi.fn().mockResolvedValue({ Success: true }),
33
+ Dispose: vi.fn(),
34
+ };
35
+ createdSession = session;
36
+ return session;
37
+ }
38
+ return {
39
+ AgentClientSession: MockAgentClientSession,
40
+ };
41
+ });
42
+ import { AgentClientService } from '../lib/agent-client.service';
43
+ describe('AgentClientService', () => {
44
+ let service;
45
+ beforeEach(() => {
46
+ vi.clearAllMocks();
47
+ service = new AgentClientService();
48
+ });
49
+ describe('Observable pass-throughs', () => {
50
+ it('should expose ToolRequested$ from the session', () => {
51
+ expect(service.ToolRequested$).toBe(createdSession.ToolRequested$);
52
+ });
53
+ it('should expose ToolExecuted$ from the session', () => {
54
+ expect(service.ToolExecuted$).toBe(createdSession.ToolExecuted$);
55
+ });
56
+ it('should expose AgentProgress$ from the session', () => {
57
+ expect(service.AgentProgress$).toBe(createdSession.AgentProgress$);
58
+ });
59
+ it('should expose SessionActive$ from the session', () => {
60
+ expect(service.SessionActive$).toBe(createdSession.SessionActive$);
61
+ });
62
+ it('should expose Error$ from the session', () => {
63
+ expect(service.Error$).toBe(createdSession.Error$);
64
+ });
65
+ });
66
+ describe('Session state', () => {
67
+ it('should return SessionId from the session', () => {
68
+ createdSession.SessionId = 'test-session-123';
69
+ expect(service.SessionId).toBe('test-session-123');
70
+ });
71
+ it('should return null SessionId when no session is active', () => {
72
+ createdSession.SessionId = null;
73
+ expect(service.SessionId).toBeNull();
74
+ });
75
+ it('should return IsActive from the session', () => {
76
+ createdSession.IsActive = true;
77
+ expect(service.IsActive).toBe(true);
78
+ });
79
+ it('should return false when session is not active', () => {
80
+ createdSession.IsActive = false;
81
+ expect(service.IsActive).toBe(false);
82
+ });
83
+ });
84
+ describe('Tool registration', () => {
85
+ it('should delegate RegisterTool to the session', () => {
86
+ const tool = { Name: 'TestTool', Handler: vi.fn() };
87
+ service.RegisterTool(tool);
88
+ expect(createdSession.RegisterTool).toHaveBeenCalledWith(tool);
89
+ });
90
+ it('should delegate UnregisterTool to the session', () => {
91
+ service.UnregisterTool('TestTool');
92
+ expect(createdSession.UnregisterTool).toHaveBeenCalledWith('TestTool');
93
+ });
94
+ it('should delegate GetRegisteredTools to the session', () => {
95
+ const tools = [{ Name: 'Tool1' }, { Name: 'Tool2' }];
96
+ createdSession.GetRegisteredTools.mockReturnValue(tools);
97
+ expect(service.GetRegisteredTools()).toBe(tools);
98
+ });
99
+ });
100
+ describe('Tool decoration', () => {
101
+ it('should delegate RegisterToolDecorator to the session', () => {
102
+ const decorator = vi.fn();
103
+ service.RegisterToolDecorator('MyTool', decorator);
104
+ expect(createdSession.RegisterToolDecorator).toHaveBeenCalledWith('MyTool', decorator);
105
+ });
106
+ it('should delegate SetDecoratorContext to the session', () => {
107
+ const context = { activeConversationId: 'conv-123' };
108
+ service.SetDecoratorContext(context);
109
+ expect(createdSession.SetDecoratorContext).toHaveBeenCalledWith(context);
110
+ });
111
+ it('should delegate DecorateAndSendTools to the session', async () => {
112
+ const baseTools = [{ Name: 'BaseTool' }];
113
+ await service.DecorateAndSendTools(baseTools);
114
+ expect(createdSession.DecorateAndSendTools).toHaveBeenCalledWith(baseTools);
115
+ });
116
+ });
117
+ describe('Session lifecycle', () => {
118
+ it('should delegate StartSession to the session', () => {
119
+ service.StartSession('session-abc');
120
+ expect(createdSession.StartSession).toHaveBeenCalledWith('session-abc');
121
+ });
122
+ it('should delegate StopSession to the session', () => {
123
+ service.StopSession();
124
+ expect(createdSession.StopSession).toHaveBeenCalled();
125
+ });
126
+ });
127
+ describe('Agent execution', () => {
128
+ it('should delegate RunAgent to the session', async () => {
129
+ const params = { AgentId: 'agent-1', Message: 'Hello' };
130
+ const result = await service.RunAgent(params);
131
+ expect(createdSession.RunAgent).toHaveBeenCalledWith(params);
132
+ expect(result).toEqual({ Success: true });
133
+ });
134
+ it('should delegate RunAgentFromConversationDetail to the session', async () => {
135
+ const params = { ConversationDetailId: 'detail-1' };
136
+ const result = await service.RunAgentFromConversationDetail(params);
137
+ expect(createdSession.RunAgentFromConversationDetail).toHaveBeenCalledWith(params);
138
+ expect(result).toEqual({ Success: true });
139
+ });
140
+ });
141
+ describe('Angular lifecycle', () => {
142
+ it('should call Dispose on the session when destroyed', () => {
143
+ service.ngOnDestroy();
144
+ expect(createdSession.Dispose).toHaveBeenCalled();
145
+ });
146
+ });
147
+ });
148
+ //# sourceMappingURL=agent-client-service.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-client-service.test.js","sourceRoot":"","sources":["../../src/__tests__/agent-client-service.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, vi, beforeEach } from 'vitest';\n\n/**\n * Tests for AgentClientService — verifies pass-through delegation to AgentClientSession.\n */\n\nvi.mock('@angular/core', () => ({\n Injectable: () => (target: Function) => target,\n OnDestroy: class {},\n}));\n\n// Track the mock session created by the constructor\nlet createdSession: Record<string, unknown>;\n\nvi.mock('@memberjunction/ai-agent-client', () => {\n // Factory runs at module load — must define mock inside\n function MockAgentClientSession() {\n const session: Record<string, unknown> = {\n ToolRequested$: { subscribe: () => {} },\n ToolExecuted$: { subscribe: () => {} },\n AgentProgress$: { subscribe: () => {} },\n SessionActive$: { subscribe: () => {} },\n Error$: { subscribe: () => {} },\n SessionId: null,\n IsActive: false,\n RegisterTool: vi.fn(),\n UnregisterTool: vi.fn(),\n GetRegisteredTools: vi.fn().mockReturnValue([]),\n RegisterToolDecorator: vi.fn(),\n SetDecoratorContext: vi.fn(),\n DecorateAndSendTools: vi.fn().mockResolvedValue(undefined),\n StartSession: vi.fn(),\n StopSession: vi.fn(),\n RunAgent: vi.fn().mockResolvedValue({ Success: true }),\n RunAgentFromConversationDetail: vi.fn().mockResolvedValue({ Success: true }),\n Dispose: vi.fn(),\n };\n createdSession = session;\n return session;\n }\n return {\n AgentClientSession: MockAgentClientSession,\n };\n});\n\nimport { AgentClientService } from '../lib/agent-client.service';\n\ndescribe('AgentClientService', () => {\n let service: AgentClientService;\n\n beforeEach(() => {\n vi.clearAllMocks();\n service = new AgentClientService();\n });\n\n describe('Observable pass-throughs', () => {\n it('should expose ToolRequested$ from the session', () => {\n expect(service.ToolRequested$).toBe(createdSession.ToolRequested$);\n });\n\n it('should expose ToolExecuted$ from the session', () => {\n expect(service.ToolExecuted$).toBe(createdSession.ToolExecuted$);\n });\n\n it('should expose AgentProgress$ from the session', () => {\n expect(service.AgentProgress$).toBe(createdSession.AgentProgress$);\n });\n\n it('should expose SessionActive$ from the session', () => {\n expect(service.SessionActive$).toBe(createdSession.SessionActive$);\n });\n\n it('should expose Error$ from the session', () => {\n expect(service.Error$).toBe(createdSession.Error$);\n });\n });\n\n describe('Session state', () => {\n it('should return SessionId from the session', () => {\n createdSession.SessionId = 'test-session-123';\n expect(service.SessionId).toBe('test-session-123');\n });\n\n it('should return null SessionId when no session is active', () => {\n createdSession.SessionId = null;\n expect(service.SessionId).toBeNull();\n });\n\n it('should return IsActive from the session', () => {\n createdSession.IsActive = true;\n expect(service.IsActive).toBe(true);\n });\n\n it('should return false when session is not active', () => {\n createdSession.IsActive = false;\n expect(service.IsActive).toBe(false);\n });\n });\n\n describe('Tool registration', () => {\n it('should delegate RegisterTool to the session', () => {\n const tool = { Name: 'TestTool', Handler: vi.fn() };\n service.RegisterTool(tool as never);\n expect(createdSession.RegisterTool).toHaveBeenCalledWith(tool);\n });\n\n it('should delegate UnregisterTool to the session', () => {\n service.UnregisterTool('TestTool');\n expect(createdSession.UnregisterTool).toHaveBeenCalledWith('TestTool');\n });\n\n it('should delegate GetRegisteredTools to the session', () => {\n const tools = [{ Name: 'Tool1' }, { Name: 'Tool2' }];\n (createdSession.GetRegisteredTools as ReturnType<typeof vi.fn>).mockReturnValue(tools);\n expect(service.GetRegisteredTools()).toBe(tools);\n });\n });\n\n describe('Tool decoration', () => {\n it('should delegate RegisterToolDecorator to the session', () => {\n const decorator = vi.fn();\n service.RegisterToolDecorator('MyTool', decorator as never);\n expect(createdSession.RegisterToolDecorator).toHaveBeenCalledWith('MyTool', decorator);\n });\n\n it('should delegate SetDecoratorContext to the session', () => {\n const context = { activeConversationId: 'conv-123' };\n service.SetDecoratorContext(context as never);\n expect(createdSession.SetDecoratorContext).toHaveBeenCalledWith(context);\n });\n\n it('should delegate DecorateAndSendTools to the session', async () => {\n const baseTools = [{ Name: 'BaseTool' }];\n await service.DecorateAndSendTools(baseTools as never);\n expect(createdSession.DecorateAndSendTools).toHaveBeenCalledWith(baseTools);\n });\n });\n\n describe('Session lifecycle', () => {\n it('should delegate StartSession to the session', () => {\n service.StartSession('session-abc');\n expect(createdSession.StartSession).toHaveBeenCalledWith('session-abc');\n });\n\n it('should delegate StopSession to the session', () => {\n service.StopSession();\n expect(createdSession.StopSession).toHaveBeenCalled();\n });\n });\n\n describe('Agent execution', () => {\n it('should delegate RunAgent to the session', async () => {\n const params = { AgentId: 'agent-1', Message: 'Hello' };\n const result = await service.RunAgent(params as never);\n expect(createdSession.RunAgent).toHaveBeenCalledWith(params);\n expect(result).toEqual({ Success: true });\n });\n\n it('should delegate RunAgentFromConversationDetail to the session', async () => {\n const params = { ConversationDetailId: 'detail-1' };\n const result = await service.RunAgentFromConversationDetail(params as never);\n expect(createdSession.RunAgentFromConversationDetail).toHaveBeenCalledWith(params);\n expect(result).toEqual({ Success: true });\n });\n });\n\n describe('Angular lifecycle', () => {\n it('should call Dispose on the session when destroyed', () => {\n service.ngOnDestroy();\n expect(createdSession.Dispose).toHaveBeenCalled();\n });\n });\n});\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,7 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ describe('@memberjunction/ng-agent-client', () => {
3
+ it('should have a passing test', () => {
4
+ expect(true).toBe(true);
5
+ });
6
+ });
7
+ //# sourceMappingURL=index.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/__tests__/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, it, expect } from 'vitest';\n\ndescribe('@memberjunction/ng-agent-client', () => {\n it('should have a passing test', () => {\n expect(true).toBe(true);\n });\n});\n"]}
@@ -1,73 +1,72 @@
1
1
  /**
2
2
  * @fileoverview Angular adapter for the MJ Agent Client SDK.
3
3
  *
4
- * Provides an injectable service that wraps AgentClientSession with
5
- * RxJS observables for reactive Angular consumption.
4
+ * Thin Angular wrapper around AgentClientSession from @memberjunction/ai-agent-client.
5
+ * Provides Angular dependency injection and lifecycle management.
6
+ *
7
+ * This service does NOT contain business logic, GraphQL code, or tool handlers.
8
+ * All heavy lifting is in the core SDK. The consuming application registers tools
9
+ * and handles events as appropriate for its context.
6
10
  *
7
11
  * @module @memberjunction/ng-agent-client
8
12
  */
9
13
  import { OnDestroy } from '@angular/core';
10
- import { BehaviorSubject, Subject } from 'rxjs';
11
- import { ClientToolDefinition, AgentMessage, AgentProgress, AgentError, ClientToolRequest, TransportOptions } from '@memberjunction/ai-agent-client';
14
+ import { ClientToolDefinition, ClientToolMetadata, ClientToolDecorator, ClientToolDecoratorContext, ClientToolRequestEvent, ClientToolResultEvent, SessionError, AgentProgress, RunAgentParams, RunAgentFromConversationDetailParams, RunAgentResult } from '@memberjunction/ai-agent-client';
15
+ import { Observable } from 'rxjs';
12
16
  import * as i0 from "@angular/core";
13
17
  /**
14
- * Angular injectable service that wraps the framework-agnostic Agent Client SDK.
18
+ * Angular injectable wrapper around the framework-agnostic AgentClientSession.
19
+ *
20
+ * Provides:
21
+ * - Angular DI (providedIn: root singleton)
22
+ * - Automatic cleanup via ngOnDestroy
23
+ * - Pass-through access to all SDK observables and methods
15
24
  *
16
- * Provides RxJS observable bridges for agent messages, progress, and connection state.
17
- * Pre-registers built-in navigation and component tools.
25
+ * Usage:
26
+ * ```typescript
27
+ * const agentClient = inject(AgentClientService);
28
+ * agentClient.RegisterTool({ Name: 'NavigateToRecord', ... });
29
+ * agentClient.StartSession('session-123');
30
+ * agentClient.ToolRequested$.subscribe(e => console.log('Tool:', e));
31
+ * ```
18
32
  */
19
33
  export declare class AgentClientService implements OnDestroy {
20
34
  private session;
21
- private toolRegistry;
22
- private router;
23
- /** Stream of all agent messages received during the session */
24
- AgentMessages$: BehaviorSubject<AgentMessage[]>;
25
- /** Whether the client is currently connected to an agent */
26
- IsConnected$: BehaviorSubject<boolean>;
27
- /** Stream of agent progress updates */
28
- Progress$: Subject<AgentProgress>;
29
- /** Stream of agent errors */
30
- Errors$: Subject<AgentError>;
31
- /** Stream of client tool requests (for UI visualization) */
32
- ToolRequests$: Subject<ClientToolRequest>;
33
- constructor();
34
- /**
35
- * Connect to an agent using WebSocket transport.
36
- *
37
- * @param url - The WebSocket URL of the agent server
38
- * @param agentId - The ID of the agent to connect to
39
- * @param conversationId - Optional existing conversation to resume
40
- * @param options - Optional transport options (auth, reconnection)
41
- */
42
- ConnectToAgent(url: string, agentId: string, conversationId?: string, options?: TransportOptions): Promise<void>;
43
- /**
44
- * Send a user message to the connected agent.
45
- */
46
- SendMessage(content: string): Promise<void>;
47
- /**
48
- * Disconnect from the current agent session.
49
- */
50
- Disconnect(): Promise<void>;
51
- /**
52
- * Register a custom client-side tool.
53
- */
35
+ /** Emitted when a tool request is received from the server (before execution) */
36
+ get ToolRequested$(): Observable<ClientToolRequestEvent>;
37
+ /** Emitted after a tool has been executed (with result) */
38
+ get ToolExecuted$(): Observable<ClientToolResultEvent>;
39
+ /** Emitted when agent execution progress updates arrive */
40
+ get AgentProgress$(): Observable<AgentProgress>;
41
+ /** Emitted when session state changes */
42
+ get SessionActive$(): Observable<boolean>;
43
+ /** Emitted on errors during tool execution or communication */
44
+ get Error$(): Observable<SessionError>;
45
+ /** The current session ID, or null if no session is active */
46
+ get SessionId(): string | null;
47
+ /** Whether a session is currently active */
48
+ get IsActive(): boolean;
49
+ /** Register a client-side tool handler */
54
50
  RegisterTool(tool: ClientToolDefinition): void;
55
- /**
56
- * Get the current conversation ID.
57
- */
58
- get ConversationId(): string | null;
59
- /**
60
- * Clean up on service destruction.
61
- */
51
+ /** Unregister a client-side tool */
52
+ UnregisterTool(toolName: string): void;
53
+ /** Get all registered tool definitions */
54
+ GetRegisteredTools(): ClientToolDefinition[];
55
+ /** Register a decorator for runtime enrichment of a metadata-driven tool */
56
+ RegisterToolDecorator(toolName: string, decorator: ClientToolDecorator): void;
57
+ /** Set the runtime context for decorators */
58
+ SetDecoratorContext(context: ClientToolDecoratorContext): void;
59
+ /** Decorate base tools and send enriched definitions to the server */
60
+ DecorateAndSendTools(baseTools: ClientToolMetadata[]): Promise<void>;
61
+ /** Start listening for client tool requests for a session */
62
+ StartSession(sessionId: string): void;
63
+ /** Stop listening and clean up the session */
64
+ StopSession(): void;
65
+ /** Run an agent with a message */
66
+ RunAgent(params: RunAgentParams): Promise<RunAgentResult>;
67
+ /** Run an agent from an existing conversation detail */
68
+ RunAgentFromConversationDetail(params: RunAgentFromConversationDetailParams): Promise<RunAgentResult>;
62
69
  ngOnDestroy(): void;
63
- /**
64
- * Set up event handlers on the session that feed into RxJS observables.
65
- */
66
- private setupSessionHandlers;
67
- /**
68
- * Register built-in navigation and component tools.
69
- */
70
- private registerBuiltInTools;
71
70
  static ɵfac: i0.ɵɵFactoryDeclaration<AgentClientService, never>;
72
71
  static ɵprov: i0.ɵɵInjectableDeclaration<AgentClientService>;
73
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"agent-client.service.d.ts","sourceRoot":"","sources":["../../src/lib/agent-client.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAc,SAAS,EAAU,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAIH,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EACnB,MAAM,iCAAiC,CAAC;;AAEzC;;;;;GAKG;AACH,qBACa,kBAAmB,YAAW,SAAS;IAChD,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,YAAY,CAA4B;IAChD,OAAO,CAAC,MAAM,CAAkB;IAEhC,+DAA+D;IACxD,cAAc,kCAA2C;IAEhE,4DAA4D;IACrD,YAAY,2BAAuC;IAE1D,uCAAuC;IAChC,SAAS,yBAAgC;IAEhD,6BAA6B;IACtB,OAAO,sBAA6B;IAE3C,4DAA4D;IACrD,aAAa,6BAAoC;;IAMxD;;;;;;;OAOG;IACU,cAAc,CACvB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC,IAAI,CAAC;IAchB;;OAEG;IACU,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxD;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASxC;;OAEG;IACI,YAAY,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAIrD;;OAEG;IACH,IAAW,cAAc,IAAI,MAAM,GAAG,IAAI,CAEzC;IAED;;OAEG;IACI,WAAW,IAAI,IAAI;IAU1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAwB5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;yCAlInB,kBAAkB;6CAAlB,kBAAkB;CAwL9B"}
1
+ {"version":3,"file":"agent-client.service.d.ts","sourceRoot":"","sources":["../../src/lib/agent-client.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAc,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAEH,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,0BAA0B,EAC1B,sBAAsB,EACtB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,oCAAoC,EACpC,cAAc,EACjB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;;AAElC;;;;;;;;;;;;;;;GAeG;AACH,qBACa,kBAAmB,YAAW,SAAS;IAChD,OAAO,CAAC,OAAO,CAA4B;IAI3C,iFAAiF;IACjF,IAAW,cAAc,IAAI,UAAU,CAAC,sBAAsB,CAAC,CAE9D;IAED,2DAA2D;IAC3D,IAAW,aAAa,IAAI,UAAU,CAAC,qBAAqB,CAAC,CAE5D;IAED,2DAA2D;IAC3D,IAAW,cAAc,IAAI,UAAU,CAAC,aAAa,CAAC,CAErD;IAED,yCAAyC;IACzC,IAAW,cAAc,IAAI,UAAU,CAAC,OAAO,CAAC,CAE/C;IAED,+DAA+D;IAC/D,IAAW,MAAM,IAAI,UAAU,CAAC,YAAY,CAAC,CAE5C;IAID,8DAA8D;IAC9D,IAAW,SAAS,IAAI,MAAM,GAAG,IAAI,CAEpC;IAED,4CAA4C;IAC5C,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAID,0CAA0C;IACnC,YAAY,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI;IAIrD,oCAAoC;IAC7B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI7C,0CAA0C;IACnC,kBAAkB,IAAI,oBAAoB,EAAE;IAMnD,4EAA4E;IACrE,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,GAAG,IAAI;IAIpF,6CAA6C;IACtC,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI;IAIrE,sEAAsE;IACzD,oBAAoB,CAAC,SAAS,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjF,6DAA6D;IACtD,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI5C,8CAA8C;IACvC,WAAW,IAAI,IAAI;IAM1B,kCAAkC;IACrB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAItE,wDAAwD;IAC3C,8BAA8B,CAAC,MAAM,EAAE,oCAAoC,GAAG,OAAO,CAAC,cAAc,CAAC;IAM3G,WAAW,IAAI,IAAI;yCAtGjB,kBAAkB;6CAAlB,kBAAkB;CAyG9B"}
@@ -1,178 +1,113 @@
1
1
  /**
2
2
  * @fileoverview Angular adapter for the MJ Agent Client SDK.
3
3
  *
4
- * Provides an injectable service that wraps AgentClientSession with
5
- * RxJS observables for reactive Angular consumption.
4
+ * Thin Angular wrapper around AgentClientSession from @memberjunction/ai-agent-client.
5
+ * Provides Angular dependency injection and lifecycle management.
6
+ *
7
+ * This service does NOT contain business logic, GraphQL code, or tool handlers.
8
+ * All heavy lifting is in the core SDK. The consuming application registers tools
9
+ * and handles events as appropriate for its context.
6
10
  *
7
11
  * @module @memberjunction/ng-agent-client
8
12
  */
9
- import { Injectable, inject } from '@angular/core';
10
- import { Router } from '@angular/router';
11
- import { BehaviorSubject, Subject } from 'rxjs';
12
- import { AgentClientSession, ClientToolRegistry, WebSocketTransport, } from '@memberjunction/ai-agent-client';
13
+ import { Injectable } from '@angular/core';
14
+ import { AgentClientSession, } from '@memberjunction/ai-agent-client';
13
15
  import * as i0 from "@angular/core";
14
16
  /**
15
- * Angular injectable service that wraps the framework-agnostic Agent Client SDK.
17
+ * Angular injectable wrapper around the framework-agnostic AgentClientSession.
18
+ *
19
+ * Provides:
20
+ * - Angular DI (providedIn: root singleton)
21
+ * - Automatic cleanup via ngOnDestroy
22
+ * - Pass-through access to all SDK observables and methods
16
23
  *
17
- * Provides RxJS observable bridges for agent messages, progress, and connection state.
18
- * Pre-registers built-in navigation and component tools.
24
+ * Usage:
25
+ * ```typescript
26
+ * const agentClient = inject(AgentClientService);
27
+ * agentClient.RegisterTool({ Name: 'NavigateToRecord', ... });
28
+ * agentClient.StartSession('session-123');
29
+ * agentClient.ToolRequested$.subscribe(e => console.log('Tool:', e));
30
+ * ```
19
31
  */
20
32
  export class AgentClientService {
21
- session = null;
22
- toolRegistry = new ClientToolRegistry();
23
- router = inject(Router);
24
- /** Stream of all agent messages received during the session */
25
- AgentMessages$ = new BehaviorSubject([]);
26
- /** Whether the client is currently connected to an agent */
27
- IsConnected$ = new BehaviorSubject(false);
28
- /** Stream of agent progress updates */
29
- Progress$ = new Subject();
30
- /** Stream of agent errors */
31
- Errors$ = new Subject();
32
- /** Stream of client tool requests (for UI visualization) */
33
- ToolRequests$ = new Subject();
34
- constructor() {
35
- this.registerBuiltInTools();
36
- }
37
- /**
38
- * Connect to an agent using WebSocket transport.
39
- *
40
- * @param url - The WebSocket URL of the agent server
41
- * @param agentId - The ID of the agent to connect to
42
- * @param conversationId - Optional existing conversation to resume
43
- * @param options - Optional transport options (auth, reconnection)
44
- */
45
- async ConnectToAgent(url, agentId, conversationId, options) {
46
- // Clean up any existing session
47
- await this.Disconnect();
48
- const transport = new WebSocketTransport();
49
- await transport.Connect(url, options);
50
- this.session = new AgentClientSession(transport, this.toolRegistry);
51
- this.setupSessionHandlers();
52
- await this.session.Connect(agentId, conversationId);
53
- this.IsConnected$.next(true);
54
- }
55
- /**
56
- * Send a user message to the connected agent.
57
- */
58
- async SendMessage(content) {
59
- if (!this.session) {
60
- throw new Error('Not connected to an agent. Call ConnectToAgent() first.');
61
- }
62
- await this.session.SendMessage(content);
63
- }
64
- /**
65
- * Disconnect from the current agent session.
66
- */
67
- async Disconnect() {
68
- if (this.session) {
69
- await this.session.Disconnect();
70
- this.session = null;
71
- this.IsConnected$.next(false);
72
- this.AgentMessages$.next([]);
73
- }
74
- }
75
- /**
76
- * Register a custom client-side tool.
77
- */
33
+ session = new AgentClientSession();
34
+ // --- Observable Pass-Through ---
35
+ /** Emitted when a tool request is received from the server (before execution) */
36
+ get ToolRequested$() {
37
+ return this.session.ToolRequested$;
38
+ }
39
+ /** Emitted after a tool has been executed (with result) */
40
+ get ToolExecuted$() {
41
+ return this.session.ToolExecuted$;
42
+ }
43
+ /** Emitted when agent execution progress updates arrive */
44
+ get AgentProgress$() {
45
+ return this.session.AgentProgress$;
46
+ }
47
+ /** Emitted when session state changes */
48
+ get SessionActive$() {
49
+ return this.session.SessionActive$;
50
+ }
51
+ /** Emitted on errors during tool execution or communication */
52
+ get Error$() {
53
+ return this.session.Error$;
54
+ }
55
+ // --- Session State ---
56
+ /** The current session ID, or null if no session is active */
57
+ get SessionId() {
58
+ return this.session.SessionId;
59
+ }
60
+ /** Whether a session is currently active */
61
+ get IsActive() {
62
+ return this.session.IsActive;
63
+ }
64
+ // --- Tool Registration ---
65
+ /** Register a client-side tool handler */
78
66
  RegisterTool(tool) {
79
- this.toolRegistry.Register(tool);
67
+ this.session.RegisterTool(tool);
68
+ }
69
+ /** Unregister a client-side tool */
70
+ UnregisterTool(toolName) {
71
+ this.session.UnregisterTool(toolName);
72
+ }
73
+ /** Get all registered tool definitions */
74
+ GetRegisteredTools() {
75
+ return this.session.GetRegisteredTools();
76
+ }
77
+ // --- Tool Decoration ---
78
+ /** Register a decorator for runtime enrichment of a metadata-driven tool */
79
+ RegisterToolDecorator(toolName, decorator) {
80
+ this.session.RegisterToolDecorator(toolName, decorator);
81
+ }
82
+ /** Set the runtime context for decorators */
83
+ SetDecoratorContext(context) {
84
+ this.session.SetDecoratorContext(context);
85
+ }
86
+ /** Decorate base tools and send enriched definitions to the server */
87
+ async DecorateAndSendTools(baseTools) {
88
+ return this.session.DecorateAndSendTools(baseTools);
89
+ }
90
+ // --- Session Lifecycle ---
91
+ /** Start listening for client tool requests for a session */
92
+ StartSession(sessionId) {
93
+ this.session.StartSession(sessionId);
94
+ }
95
+ /** Stop listening and clean up the session */
96
+ StopSession() {
97
+ this.session.StopSession();
98
+ }
99
+ // --- Agent Execution ---
100
+ /** Run an agent with a message */
101
+ async RunAgent(params) {
102
+ return this.session.RunAgent(params);
80
103
  }
81
- /**
82
- * Get the current conversation ID.
83
- */
84
- get ConversationId() {
85
- return this.session?.ConversationId ?? null;
104
+ /** Run an agent from an existing conversation detail */
105
+ async RunAgentFromConversationDetail(params) {
106
+ return this.session.RunAgentFromConversationDetail(params);
86
107
  }
87
- /**
88
- * Clean up on service destruction.
89
- */
108
+ // --- Angular Lifecycle ---
90
109
  ngOnDestroy() {
91
- // Fire-and-forget disconnect on destroy
92
- this.Disconnect().catch(() => { });
93
- this.AgentMessages$.complete();
94
- this.IsConnected$.complete();
95
- this.Progress$.complete();
96
- this.Errors$.complete();
97
- this.ToolRequests$.complete();
98
- }
99
- /**
100
- * Set up event handlers on the session that feed into RxJS observables.
101
- */
102
- setupSessionHandlers() {
103
- if (!this.session)
104
- return;
105
- this.session.OnAgentMessage((msg) => {
106
- const current = this.AgentMessages$.value;
107
- this.AgentMessages$.next([...current, msg]);
108
- });
109
- this.session.OnProgress((progress) => {
110
- this.Progress$.next(progress);
111
- });
112
- this.session.OnError((error) => {
113
- this.Errors$.next(error);
114
- if (error.Code === 'DISCONNECTED') {
115
- this.IsConnected$.next(false);
116
- }
117
- });
118
- this.session.OnToolRequest((req) => {
119
- this.ToolRequests$.next(req);
120
- });
121
- }
122
- /**
123
- * Register built-in navigation and component tools.
124
- */
125
- registerBuiltInTools() {
126
- this.toolRegistry.Register({
127
- Name: 'navigate_to_record',
128
- Description: 'Navigate the browser to a specific entity record in MJ Explorer',
129
- ParameterSchema: {
130
- type: 'object',
131
- properties: {
132
- EntityName: { type: 'string' },
133
- RecordID: { type: 'string' },
134
- },
135
- required: ['EntityName', 'RecordID'],
136
- },
137
- Handler: async (params) => {
138
- const entityName = String(params['EntityName']);
139
- const recordId = String(params['RecordID']);
140
- await this.router.navigate(['/resource', 'entity', entityName, recordId]);
141
- return { Success: true, Data: { Navigated: true } };
142
- },
143
- });
144
- this.toolRegistry.Register({
145
- Name: 'navigate_to_app',
146
- Description: 'Switch to a different MJ Explorer application',
147
- ParameterSchema: {
148
- type: 'object',
149
- properties: {
150
- AppName: { type: 'string' },
151
- },
152
- required: ['AppName'],
153
- },
154
- Handler: async (params) => {
155
- const appName = String(params['AppName']);
156
- await this.router.navigate(['/app', appName]);
157
- return { Success: true, Data: { Navigated: true } };
158
- },
159
- });
160
- this.toolRegistry.Register({
161
- Name: 'navigate_to_tab',
162
- Description: 'Switch to a specific tab within the current application',
163
- ParameterSchema: {
164
- type: 'object',
165
- properties: {
166
- TabName: { type: 'string' },
167
- },
168
- required: ['TabName'],
169
- },
170
- Handler: async (params) => {
171
- // Tab navigation is handled via the app's internal routing
172
- const tabName = String(params['TabName']);
173
- return { Success: true, Data: { TabName: tabName, Note: 'Tab switch requested' } };
174
- },
175
- });
110
+ this.session.Dispose();
176
111
  }
177
112
  static ɵfac = function AgentClientService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AgentClientService)(); };
178
113
  static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: AgentClientService, factory: AgentClientService.ɵfac, providedIn: 'root' });
@@ -180,5 +115,5 @@ export class AgentClientService {
180
115
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AgentClientService, [{
181
116
  type: Injectable,
182
117
  args: [{ providedIn: 'root' }]
183
- }], () => [], null); })();
118
+ }], null, null); })();
184
119
  //# sourceMappingURL=agent-client.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-client.service.js","sourceRoot":"","sources":["../../src/lib/agent-client.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Angular adapter for the MJ Agent Client SDK.\n *\n * Provides an injectable service that wraps AgentClientSession with\n * RxJS observables for reactive Angular consumption.\n *\n * @module @memberjunction/ng-agent-client\n */\n\nimport { Injectable, OnDestroy, inject } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { BehaviorSubject, Subject } from 'rxjs';\nimport {\n AgentClientSession,\n ClientToolRegistry,\n WebSocketTransport,\n ClientToolDefinition,\n AgentMessage,\n AgentProgress,\n AgentError,\n ClientToolRequest,\n TransportOptions,\n} from '@memberjunction/ai-agent-client';\n\n/**\n * Angular injectable service that wraps the framework-agnostic Agent Client SDK.\n *\n * Provides RxJS observable bridges for agent messages, progress, and connection state.\n * Pre-registers built-in navigation and component tools.\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentClientService implements OnDestroy {\n private session: AgentClientSession | null = null;\n private toolRegistry = new ClientToolRegistry();\n private router = inject(Router);\n\n /** Stream of all agent messages received during the session */\n public AgentMessages$ = new BehaviorSubject<AgentMessage[]>([]);\n\n /** Whether the client is currently connected to an agent */\n public IsConnected$ = new BehaviorSubject<boolean>(false);\n\n /** Stream of agent progress updates */\n public Progress$ = new Subject<AgentProgress>();\n\n /** Stream of agent errors */\n public Errors$ = new Subject<AgentError>();\n\n /** Stream of client tool requests (for UI visualization) */\n public ToolRequests$ = new Subject<ClientToolRequest>();\n\n constructor() {\n this.registerBuiltInTools();\n }\n\n /**\n * Connect to an agent using WebSocket transport.\n *\n * @param url - The WebSocket URL of the agent server\n * @param agentId - The ID of the agent to connect to\n * @param conversationId - Optional existing conversation to resume\n * @param options - Optional transport options (auth, reconnection)\n */\n public async ConnectToAgent(\n url: string,\n agentId: string,\n conversationId?: string,\n options?: TransportOptions\n ): Promise<void> {\n // Clean up any existing session\n await this.Disconnect();\n\n const transport = new WebSocketTransport();\n await transport.Connect(url, options);\n\n this.session = new AgentClientSession(transport, this.toolRegistry);\n this.setupSessionHandlers();\n\n await this.session.Connect(agentId, conversationId);\n this.IsConnected$.next(true);\n }\n\n /**\n * Send a user message to the connected agent.\n */\n public async SendMessage(content: string): Promise<void> {\n if (!this.session) {\n throw new Error('Not connected to an agent. Call ConnectToAgent() first.');\n }\n await this.session.SendMessage(content);\n }\n\n /**\n * Disconnect from the current agent session.\n */\n public async Disconnect(): Promise<void> {\n if (this.session) {\n await this.session.Disconnect();\n this.session = null;\n this.IsConnected$.next(false);\n this.AgentMessages$.next([]);\n }\n }\n\n /**\n * Register a custom client-side tool.\n */\n public RegisterTool(tool: ClientToolDefinition): void {\n this.toolRegistry.Register(tool);\n }\n\n /**\n * Get the current conversation ID.\n */\n public get ConversationId(): string | null {\n return this.session?.ConversationId ?? null;\n }\n\n /**\n * Clean up on service destruction.\n */\n public ngOnDestroy(): void {\n // Fire-and-forget disconnect on destroy\n this.Disconnect().catch(() => { /* intentional: best-effort cleanup */ });\n this.AgentMessages$.complete();\n this.IsConnected$.complete();\n this.Progress$.complete();\n this.Errors$.complete();\n this.ToolRequests$.complete();\n }\n\n /**\n * Set up event handlers on the session that feed into RxJS observables.\n */\n private setupSessionHandlers(): void {\n if (!this.session) return;\n\n this.session.OnAgentMessage((msg) => {\n const current = this.AgentMessages$.value;\n this.AgentMessages$.next([...current, msg]);\n });\n\n this.session.OnProgress((progress) => {\n this.Progress$.next(progress);\n });\n\n this.session.OnError((error) => {\n this.Errors$.next(error);\n if (error.Code === 'DISCONNECTED') {\n this.IsConnected$.next(false);\n }\n });\n\n this.session.OnToolRequest((req) => {\n this.ToolRequests$.next(req);\n });\n }\n\n /**\n * Register built-in navigation and component tools.\n */\n private registerBuiltInTools(): void {\n this.toolRegistry.Register({\n Name: 'navigate_to_record',\n Description: 'Navigate the browser to a specific entity record in MJ Explorer',\n ParameterSchema: {\n type: 'object',\n properties: {\n EntityName: { type: 'string' },\n RecordID: { type: 'string' },\n },\n required: ['EntityName', 'RecordID'],\n },\n Handler: async (params) => {\n const entityName = String(params['EntityName']);\n const recordId = String(params['RecordID']);\n await this.router.navigate(['/resource', 'entity', entityName, recordId]);\n return { Success: true, Data: { Navigated: true } };\n },\n });\n\n this.toolRegistry.Register({\n Name: 'navigate_to_app',\n Description: 'Switch to a different MJ Explorer application',\n ParameterSchema: {\n type: 'object',\n properties: {\n AppName: { type: 'string' },\n },\n required: ['AppName'],\n },\n Handler: async (params) => {\n const appName = String(params['AppName']);\n await this.router.navigate(['/app', appName]);\n return { Success: true, Data: { Navigated: true } };\n },\n });\n\n this.toolRegistry.Register({\n Name: 'navigate_to_tab',\n Description: 'Switch to a specific tab within the current application',\n ParameterSchema: {\n type: 'object',\n properties: {\n TabName: { type: 'string' },\n },\n required: ['TabName'],\n },\n Handler: async (params) => {\n // Tab navigation is handled via the app's internal routing\n const tabName = String(params['TabName']);\n return { Success: true, Data: { TabName: tabName, Note: 'Tab switch requested' } };\n },\n });\n }\n}\n"]}
1
+ {"version":3,"file":"agent-client.service.js","sourceRoot":"","sources":["../../src/lib/agent-client.service.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Angular adapter for the MJ Agent Client SDK.\n *\n * Thin Angular wrapper around AgentClientSession from @memberjunction/ai-agent-client.\n * Provides Angular dependency injection and lifecycle management.\n *\n * This service does NOT contain business logic, GraphQL code, or tool handlers.\n * All heavy lifting is in the core SDK. The consuming application registers tools\n * and handles events as appropriate for its context.\n *\n * @module @memberjunction/ng-agent-client\n */\n\nimport { Injectable, OnDestroy } from '@angular/core';\nimport {\n AgentClientSession,\n ClientToolDefinition,\n ClientToolMetadata,\n ClientToolDecorator,\n ClientToolDecoratorContext,\n ClientToolRequestEvent,\n ClientToolResultEvent,\n SessionError,\n AgentProgress,\n RunAgentParams,\n RunAgentFromConversationDetailParams,\n RunAgentResult,\n} from '@memberjunction/ai-agent-client';\nimport { Observable } from 'rxjs';\n\n/**\n * Angular injectable wrapper around the framework-agnostic AgentClientSession.\n *\n * Provides:\n * - Angular DI (providedIn: root singleton)\n * - Automatic cleanup via ngOnDestroy\n * - Pass-through access to all SDK observables and methods\n *\n * Usage:\n * ```typescript\n * const agentClient = inject(AgentClientService);\n * agentClient.RegisterTool({ Name: 'NavigateToRecord', ... });\n * agentClient.StartSession('session-123');\n * agentClient.ToolRequested$.subscribe(e => console.log('Tool:', e));\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class AgentClientService implements OnDestroy {\n private session = new AgentClientSession();\n\n // --- Observable Pass-Through ---\n\n /** Emitted when a tool request is received from the server (before execution) */\n public get ToolRequested$(): Observable<ClientToolRequestEvent> {\n return this.session.ToolRequested$;\n }\n\n /** Emitted after a tool has been executed (with result) */\n public get ToolExecuted$(): Observable<ClientToolResultEvent> {\n return this.session.ToolExecuted$;\n }\n\n /** Emitted when agent execution progress updates arrive */\n public get AgentProgress$(): Observable<AgentProgress> {\n return this.session.AgentProgress$;\n }\n\n /** Emitted when session state changes */\n public get SessionActive$(): Observable<boolean> {\n return this.session.SessionActive$;\n }\n\n /** Emitted on errors during tool execution or communication */\n public get Error$(): Observable<SessionError> {\n return this.session.Error$;\n }\n\n // --- Session State ---\n\n /** The current session ID, or null if no session is active */\n public get SessionId(): string | null {\n return this.session.SessionId;\n }\n\n /** Whether a session is currently active */\n public get IsActive(): boolean {\n return this.session.IsActive;\n }\n\n // --- Tool Registration ---\n\n /** Register a client-side tool handler */\n public RegisterTool(tool: ClientToolDefinition): void {\n this.session.RegisterTool(tool);\n }\n\n /** Unregister a client-side tool */\n public UnregisterTool(toolName: string): void {\n this.session.UnregisterTool(toolName);\n }\n\n /** Get all registered tool definitions */\n public GetRegisteredTools(): ClientToolDefinition[] {\n return this.session.GetRegisteredTools();\n }\n\n // --- Tool Decoration ---\n\n /** Register a decorator for runtime enrichment of a metadata-driven tool */\n public RegisterToolDecorator(toolName: string, decorator: ClientToolDecorator): void {\n this.session.RegisterToolDecorator(toolName, decorator);\n }\n\n /** Set the runtime context for decorators */\n public SetDecoratorContext(context: ClientToolDecoratorContext): void {\n this.session.SetDecoratorContext(context);\n }\n\n /** Decorate base tools and send enriched definitions to the server */\n public async DecorateAndSendTools(baseTools: ClientToolMetadata[]): Promise<void> {\n return this.session.DecorateAndSendTools(baseTools);\n }\n\n // --- Session Lifecycle ---\n\n /** Start listening for client tool requests for a session */\n public StartSession(sessionId: string): void {\n this.session.StartSession(sessionId);\n }\n\n /** Stop listening and clean up the session */\n public StopSession(): void {\n this.session.StopSession();\n }\n\n // --- Agent Execution ---\n\n /** Run an agent with a message */\n public async RunAgent(params: RunAgentParams): Promise<RunAgentResult> {\n return this.session.RunAgent(params);\n }\n\n /** Run an agent from an existing conversation detail */\n public async RunAgentFromConversationDetail(params: RunAgentFromConversationDetailParams): Promise<RunAgentResult> {\n return this.session.RunAgentFromConversationDetail(params);\n }\n\n // --- Angular Lifecycle ---\n\n public ngOnDestroy(): void {\n this.session.Dispose();\n }\n}\n"]}
@@ -1,5 +1,3 @@
1
1
  export * from './lib/agent-client.service';
2
2
  export * from './lib/agent-client.module';
3
- export * from './lib/tools/navigation-tool';
4
- export * from './lib/tools/component-tool';
5
3
  //# sourceMappingURL=public-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAIA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC"}
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAIA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC"}
@@ -3,6 +3,4 @@
3
3
  */
4
4
  export * from './lib/agent-client.service';
5
5
  export * from './lib/agent-client.module';
6
- export * from './lib/tools/navigation-tool';
7
- export * from './lib/tools/component-tool';
8
6
  //# sourceMappingURL=public-api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC","sourcesContent":["/*\n * Public API Surface for @memberjunction/ng-agent-client\n */\n\nexport * from './lib/agent-client.service';\nexport * from './lib/agent-client.module';\nexport * from './lib/tools/navigation-tool';\nexport * from './lib/tools/component-tool';\n"]}
1
+ {"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,4BAA4B,CAAC;AAC3C,cAAc,2BAA2B,CAAC","sourcesContent":["/*\n * Public API Surface for @memberjunction/ng-agent-client\n */\n\nexport * from './lib/agent-client.service';\nexport * from './lib/agent-client.module';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-agent-client",
3
- "version": "5.22.0",
3
+ "version": "5.24.0",
4
4
  "description": "MemberJunction: Angular adapter for the Agent Client SDK - injectable service, navigation tools, RxJS bridges",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -8,7 +8,7 @@
8
8
  "/dist"
9
9
  ],
10
10
  "scripts": {
11
- "test": "echo \"No tests configured yet\"",
11
+ "test": "vitest run",
12
12
  "build": "ngc",
13
13
  "test:watch": "vitest"
14
14
  },
@@ -26,8 +26,8 @@
26
26
  "@angular/router": "21.1.3"
27
27
  },
28
28
  "dependencies": {
29
- "@memberjunction/ai-agent-client": "5.22.0",
30
- "@memberjunction/global": "5.22.0",
29
+ "@memberjunction/ai-agent-client": "5.24.0",
30
+ "@memberjunction/global": "5.24.0",
31
31
  "rxjs": "^7.8.2",
32
32
  "tslib": "^2.8.1"
33
33
  },
@@ -1,25 +0,0 @@
1
- /**
2
- * @fileoverview Component interaction tool definitions for the Angular Agent Client.
3
- *
4
- * Pre-built tool definitions for manipulating Knowledge Hub UI components
5
- * from agent commands (opening panels, applying filters, etc.).
6
- *
7
- * @module @memberjunction/ng-agent-client
8
- */
9
- import { ClientToolDefinition } from '@memberjunction/ai-agent-client';
10
- /**
11
- * Create an "open_search_panel" tool definition.
12
- * Opens or focuses the search panel in the Knowledge Hub.
13
- */
14
- export declare function CreateOpenSearchPanelTool(): ClientToolDefinition;
15
- /**
16
- * Create an "apply_search_filter" tool definition.
17
- * Applies filters to the current Knowledge Hub search results.
18
- */
19
- export declare function CreateApplySearchFilterTool(): ClientToolDefinition;
20
- /**
21
- * Create a "show_entity_details" tool definition.
22
- * Opens a details panel for a specific entity record.
23
- */
24
- export declare function CreateShowEntityDetailsTool(): ClientToolDefinition;
25
- //# sourceMappingURL=component-tool.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component-tool.d.ts","sourceRoot":"","sources":["../../../src/lib/tools/component-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,oBAAoB,EAAoB,MAAM,iCAAiC,CAAC;AAEzF;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,oBAAoB,CAoBhE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,oBAAoB,CAoClE;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,oBAAoB,CAuBlE"}
@@ -1,103 +0,0 @@
1
- /**
2
- * @fileoverview Component interaction tool definitions for the Angular Agent Client.
3
- *
4
- * Pre-built tool definitions for manipulating Knowledge Hub UI components
5
- * from agent commands (opening panels, applying filters, etc.).
6
- *
7
- * @module @memberjunction/ng-agent-client
8
- */
9
- /**
10
- * Create an "open_search_panel" tool definition.
11
- * Opens or focuses the search panel in the Knowledge Hub.
12
- */
13
- export function CreateOpenSearchPanelTool() {
14
- return {
15
- Name: 'open_search_panel',
16
- Description: 'Open or focus the search panel in the Knowledge Hub',
17
- ParameterSchema: {
18
- type: 'object',
19
- properties: {
20
- Query: { type: 'string', description: 'Optional search query to pre-fill' },
21
- },
22
- },
23
- Handler: async (params) => {
24
- const query = params['Query'] != null ? String(params['Query']) : undefined;
25
- // In a real implementation, this would emit an event picked up by the
26
- // Knowledge Hub shell component. For now, return success with the intent.
27
- return {
28
- Success: true,
29
- Data: { Action: 'open_search_panel', Query: query },
30
- };
31
- },
32
- };
33
- }
34
- /**
35
- * Create an "apply_search_filter" tool definition.
36
- * Applies filters to the current Knowledge Hub search results.
37
- */
38
- export function CreateApplySearchFilterTool() {
39
- return {
40
- Name: 'apply_search_filter',
41
- Description: 'Apply filters to the current Knowledge Hub search results',
42
- ParameterSchema: {
43
- type: 'object',
44
- properties: {
45
- EntityNames: {
46
- type: 'array',
47
- items: { type: 'string' },
48
- description: 'Filter to specific entity names',
49
- },
50
- SourceTypes: {
51
- type: 'array',
52
- items: { type: 'string' },
53
- description: 'Filter to specific source types',
54
- },
55
- Tags: {
56
- type: 'array',
57
- items: { type: 'string' },
58
- description: 'Filter to specific tags',
59
- },
60
- },
61
- },
62
- Handler: async (params) => {
63
- return {
64
- Success: true,
65
- Data: {
66
- Action: 'apply_search_filter',
67
- EntityNames: params['EntityNames'],
68
- SourceTypes: params['SourceTypes'],
69
- Tags: params['Tags'],
70
- },
71
- };
72
- },
73
- };
74
- }
75
- /**
76
- * Create a "show_entity_details" tool definition.
77
- * Opens a details panel for a specific entity record.
78
- */
79
- export function CreateShowEntityDetailsTool() {
80
- return {
81
- Name: 'show_entity_details',
82
- Description: 'Open a details panel for a specific entity record',
83
- ParameterSchema: {
84
- type: 'object',
85
- properties: {
86
- EntityName: { type: 'string', description: 'The MJ entity name' },
87
- RecordID: { type: 'string', description: 'The record ID to show details for' },
88
- },
89
- required: ['EntityName', 'RecordID'],
90
- },
91
- Handler: async (params) => {
92
- return {
93
- Success: true,
94
- Data: {
95
- Action: 'show_entity_details',
96
- EntityName: String(params['EntityName']),
97
- RecordID: String(params['RecordID']),
98
- },
99
- };
100
- },
101
- };
102
- }
103
- //# sourceMappingURL=component-tool.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"component-tool.js","sourceRoot":"","sources":["../../../src/lib/tools/component-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;GAGG;AACH,MAAM,UAAU,yBAAyB;IACrC,OAAO;QACH,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,qDAAqD;QAClE,eAAe,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACR,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;aAC9E;SACJ;QACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAA6B,EAAE;YAC1E,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5E,sEAAsE;YACtE,0EAA0E;YAC1E,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE,EAAE,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,EAAE;aACtD,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B;IACvC,OAAO;QACH,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,2DAA2D;QACxE,eAAe,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACR,WAAW,EAAE;oBACT,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,WAAW,EAAE,iCAAiC;iBACjD;gBACD,WAAW,EAAE;oBACT,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,WAAW,EAAE,iCAAiC;iBACjD;gBACD,IAAI,EAAE;oBACF,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACzB,WAAW,EAAE,yBAAyB;iBACzC;aACJ;SACJ;QACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAA6B,EAAE;YAC1E,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACF,MAAM,EAAE,qBAAqB;oBAC7B,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC;oBAClC,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC;oBAClC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC;iBACvB;aACJ,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B;IACvC,OAAO;QACH,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,mDAAmD;QAChE,eAAe,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACR,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;gBACjE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;aACjF;YACD,QAAQ,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC;SACvC;QACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAA6B,EAAE;YAC1E,OAAO;gBACH,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACF,MAAM,EAAE,qBAAqB;oBAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;oBACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;iBACvC;aACJ,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC","sourcesContent":["/**\n * @fileoverview Component interaction tool definitions for the Angular Agent Client.\n *\n * Pre-built tool definitions for manipulating Knowledge Hub UI components\n * from agent commands (opening panels, applying filters, etc.).\n *\n * @module @memberjunction/ng-agent-client\n */\n\nimport { ClientToolDefinition, ClientToolResult } from '@memberjunction/ai-agent-client';\n\n/**\n * Create an \"open_search_panel\" tool definition.\n * Opens or focuses the search panel in the Knowledge Hub.\n */\nexport function CreateOpenSearchPanelTool(): ClientToolDefinition {\n return {\n Name: 'open_search_panel',\n Description: 'Open or focus the search panel in the Knowledge Hub',\n ParameterSchema: {\n type: 'object',\n properties: {\n Query: { type: 'string', description: 'Optional search query to pre-fill' },\n },\n },\n Handler: async (params: Record<string, unknown>): Promise<ClientToolResult> => {\n const query = params['Query'] != null ? String(params['Query']) : undefined;\n // In a real implementation, this would emit an event picked up by the\n // Knowledge Hub shell component. For now, return success with the intent.\n return {\n Success: true,\n Data: { Action: 'open_search_panel', Query: query },\n };\n },\n };\n}\n\n/**\n * Create an \"apply_search_filter\" tool definition.\n * Applies filters to the current Knowledge Hub search results.\n */\nexport function CreateApplySearchFilterTool(): ClientToolDefinition {\n return {\n Name: 'apply_search_filter',\n Description: 'Apply filters to the current Knowledge Hub search results',\n ParameterSchema: {\n type: 'object',\n properties: {\n EntityNames: {\n type: 'array',\n items: { type: 'string' },\n description: 'Filter to specific entity names',\n },\n SourceTypes: {\n type: 'array',\n items: { type: 'string' },\n description: 'Filter to specific source types',\n },\n Tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Filter to specific tags',\n },\n },\n },\n Handler: async (params: Record<string, unknown>): Promise<ClientToolResult> => {\n return {\n Success: true,\n Data: {\n Action: 'apply_search_filter',\n EntityNames: params['EntityNames'],\n SourceTypes: params['SourceTypes'],\n Tags: params['Tags'],\n },\n };\n },\n };\n}\n\n/**\n * Create a \"show_entity_details\" tool definition.\n * Opens a details panel for a specific entity record.\n */\nexport function CreateShowEntityDetailsTool(): ClientToolDefinition {\n return {\n Name: 'show_entity_details',\n Description: 'Open a details panel for a specific entity record',\n ParameterSchema: {\n type: 'object',\n properties: {\n EntityName: { type: 'string', description: 'The MJ entity name' },\n RecordID: { type: 'string', description: 'The record ID to show details for' },\n },\n required: ['EntityName', 'RecordID'],\n },\n Handler: async (params: Record<string, unknown>): Promise<ClientToolResult> => {\n return {\n Success: true,\n Data: {\n Action: 'show_entity_details',\n EntityName: String(params['EntityName']),\n RecordID: String(params['RecordID']),\n },\n };\n },\n };\n}\n"]}
@@ -1,19 +0,0 @@
1
- /**
2
- * @fileoverview Navigation tool definitions for the Angular Agent Client.
3
- *
4
- * Pre-built tool definitions for navigating MJ Explorer from agent commands.
5
- * These are registered automatically by the AgentClientService.
6
- *
7
- * @module @memberjunction/ng-agent-client
8
- */
9
- import { Router } from '@angular/router';
10
- import { ClientToolDefinition } from '@memberjunction/ai-agent-client';
11
- /**
12
- * Create a "navigate_to_record" tool definition bound to a specific Angular Router.
13
- */
14
- export declare function CreateNavigateToRecordTool(router: Router): ClientToolDefinition;
15
- /**
16
- * Create a "navigate_to_app" tool definition bound to a specific Angular Router.
17
- */
18
- export declare function CreateNavigateToAppTool(router: Router): ClientToolDefinition;
19
- //# sourceMappingURL=navigation-tool.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigation-tool.d.ts","sourceRoot":"","sources":["../../../src/lib/tools/navigation-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,oBAAoB,EAAoB,MAAM,iCAAiC,CAAC;AAEzF;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAyB/E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAuB5E"}
@@ -1,65 +0,0 @@
1
- /**
2
- * @fileoverview Navigation tool definitions for the Angular Agent Client.
3
- *
4
- * Pre-built tool definitions for navigating MJ Explorer from agent commands.
5
- * These are registered automatically by the AgentClientService.
6
- *
7
- * @module @memberjunction/ng-agent-client
8
- */
9
- /**
10
- * Create a "navigate_to_record" tool definition bound to a specific Angular Router.
11
- */
12
- export function CreateNavigateToRecordTool(router) {
13
- return {
14
- Name: 'navigate_to_record',
15
- Description: 'Navigate the browser to a specific entity record in MJ Explorer',
16
- ParameterSchema: {
17
- type: 'object',
18
- properties: {
19
- EntityName: { type: 'string', description: 'The MJ entity name' },
20
- RecordID: { type: 'string', description: 'The record ID to navigate to' },
21
- },
22
- required: ['EntityName', 'RecordID'],
23
- },
24
- Handler: async (params) => {
25
- const entityName = String(params['EntityName']);
26
- const recordId = String(params['RecordID']);
27
- try {
28
- await router.navigate(['/resource', 'entity', entityName, recordId]);
29
- return { Success: true, Data: { Navigated: true, EntityName: entityName, RecordID: recordId } };
30
- }
31
- catch (error) {
32
- const message = error instanceof Error ? error.message : String(error);
33
- return { Success: false, ErrorMessage: `Navigation failed: ${message}` };
34
- }
35
- },
36
- };
37
- }
38
- /**
39
- * Create a "navigate_to_app" tool definition bound to a specific Angular Router.
40
- */
41
- export function CreateNavigateToAppTool(router) {
42
- return {
43
- Name: 'navigate_to_app',
44
- Description: 'Switch to a different MJ Explorer application by name',
45
- ParameterSchema: {
46
- type: 'object',
47
- properties: {
48
- AppName: { type: 'string', description: 'The application name to switch to' },
49
- },
50
- required: ['AppName'],
51
- },
52
- Handler: async (params) => {
53
- const appName = String(params['AppName']);
54
- try {
55
- await router.navigate(['/app', appName]);
56
- return { Success: true, Data: { Navigated: true, AppName: appName } };
57
- }
58
- catch (error) {
59
- const message = error instanceof Error ? error.message : String(error);
60
- return { Success: false, ErrorMessage: `Navigation failed: ${message}` };
61
- }
62
- },
63
- };
64
- }
65
- //# sourceMappingURL=navigation-tool.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"navigation-tool.js","sourceRoot":"","sources":["../../../src/lib/tools/navigation-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;GAEG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAc;IACrD,OAAO;QACH,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,iEAAiE;QAC9E,eAAe,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACR,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;gBACjE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;aAC5E;YACD,QAAQ,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC;SACvC;QACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAA6B,EAAE;YAC1E,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAE5C,IAAI,CAAC;gBACD,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;gBACrE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC;YACpG,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,sBAAsB,OAAO,EAAE,EAAE,CAAC;YAC7E,CAAC;QACL,CAAC;KACJ,CAAC;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc;IAClD,OAAO;QACH,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,uDAAuD;QACpE,eAAe,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACR,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;aAChF;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACxB;QACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAA6B,EAAE;YAC1E,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;YAE1C,IAAI,CAAC;gBACD,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;gBACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;YAC1E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,sBAAsB,OAAO,EAAE,EAAE,CAAC;YAC7E,CAAC;QACL,CAAC;KACJ,CAAC;AACN,CAAC","sourcesContent":["/**\n * @fileoverview Navigation tool definitions for the Angular Agent Client.\n *\n * Pre-built tool definitions for navigating MJ Explorer from agent commands.\n * These are registered automatically by the AgentClientService.\n *\n * @module @memberjunction/ng-agent-client\n */\n\nimport { Router } from '@angular/router';\nimport { ClientToolDefinition, ClientToolResult } from '@memberjunction/ai-agent-client';\n\n/**\n * Create a \"navigate_to_record\" tool definition bound to a specific Angular Router.\n */\nexport function CreateNavigateToRecordTool(router: Router): ClientToolDefinition {\n return {\n Name: 'navigate_to_record',\n Description: 'Navigate the browser to a specific entity record in MJ Explorer',\n ParameterSchema: {\n type: 'object',\n properties: {\n EntityName: { type: 'string', description: 'The MJ entity name' },\n RecordID: { type: 'string', description: 'The record ID to navigate to' },\n },\n required: ['EntityName', 'RecordID'],\n },\n Handler: async (params: Record<string, unknown>): Promise<ClientToolResult> => {\n const entityName = String(params['EntityName']);\n const recordId = String(params['RecordID']);\n\n try {\n await router.navigate(['/resource', 'entity', entityName, recordId]);\n return { Success: true, Data: { Navigated: true, EntityName: entityName, RecordID: recordId } };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { Success: false, ErrorMessage: `Navigation failed: ${message}` };\n }\n },\n };\n}\n\n/**\n * Create a \"navigate_to_app\" tool definition bound to a specific Angular Router.\n */\nexport function CreateNavigateToAppTool(router: Router): ClientToolDefinition {\n return {\n Name: 'navigate_to_app',\n Description: 'Switch to a different MJ Explorer application by name',\n ParameterSchema: {\n type: 'object',\n properties: {\n AppName: { type: 'string', description: 'The application name to switch to' },\n },\n required: ['AppName'],\n },\n Handler: async (params: Record<string, unknown>): Promise<ClientToolResult> => {\n const appName = String(params['AppName']);\n\n try {\n await router.navigate(['/app', appName]);\n return { Success: true, Data: { Navigated: true, AppName: appName } };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { Success: false, ErrorMessage: `Navigation failed: ${message}` };\n }\n },\n };\n}\n"]}