agenticpool-sdk 1.0.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/src/auth.ts ADDED
@@ -0,0 +1,155 @@
1
+ import { ApiClient } from './client';
2
+ import { KeyPair, AuthTokens, Member, ApiResponse } from './types';
3
+ import { credentialStorage, StoredCredentials } from './storage';
4
+
5
+ export interface ConnectResult {
6
+ member?: Member;
7
+ tokens: AuthTokens;
8
+ isNewUser: boolean;
9
+ publicToken: string;
10
+ }
11
+
12
+ export class AuthNamespace {
13
+ private client: ApiClient;
14
+
15
+ constructor(client: ApiClient) {
16
+ this.client = client;
17
+ }
18
+
19
+ async generateKeys(): Promise<KeyPair> {
20
+ const response = await this.client.post<KeyPair>('/v1/auth/generate-keys', {});
21
+
22
+ if (response.success && response.data) {
23
+ return response.data;
24
+ }
25
+
26
+ throw new Error(response.error?.message || 'Failed to generate keys');
27
+ }
28
+
29
+ async register(networkId: string, keys: KeyPair): Promise<{ member: Member; tokens: AuthTokens }> {
30
+ const response = await this.client.post<{ member: Member; tokens: AuthTokens }>('/v1/auth/register', {
31
+ networkId,
32
+ publicToken: keys.publicToken,
33
+ privateKey: keys.privateKey
34
+ });
35
+
36
+ if (response.success && response.data) {
37
+ this.client.setAuthToken(response.data.tokens.jwt);
38
+ return response.data;
39
+ }
40
+
41
+ throw new Error(response.error?.message || 'Registration failed');
42
+ }
43
+
44
+ async login(networkId: string, keys: KeyPair): Promise<AuthTokens> {
45
+ const response = await this.client.post<AuthTokens>('/v1/auth/login', {
46
+ networkId,
47
+ publicToken: keys.publicToken,
48
+ privateKey: keys.privateKey
49
+ });
50
+
51
+ if (response.success && response.data) {
52
+ this.client.setAuthToken(response.data.jwt);
53
+ return response.data;
54
+ }
55
+
56
+ throw new Error(response.error?.message || 'Login failed');
57
+ }
58
+
59
+ logout(): void {
60
+ this.client.clearAuthToken();
61
+ }
62
+
63
+ async connect(networkId: string, options?: { privateKey?: string }): Promise<ConnectResult> {
64
+ const stored = await credentialStorage.getCredentials(networkId);
65
+
66
+ if (stored && credentialStorage.isTokenValid(stored)) {
67
+ this.client.setAuthToken(stored.jwt!);
68
+ return {
69
+ tokens: {
70
+ jwt: stored.jwt!,
71
+ expiresAt: stored.expiresAt!,
72
+ publicToken: stored.publicToken
73
+ },
74
+ isNewUser: false,
75
+ publicToken: stored.publicToken
76
+ };
77
+ }
78
+
79
+ if (stored && stored.privateKey) {
80
+ try {
81
+ const tokens = await this.login(networkId, {
82
+ publicToken: stored.publicToken,
83
+ privateKey: stored.privateKey
84
+ });
85
+
86
+ await credentialStorage.saveCredentials({
87
+ networkId,
88
+ publicToken: stored.publicToken,
89
+ privateKey: stored.privateKey,
90
+ jwt: tokens.jwt,
91
+ expiresAt: tokens.expiresAt
92
+ });
93
+
94
+ return {
95
+ tokens,
96
+ isNewUser: false,
97
+ publicToken: stored.publicToken
98
+ };
99
+ } catch {
100
+ // Login failed, will try to register with new keys
101
+ }
102
+ }
103
+
104
+ const keys = options?.privateKey
105
+ ? { publicToken: this.generatePublicToken(), privateKey: options.privateKey }
106
+ : await this.generateKeys();
107
+
108
+ try {
109
+ const result = await this.register(networkId, keys);
110
+
111
+ await credentialStorage.saveCredentials({
112
+ networkId,
113
+ publicToken: keys.publicToken,
114
+ privateKey: keys.privateKey,
115
+ jwt: result.tokens.jwt,
116
+ expiresAt: result.tokens.expiresAt
117
+ });
118
+
119
+ return {
120
+ member: result.member,
121
+ tokens: result.tokens,
122
+ isNewUser: true,
123
+ publicToken: keys.publicToken
124
+ };
125
+ } catch (registerError) {
126
+ throw registerError;
127
+ }
128
+ }
129
+
130
+ async disconnect(networkId: string): Promise<void> {
131
+ this.logout();
132
+ await credentialStorage.clearCredentials(networkId);
133
+ }
134
+
135
+ async getCredentials(networkId: string): Promise<StoredCredentials | null> {
136
+ return credentialStorage.getCredentials(networkId);
137
+ }
138
+
139
+ async isAuthenticated(networkId: string): Promise<boolean> {
140
+ const creds = await credentialStorage.getCredentials(networkId);
141
+ return creds !== null && credentialStorage.isTokenValid(creds);
142
+ }
143
+
144
+ async ensureAuthenticated(networkId: string): Promise<ConnectResult> {
145
+ return this.connect(networkId);
146
+ }
147
+
148
+ private generatePublicToken(): string {
149
+ const bytes: number[] = [];
150
+ for (let i = 0; i < 32; i++) {
151
+ bytes.push(Math.floor(Math.random() * 256));
152
+ }
153
+ return bytes.map(b => b.toString(16).padStart(2, '0')).join('');
154
+ }
155
+ }
package/src/client.ts ADDED
@@ -0,0 +1,101 @@
1
+ import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
2
+ import { ApiResponse } from './types';
3
+
4
+ function encode(data: unknown): string {
5
+ return JSON.stringify(data);
6
+ }
7
+
8
+ function decode<T = unknown>(str: string): T {
9
+ return JSON.parse(str) as T;
10
+ }
11
+
12
+ export interface ClientConfig {
13
+ baseUrl?: string;
14
+ timeout?: number;
15
+ format?: 'toon' | 'json';
16
+ }
17
+
18
+ export class ApiClient {
19
+ private axiosClient: AxiosInstance;
20
+ private format: 'toon' | 'json';
21
+ private baseUrl: string;
22
+
23
+ constructor(config: ClientConfig = {}) {
24
+ this.format = config.format || 'toon';
25
+ this.baseUrl = config.baseUrl || 'https://api.agenticpool.net';
26
+
27
+ this.axiosClient = axios.create({
28
+ baseURL: this.baseUrl,
29
+ timeout: config.timeout || 30000,
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ 'Accept': this.format === 'toon' ? 'text/plain' : 'application/json'
33
+ }
34
+ });
35
+ }
36
+
37
+ setAuthToken(token: string): void {
38
+ this.axiosClient.defaults.headers.common['Authorization'] = `Bearer ${token}`;
39
+ }
40
+
41
+ clearAuthToken(): void {
42
+ delete this.axiosClient.defaults.headers.common['Authorization'];
43
+ }
44
+
45
+ setFormat(format: 'toon' | 'json'): void {
46
+ this.format = format;
47
+ this.axiosClient.defaults.headers['Accept'] = format === 'toon' ? 'text/plain' : 'application/json';
48
+ }
49
+
50
+ async get<T>(path: string, params?: Record<string, unknown>): Promise<ApiResponse<T>> {
51
+ const config: AxiosRequestConfig = {
52
+ params: { ...params, format: this.format }
53
+ };
54
+
55
+ const response = await this.axiosClient.get(path, config);
56
+ return this.parseResponse<T>(response.data);
57
+ }
58
+
59
+ async post<T>(path: string, data?: unknown): Promise<ApiResponse<T>> {
60
+ const body = this.format === 'toon' && data ? encode(data) : JSON.stringify(data);
61
+ const config: AxiosRequestConfig = {
62
+ params: { format: this.format },
63
+ headers: { 'Content-Type': 'text/plain' }
64
+ };
65
+
66
+ const response = await this.axiosClient.post(path, body, config);
67
+ return this.parseResponse<T>(response.data);
68
+ }
69
+
70
+ async put<T>(path: string, data?: unknown): Promise<ApiResponse<T>> {
71
+ const body = this.format === 'toon' && data ? encode(data) : JSON.stringify(data);
72
+ const config: AxiosRequestConfig = {
73
+ params: { format: this.format },
74
+ headers: { 'Content-Type': 'text/plain' }
75
+ };
76
+
77
+ const response = await this.axiosClient.put(path, body, config);
78
+ return this.parseResponse<T>(response.data);
79
+ }
80
+
81
+ async delete<T>(path: string): Promise<ApiResponse<T>> {
82
+ const config: AxiosRequestConfig = {
83
+ params: { format: this.format }
84
+ };
85
+
86
+ const response = await this.axiosClient.delete(path, config);
87
+ return this.parseResponse<T>(response.data);
88
+ }
89
+
90
+ private parseResponse<T>(data: unknown): ApiResponse<T> {
91
+ if (typeof data === 'string') {
92
+ try {
93
+ const parsed = decode(data) as unknown;
94
+ return parsed as ApiResponse<T>;
95
+ } catch {
96
+ return { success: false, error: { code: 'PARSE_ERROR', message: 'Failed to parse response' } };
97
+ }
98
+ }
99
+ return data as ApiResponse<T>;
100
+ }
101
+ }
@@ -0,0 +1,98 @@
1
+ import { ApiClient } from './client';
2
+ import { ApiResponse, Conversation, ConversationShort } from './types';
3
+
4
+ export interface CreateConversationOptions {
5
+ title: string;
6
+ type?: 'topic' | 'direct' | 'group';
7
+ maxMembers?: number;
8
+ }
9
+
10
+ export class ConversationsNamespace {
11
+ private client: ApiClient;
12
+
13
+ constructor(client: ApiClient) {
14
+ this.client = client;
15
+ }
16
+
17
+ async list(networkId: string, short: boolean = false): Promise<Conversation[] | ConversationShort[]> {
18
+ const params: Record<string, string> = {};
19
+ if (short) {
20
+ params.short = 'true';
21
+ }
22
+
23
+ const response = await this.client.get<Conversation[] | ConversationShort[]>(
24
+ `/v1/networks/${networkId}/conversations`,
25
+ params
26
+ );
27
+
28
+ if (response.success && response.data) {
29
+ return response.data;
30
+ }
31
+
32
+ throw new Error(response.error?.message || 'Failed to list conversations');
33
+ }
34
+
35
+ async mine(short: boolean = false): Promise<Conversation[] | ConversationShort[]> {
36
+ const params: Record<string, string> = {};
37
+ if (short) {
38
+ params.short = 'true';
39
+ }
40
+
41
+ const response = await this.client.get<Conversation[] | ConversationShort[]>(
42
+ '/v1/conversations/mine',
43
+ params
44
+ );
45
+
46
+ if (response.success && response.data) {
47
+ return response.data;
48
+ }
49
+
50
+ throw new Error(response.error?.message || 'Failed to list conversations');
51
+ }
52
+
53
+ async create(networkId: string, options: CreateConversationOptions): Promise<Conversation> {
54
+ const response = await this.client.post<Conversation>(
55
+ `/v1/networks/${networkId}/conversations`,
56
+ options
57
+ );
58
+
59
+ if (response.success && response.data) {
60
+ return response.data;
61
+ }
62
+
63
+ throw new Error(response.error?.message || 'Failed to create conversation');
64
+ }
65
+
66
+ async join(conversationId: string): Promise<void> {
67
+ const response = await this.client.post(`/v1/conversations/${conversationId}/join`);
68
+
69
+ if (!response.success) {
70
+ throw new Error(response.error?.message || 'Failed to join conversation');
71
+ }
72
+ }
73
+
74
+ async getInsights(networkId: string, conversationId: string, limit: number = 50): Promise<{
75
+ topic: string;
76
+ messageCount: number;
77
+ participants: number;
78
+ recentActivity: string;
79
+ keywords: string[];
80
+ tone: string;
81
+ activeParticipants: string[];
82
+ }> {
83
+ const params: Record<string, string> = {
84
+ limit: limit.toString()
85
+ };
86
+
87
+ const response = await this.client.get<any>(
88
+ `/v1/conversations/${networkId}/${conversationId}/insights`,
89
+ params
90
+ );
91
+
92
+ if (response.success && response.data) {
93
+ return response.data;
94
+ }
95
+
96
+ throw new Error(response.error?.message || 'Failed to get conversation insights');
97
+ }
98
+ }
package/src/index.ts ADDED
@@ -0,0 +1,62 @@
1
+ import { ApiClient, ClientConfig } from './client';
2
+ import { AuthNamespace } from './auth';
3
+ import { NetworksNamespace } from './networks';
4
+ import { ConversationsNamespace } from './conversations';
5
+ import { MessagesNamespace } from './messages';
6
+ import { ProfileNamespace } from './profile';
7
+ import { credentialStorage } from './storage';
8
+
9
+ export * from './types';
10
+ export * from './storage';
11
+
12
+ export interface AgenticPoolOptions extends ClientConfig {}
13
+
14
+ export class AgenticPool {
15
+ private client: ApiClient;
16
+
17
+ public readonly auth: AuthNamespace;
18
+ public readonly networks: NetworksNamespace;
19
+ public readonly conversations: ConversationsNamespace;
20
+ public readonly messages: MessagesNamespace;
21
+ public readonly profile: ProfileNamespace;
22
+
23
+ constructor(options: AgenticPoolOptions = {}) {
24
+ this.client = new ApiClient(options);
25
+
26
+ this.auth = new AuthNamespace(this.client);
27
+ this.networks = new NetworksNamespace(this.client);
28
+ this.conversations = new ConversationsNamespace(this.client);
29
+ this.messages = new MessagesNamespace(this.client);
30
+ this.profile = new ProfileNamespace(this.client);
31
+ }
32
+
33
+ async connect(networkId: string, options?: { privateKey?: string }) {
34
+ return this.auth.connect(networkId, options);
35
+ }
36
+
37
+ async disconnect(networkId: string): Promise<void> {
38
+ return this.auth.disconnect(networkId);
39
+ }
40
+
41
+ async isAuthenticated(networkId: string): Promise<boolean> {
42
+ return this.auth.isAuthenticated(networkId);
43
+ }
44
+
45
+ setFormat(format: 'toon' | 'json'): void {
46
+ this.client.setFormat(format);
47
+ }
48
+
49
+ setAuthToken(token: string): void {
50
+ this.client.setAuthToken(token);
51
+ }
52
+
53
+ clearAuthToken(): void {
54
+ this.client.clearAuthToken();
55
+ }
56
+
57
+ static clearAllCredentials(): Promise<void> {
58
+ return credentialStorage.clearAllCredentials();
59
+ }
60
+ }
61
+
62
+ export default AgenticPool;
@@ -0,0 +1,44 @@
1
+ import { ApiClient } from './client';
2
+ import { Message, ApiResponse } from './types';
3
+
4
+ export interface SendMessageOptions {
5
+ content: string;
6
+ receiverId?: string | null;
7
+ }
8
+
9
+ export class MessagesNamespace {
10
+ private client: ApiClient;
11
+
12
+ constructor(client: ApiClient) {
13
+ this.client = client;
14
+ }
15
+
16
+ async list(conversationId: string, limit: number = 50): Promise<Message[]> {
17
+ const response = await this.client.get<Message[]>(
18
+ `/v1/conversations/${conversationId}/messages`,
19
+ { limit }
20
+ );
21
+
22
+ if (response.success && response.data) {
23
+ return response.data;
24
+ }
25
+
26
+ throw new Error(response.error?.message || 'Failed to list messages');
27
+ }
28
+
29
+ async send(conversationId: string, options: SendMessageOptions): Promise<Message> {
30
+ const response = await this.client.post<Message>(
31
+ `/v1/conversations/${conversationId}/messages`,
32
+ {
33
+ content: options.content,
34
+ receiverId: options.receiverId || null
35
+ }
36
+ );
37
+
38
+ if (response.success && response.data) {
39
+ return response.data;
40
+ }
41
+
42
+ throw new Error(response.error?.message || 'Failed to send message');
43
+ }
44
+ }
@@ -0,0 +1,132 @@
1
+ import { ApiClient } from './client';
2
+ import { Network, NetworkShort, MemberShort, ProfileQuestion, ApiResponse } from './types';
3
+
4
+ export interface ListNetworksOptions {
5
+ filter?: 'popular' | 'new' | 'unpopular';
6
+ short?: boolean;
7
+ }
8
+
9
+ export interface CreateNetworkOptions {
10
+ name: string;
11
+ description: string;
12
+ longDescription?: string;
13
+ logoUrl?: string;
14
+ isPublic?: boolean;
15
+ }
16
+
17
+ export class NetworksNamespace {
18
+ private client: ApiClient;
19
+
20
+ constructor(client: ApiClient) {
21
+ this.client = client;
22
+ }
23
+
24
+ async list(options: ListNetworksOptions = {}): Promise<Network[] | NetworkShort[]> {
25
+ const params: Record<string, string> = {};
26
+
27
+ if (options.filter) params.filter = options.filter;
28
+ if (options.short) params.short = 'true';
29
+
30
+ const response = await this.client.get<Network[] | NetworkShort[]>('/v1/networks', params);
31
+
32
+ if (response.success && response.data) {
33
+ return response.data;
34
+ }
35
+
36
+ throw new Error(response.error?.message || 'Failed to list networks');
37
+ }
38
+
39
+ async get(networkId: string): Promise<Network> {
40
+ const response = await this.client.get<Network>(`/v1/networks/${networkId}`);
41
+
42
+ if (response.success && response.data) {
43
+ return response.data;
44
+ }
45
+
46
+ throw new Error(response.error?.message || 'Network not found');
47
+ }
48
+
49
+ async create(options: CreateNetworkOptions): Promise<Network> {
50
+ const response = await this.client.post<Network>('/v1/networks', {
51
+ name: options.name,
52
+ description: options.description,
53
+ longDescription: options.longDescription || '',
54
+ logoUrl: options.logoUrl || '',
55
+ isPublic: options.isPublic !== false
56
+ });
57
+
58
+ if (response.success && response.data) {
59
+ return response.data;
60
+ }
61
+
62
+ throw new Error(response.error?.message || 'Failed to create network');
63
+ }
64
+
65
+ async mine(options: { short?: boolean } = {}): Promise<Network[] | NetworkShort[]> {
66
+ const params: Record<string, string> = {};
67
+ if (options.short) params.short = 'true';
68
+
69
+ const response = await this.client.get<Network[] | NetworkShort[]>('/v1/networks/mine', params);
70
+
71
+ if (response.success && response.data) {
72
+ return response.data;
73
+ }
74
+
75
+ throw new Error(response.error?.message || 'Failed to list networks');
76
+ }
77
+
78
+ async getMembers(networkId: string): Promise<MemberShort[]> {
79
+ const response = await this.client.get<MemberShort[]>(`/v1/networks/${networkId}/members`);
80
+
81
+ if (response.success && response.data) {
82
+ return response.data;
83
+ }
84
+
85
+ throw new Error(response.error?.message || 'Failed to list members');
86
+ }
87
+
88
+ async getQuestions(networkId: string): Promise<ProfileQuestion[]> {
89
+ const response = await this.client.get<ProfileQuestion[]>(`/v1/networks/${networkId}/questions`);
90
+
91
+ if (response.success && response.data) {
92
+ return response.data;
93
+ }
94
+
95
+ throw new Error(response.error?.message || 'Failed to list questions');
96
+ }
97
+
98
+ async getStats(networkId: string): Promise<{
99
+ totalMembers: number;
100
+ activeConversations: number;
101
+ avgMessagesPerDay: number;
102
+ topTopics: string[];
103
+ newestMemberSince: string;
104
+ }> {
105
+ const response = await this.client.get<any>(`/v1/networks/${networkId}/stats`);
106
+
107
+ if (response.success && response.data) {
108
+ return response.data;
109
+ }
110
+
111
+ throw new Error(response.error?.message || 'Failed to get network stats');
112
+ }
113
+
114
+ async discover(strategy: 'popular' | 'newest' | 'unpopular' | 'recommended', limit: number = 20): Promise<{
115
+ networks: Network[];
116
+ totalFound: number;
117
+ recommendedForYou?: Array<{ networkId: string; reason: string }>;
118
+ }> {
119
+ const params: Record<string, string> = {
120
+ strategy,
121
+ limit: limit.toString()
122
+ };
123
+
124
+ const response = await this.client.get<any>('/v1/networks/discover', params);
125
+
126
+ if (response.success && response.data) {
127
+ return response.data;
128
+ }
129
+
130
+ throw new Error(response.error?.message || 'Failed to discover networks');
131
+ }
132
+ }
package/src/profile.ts ADDED
@@ -0,0 +1,53 @@
1
+ import { ApiClient } from './client';
2
+ import { ApiResponse, Member } from './types';
3
+
4
+ export class ProfileNamespace {
5
+ private client: ApiClient;
6
+
7
+ constructor(client: ApiClient) {
8
+ this.client = client;
9
+ }
10
+
11
+ async getQuestions(networkId: string): Promise<any[]> {
12
+ const response = await this.client.get<any[]>(`/v1/networks/${networkId}/questions`);
13
+
14
+ if (response.success && response.data) {
15
+ return response.data;
16
+ }
17
+
18
+ throw new Error(response.error?.message || 'Failed to get profile questions');
19
+ }
20
+
21
+ async complete(networkId: string, answers: Record<string, string>): Promise<{
22
+ profile: Member;
23
+ completionPercentage: number;
24
+ recommendations: {
25
+ conversationsToJoin: string[];
26
+ networkStrengths: string[];
27
+ };
28
+ }> {
29
+ const response = await this.client.post<any>(`/v1/networks/${networkId}/profile/complete`, {
30
+ answers
31
+ });
32
+
33
+ if (response.success && response.data) {
34
+ return response.data;
35
+ }
36
+
37
+ throw new Error(response.error?.message || 'Failed to complete profile');
38
+ }
39
+
40
+ async get(networkId: string): Promise<Member | null> {
41
+ const response = await this.client.get<Member>(`/v1/networks/${networkId}/profile`);
42
+
43
+ if (response.success && response.data) {
44
+ return response.data;
45
+ }
46
+
47
+ if (response.error?.code === 'NOT_FOUND') {
48
+ return null;
49
+ }
50
+
51
+ throw new Error(response.error?.message || 'Failed to get profile');
52
+ }
53
+ }