@memberjunction/ng-agent-client 0.0.1 → 5.23.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 CHANGED
@@ -1,45 +1,113 @@
1
1
  # @memberjunction/ng-agent-client
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@memberjunction/ng-agent-client`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**
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"]}
@@ -0,0 +1,8 @@
1
+ import * as i0 from "@angular/core";
2
+ import * as i1 from "@angular/common";
3
+ export declare class AgentClientModule {
4
+ static ɵfac: i0.ɵɵFactoryDeclaration<AgentClientModule, never>;
5
+ static ɵmod: i0.ɵɵNgModuleDeclaration<AgentClientModule, never, [typeof i1.CommonModule], never>;
6
+ static ɵinj: i0.ɵɵInjectorDeclaration<AgentClientModule>;
7
+ }
8
+ //# sourceMappingURL=agent-client.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-client.module.d.ts","sourceRoot":"","sources":["../../src/lib/agent-client.module.ts"],"names":[],"mappings":";;AASA,qBAKa,iBAAiB;yCAAjB,iBAAiB;0CAAjB,iBAAiB;0CAAjB,iBAAiB;CAAG"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @fileoverview Angular module for the Agent Client adapter.
3
+ *
4
+ * @module @memberjunction/ng-agent-client
5
+ */
6
+ import { NgModule } from '@angular/core';
7
+ import { CommonModule } from '@angular/common';
8
+ import * as i0 from "@angular/core";
9
+ export class AgentClientModule {
10
+ static ɵfac = function AgentClientModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AgentClientModule)(); };
11
+ static ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: AgentClientModule });
12
+ static ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule] });
13
+ }
14
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AgentClientModule, [{
15
+ type: NgModule,
16
+ args: [{
17
+ imports: [CommonModule],
18
+ declarations: [],
19
+ exports: [],
20
+ }]
21
+ }], null, null); })();
22
+ (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(AgentClientModule, { imports: [CommonModule] }); })();
23
+ //# sourceMappingURL=agent-client.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-client.module.js","sourceRoot":"","sources":["../../src/lib/agent-client.module.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;;AAO/C,MAAM,OAAO,iBAAiB;2GAAjB,iBAAiB;4DAAjB,iBAAiB;gEAJhB,YAAY;;iFAIb,iBAAiB;cAL7B,QAAQ;eAAC;gBACN,OAAO,EAAE,CAAC,YAAY,CAAC;gBACvB,YAAY,EAAE,EAAE;gBAChB,OAAO,EAAE,EAAE;aACd;;wFACY,iBAAiB,cAJhB,YAAY","sourcesContent":["/**\n * @fileoverview Angular module for the Agent Client adapter.\n *\n * @module @memberjunction/ng-agent-client\n */\n\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@NgModule({\n imports: [CommonModule],\n declarations: [],\n exports: [],\n})\nexport class AgentClientModule {}\n"]}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @fileoverview Angular adapter for the MJ Agent Client SDK.
3
+ *
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.
10
+ *
11
+ * @module @memberjunction/ng-agent-client
12
+ */
13
+ import { OnDestroy } from '@angular/core';
14
+ import { ClientToolDefinition, ClientToolMetadata, ClientToolDecorator, ClientToolDecoratorContext, ClientToolRequestEvent, ClientToolResultEvent, SessionError, AgentProgress, RunAgentParams, RunAgentFromConversationDetailParams, RunAgentResult } from '@memberjunction/ai-agent-client';
15
+ import { Observable } from 'rxjs';
16
+ import * as i0 from "@angular/core";
17
+ /**
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
24
+ *
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
+ * ```
32
+ */
33
+ export declare class AgentClientService implements OnDestroy {
34
+ private session;
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 */
50
+ RegisterTool(tool: ClientToolDefinition): void;
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>;
69
+ ngOnDestroy(): void;
70
+ static ɵfac: i0.ɵɵFactoryDeclaration<AgentClientService, never>;
71
+ static ɵprov: i0.ɵɵInjectableDeclaration<AgentClientService>;
72
+ }
73
+ //# sourceMappingURL=agent-client.service.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @fileoverview Angular adapter for the MJ Agent Client SDK.
3
+ *
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.
10
+ *
11
+ * @module @memberjunction/ng-agent-client
12
+ */
13
+ import { Injectable } from '@angular/core';
14
+ import { AgentClientSession, } from '@memberjunction/ai-agent-client';
15
+ import * as i0 from "@angular/core";
16
+ /**
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
23
+ *
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
+ * ```
31
+ */
32
+ export class AgentClientService {
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 */
66
+ RegisterTool(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);
103
+ }
104
+ /** Run an agent from an existing conversation detail */
105
+ async RunAgentFromConversationDetail(params) {
106
+ return this.session.RunAgentFromConversationDetail(params);
107
+ }
108
+ // --- Angular Lifecycle ---
109
+ ngOnDestroy() {
110
+ this.session.Dispose();
111
+ }
112
+ static ɵfac = function AgentClientService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AgentClientService)(); };
113
+ static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: AgentClientService, factory: AgentClientService.ɵfac, providedIn: 'root' });
114
+ }
115
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AgentClientService, [{
116
+ type: Injectable,
117
+ args: [{ providedIn: 'root' }]
118
+ }], null, null); })();
119
+ //# sourceMappingURL=agent-client.service.js.map
@@ -0,0 +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 * 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"]}
@@ -0,0 +1,3 @@
1
+ export * from './lib/agent-client.service';
2
+ export * from './lib/agent-client.module';
3
+ //# sourceMappingURL=public-api.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,6 @@
1
+ /*
2
+ * Public API Surface for @memberjunction/ng-agent-client
3
+ */
4
+ export * from './lib/agent-client.service';
5
+ export * from './lib/agent-client.module';
6
+ //# sourceMappingURL=public-api.js.map
@@ -0,0 +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","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,10 +1,39 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-agent-client",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @memberjunction/ng-agent-client",
5
- "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
3
+ "version": "5.23.0",
4
+ "description": "MemberJunction: Angular adapter for the Agent Client SDK - injectable service, navigation tools, RxJS bridges",
5
+ "main": "./dist/public-api.js",
6
+ "typings": "./dist/public-api.d.ts",
7
+ "files": [
8
+ "/dist"
9
+ ],
10
+ "scripts": {
11
+ "test": "vitest run",
12
+ "build": "ngc",
13
+ "test:watch": "vitest"
14
+ },
15
+ "keywords": [],
16
+ "author": "MemberJunction.com",
17
+ "license": "ISC",
18
+ "devDependencies": {
19
+ "@angular/compiler": "21.1.3",
20
+ "@angular/compiler-cli": "21.1.3",
21
+ "vitest": "^4.0.18"
22
+ },
23
+ "peerDependencies": {
24
+ "@angular/common": "21.1.3",
25
+ "@angular/core": "21.1.3",
26
+ "@angular/router": "21.1.3"
27
+ },
28
+ "dependencies": {
29
+ "@memberjunction/ai-agent-client": "5.23.0",
30
+ "@memberjunction/global": "5.23.0",
31
+ "rxjs": "^7.8.2",
32
+ "tslib": "^2.8.1"
33
+ },
34
+ "sideEffects": false,
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/MemberJunction/MJ"
38
+ }
10
39
  }