gopherhole_openclaw_a2a 0.2.1 → 0.2.3
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/dist/index.js +32 -9
- package/dist/src/connection.js +38 -3
- package/dist/src/types.d.ts +12 -2
- package/index.ts +32 -9
- package/package.json +1 -1
- package/src/connection.ts +38 -3
- package/src/types.ts +13 -2
package/dist/index.js
CHANGED
|
@@ -37,6 +37,10 @@ const plugin = {
|
|
|
37
37
|
type: 'string',
|
|
38
38
|
description: 'Path to image file to send (for send action)',
|
|
39
39
|
},
|
|
40
|
+
file: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: 'Path to file to send - PDF, documents, etc. (for send action)',
|
|
43
|
+
},
|
|
40
44
|
},
|
|
41
45
|
required: ['action'],
|
|
42
46
|
},
|
|
@@ -45,6 +49,7 @@ const plugin = {
|
|
|
45
49
|
const agentId = params.agentId;
|
|
46
50
|
const message = params.message;
|
|
47
51
|
const imagePath = params.image;
|
|
52
|
+
const filePath = params.file;
|
|
48
53
|
const manager = getA2AConnectionManager();
|
|
49
54
|
if (!manager) {
|
|
50
55
|
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'A2A channel not running' }) }] };
|
|
@@ -54,8 +59,8 @@ const plugin = {
|
|
|
54
59
|
return { content: [{ type: 'text', text: JSON.stringify({ status: 'ok', agents }) }] };
|
|
55
60
|
}
|
|
56
61
|
if (action === 'send') {
|
|
57
|
-
if (!agentId || (!message && !imagePath)) {
|
|
58
|
-
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'agentId and (message or
|
|
62
|
+
if (!agentId || (!message && !imagePath && !filePath)) {
|
|
63
|
+
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'agentId and (message, image, or file) required for send action' }) }] };
|
|
59
64
|
}
|
|
60
65
|
try {
|
|
61
66
|
const isGopherHoleConnected = manager.isGopherHoleConnected();
|
|
@@ -66,25 +71,43 @@ const plugin = {
|
|
|
66
71
|
if (message) {
|
|
67
72
|
parts.push({ kind: 'text', text: message });
|
|
68
73
|
}
|
|
69
|
-
// Add
|
|
70
|
-
|
|
74
|
+
// Add file part if image or file path provided
|
|
75
|
+
const attachmentPath = imagePath || filePath;
|
|
76
|
+
if (attachmentPath) {
|
|
71
77
|
try {
|
|
72
|
-
const
|
|
73
|
-
const base64Data =
|
|
74
|
-
const ext = extname(
|
|
78
|
+
const fileData = readFileSync(attachmentPath);
|
|
79
|
+
const base64Data = fileData.toString('base64');
|
|
80
|
+
const ext = extname(attachmentPath).toLowerCase();
|
|
75
81
|
const mimeTypes = {
|
|
82
|
+
// Images
|
|
76
83
|
'.png': 'image/png',
|
|
77
84
|
'.jpg': 'image/jpeg',
|
|
78
85
|
'.jpeg': 'image/jpeg',
|
|
79
86
|
'.gif': 'image/gif',
|
|
80
87
|
'.webp': 'image/webp',
|
|
81
88
|
'.svg': 'image/svg+xml',
|
|
89
|
+
// Documents
|
|
90
|
+
'.pdf': 'application/pdf',
|
|
91
|
+
'.doc': 'application/msword',
|
|
92
|
+
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
93
|
+
'.xls': 'application/vnd.ms-excel',
|
|
94
|
+
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
95
|
+
'.ppt': 'application/vnd.ms-powerpoint',
|
|
96
|
+
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
97
|
+
'.txt': 'text/plain',
|
|
98
|
+
'.csv': 'text/csv',
|
|
99
|
+
'.json': 'application/json',
|
|
100
|
+
'.xml': 'application/xml',
|
|
101
|
+
'.html': 'text/html',
|
|
102
|
+
'.md': 'text/markdown',
|
|
103
|
+
// Archives
|
|
104
|
+
'.zip': 'application/zip',
|
|
82
105
|
};
|
|
83
106
|
const mimeType = mimeTypes[ext] || 'application/octet-stream';
|
|
84
107
|
parts.push({ kind: 'data', data: base64Data, mimeType });
|
|
85
108
|
}
|
|
86
|
-
catch (
|
|
87
|
-
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: `Failed to read
|
|
109
|
+
catch (fileErr) {
|
|
110
|
+
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: `Failed to read file: ${fileErr.message}` }) }] };
|
|
88
111
|
}
|
|
89
112
|
}
|
|
90
113
|
let response;
|
package/dist/src/connection.js
CHANGED
|
@@ -34,9 +34,44 @@ export class A2AConnectionManager {
|
|
|
34
34
|
maxReconnectAttempts: 20,
|
|
35
35
|
requestTimeout: timeoutMs,
|
|
36
36
|
messageTimeout: timeoutMs,
|
|
37
|
-
agentCard: {
|
|
38
|
-
name: this.config.agentName ?? '
|
|
39
|
-
description: '
|
|
37
|
+
agentCard: gphConfig.agentCard ?? {
|
|
38
|
+
name: this.config.agentName ?? 'OpenClaw',
|
|
39
|
+
description: 'Personal AI assistant with tools, web search, browser control, and various skills',
|
|
40
|
+
version: '0.1.0',
|
|
41
|
+
skills: [
|
|
42
|
+
{
|
|
43
|
+
id: 'chat',
|
|
44
|
+
name: 'Chat',
|
|
45
|
+
description: 'General conversation and Q&A',
|
|
46
|
+
tags: ['conversation', 'assistant'],
|
|
47
|
+
inputModes: ['text/plain'],
|
|
48
|
+
outputModes: ['text/plain', 'text/markdown'],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: 'web-search',
|
|
52
|
+
name: 'Web Search',
|
|
53
|
+
description: 'Search the web and summarize results',
|
|
54
|
+
tags: ['search', 'research', 'web'],
|
|
55
|
+
inputModes: ['text/plain'],
|
|
56
|
+
outputModes: ['text/plain', 'text/markdown'],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: 'coding',
|
|
60
|
+
name: 'Coding',
|
|
61
|
+
description: 'Write, review, and debug code',
|
|
62
|
+
tags: ['code', 'programming', 'development'],
|
|
63
|
+
inputModes: ['text/plain'],
|
|
64
|
+
outputModes: ['text/plain', 'text/markdown'],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'files',
|
|
68
|
+
name: 'File Operations',
|
|
69
|
+
description: 'Read, write, and manage files',
|
|
70
|
+
tags: ['files', 'documents'],
|
|
71
|
+
inputModes: ['text/plain', 'application/pdf', 'image/*'],
|
|
72
|
+
outputModes: ['text/plain', 'text/markdown'],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
40
75
|
},
|
|
41
76
|
});
|
|
42
77
|
// Set up event handlers
|
package/dist/src/types.d.ts
CHANGED
|
@@ -18,12 +18,21 @@ export interface A2AMessage {
|
|
|
18
18
|
status?: 'working' | 'completed' | 'failed' | 'canceled';
|
|
19
19
|
error?: string;
|
|
20
20
|
}
|
|
21
|
-
export interface
|
|
21
|
+
export interface A2ASkill {
|
|
22
22
|
id: string;
|
|
23
23
|
name: string;
|
|
24
24
|
description?: string;
|
|
25
|
-
|
|
25
|
+
tags?: string[];
|
|
26
|
+
examples?: string[];
|
|
27
|
+
inputModes?: string[];
|
|
28
|
+
outputModes?: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface A2AAgentCard {
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
26
33
|
url?: string;
|
|
34
|
+
version?: string;
|
|
35
|
+
skills?: A2ASkill[];
|
|
27
36
|
}
|
|
28
37
|
export interface A2AResponse {
|
|
29
38
|
text: string;
|
|
@@ -45,6 +54,7 @@ export interface A2AChannelConfig {
|
|
|
45
54
|
apiKey: string;
|
|
46
55
|
hubUrl?: string;
|
|
47
56
|
requestTimeoutMs?: number;
|
|
57
|
+
agentCard?: A2AAgentCard;
|
|
48
58
|
};
|
|
49
59
|
auth?: {
|
|
50
60
|
token?: string;
|
package/index.ts
CHANGED
|
@@ -52,6 +52,10 @@ const plugin = {
|
|
|
52
52
|
type: 'string',
|
|
53
53
|
description: 'Path to image file to send (for send action)',
|
|
54
54
|
},
|
|
55
|
+
file: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'Path to file to send - PDF, documents, etc. (for send action)',
|
|
58
|
+
},
|
|
55
59
|
},
|
|
56
60
|
required: ['action'],
|
|
57
61
|
},
|
|
@@ -60,6 +64,7 @@ const plugin = {
|
|
|
60
64
|
const agentId = params.agentId as string | undefined;
|
|
61
65
|
const message = params.message as string | undefined;
|
|
62
66
|
const imagePath = params.image as string | undefined;
|
|
67
|
+
const filePath = params.file as string | undefined;
|
|
63
68
|
|
|
64
69
|
const manager = getA2AConnectionManager();
|
|
65
70
|
if (!manager) {
|
|
@@ -72,8 +77,8 @@ const plugin = {
|
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
if (action === 'send') {
|
|
75
|
-
if (!agentId || (!message && !imagePath)) {
|
|
76
|
-
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'agentId and (message or
|
|
80
|
+
if (!agentId || (!message && !imagePath && !filePath)) {
|
|
81
|
+
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: 'agentId and (message, image, or file) required for send action' }) }] };
|
|
77
82
|
}
|
|
78
83
|
try {
|
|
79
84
|
const isGopherHoleConnected = manager.isGopherHoleConnected();
|
|
@@ -87,24 +92,42 @@ const plugin = {
|
|
|
87
92
|
parts.push({ kind: 'text', text: message });
|
|
88
93
|
}
|
|
89
94
|
|
|
90
|
-
// Add
|
|
91
|
-
|
|
95
|
+
// Add file part if image or file path provided
|
|
96
|
+
const attachmentPath = imagePath || filePath;
|
|
97
|
+
if (attachmentPath) {
|
|
92
98
|
try {
|
|
93
|
-
const
|
|
94
|
-
const base64Data =
|
|
95
|
-
const ext = extname(
|
|
99
|
+
const fileData = readFileSync(attachmentPath);
|
|
100
|
+
const base64Data = fileData.toString('base64');
|
|
101
|
+
const ext = extname(attachmentPath).toLowerCase();
|
|
96
102
|
const mimeTypes: Record<string, string> = {
|
|
103
|
+
// Images
|
|
97
104
|
'.png': 'image/png',
|
|
98
105
|
'.jpg': 'image/jpeg',
|
|
99
106
|
'.jpeg': 'image/jpeg',
|
|
100
107
|
'.gif': 'image/gif',
|
|
101
108
|
'.webp': 'image/webp',
|
|
102
109
|
'.svg': 'image/svg+xml',
|
|
110
|
+
// Documents
|
|
111
|
+
'.pdf': 'application/pdf',
|
|
112
|
+
'.doc': 'application/msword',
|
|
113
|
+
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
114
|
+
'.xls': 'application/vnd.ms-excel',
|
|
115
|
+
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
116
|
+
'.ppt': 'application/vnd.ms-powerpoint',
|
|
117
|
+
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
118
|
+
'.txt': 'text/plain',
|
|
119
|
+
'.csv': 'text/csv',
|
|
120
|
+
'.json': 'application/json',
|
|
121
|
+
'.xml': 'application/xml',
|
|
122
|
+
'.html': 'text/html',
|
|
123
|
+
'.md': 'text/markdown',
|
|
124
|
+
// Archives
|
|
125
|
+
'.zip': 'application/zip',
|
|
103
126
|
};
|
|
104
127
|
const mimeType = mimeTypes[ext] || 'application/octet-stream';
|
|
105
128
|
parts.push({ kind: 'data', data: base64Data, mimeType });
|
|
106
|
-
} catch (
|
|
107
|
-
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: `Failed to read
|
|
129
|
+
} catch (fileErr) {
|
|
130
|
+
return { content: [{ type: 'text', text: JSON.stringify({ status: 'error', error: `Failed to read file: ${(fileErr as Error).message}` }) }] };
|
|
108
131
|
}
|
|
109
132
|
}
|
|
110
133
|
|
package/package.json
CHANGED
package/src/connection.ts
CHANGED
|
@@ -49,9 +49,44 @@ export class A2AConnectionManager {
|
|
|
49
49
|
maxReconnectAttempts: 20,
|
|
50
50
|
requestTimeout: timeoutMs,
|
|
51
51
|
messageTimeout: timeoutMs,
|
|
52
|
-
agentCard: {
|
|
53
|
-
name: this.config.agentName ?? '
|
|
54
|
-
description: '
|
|
52
|
+
agentCard: gphConfig.agentCard ?? {
|
|
53
|
+
name: this.config.agentName ?? 'OpenClaw',
|
|
54
|
+
description: 'Personal AI assistant with tools, web search, browser control, and various skills',
|
|
55
|
+
version: '0.1.0',
|
|
56
|
+
skills: [
|
|
57
|
+
{
|
|
58
|
+
id: 'chat',
|
|
59
|
+
name: 'Chat',
|
|
60
|
+
description: 'General conversation and Q&A',
|
|
61
|
+
tags: ['conversation', 'assistant'],
|
|
62
|
+
inputModes: ['text/plain'],
|
|
63
|
+
outputModes: ['text/plain', 'text/markdown'],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'web-search',
|
|
67
|
+
name: 'Web Search',
|
|
68
|
+
description: 'Search the web and summarize results',
|
|
69
|
+
tags: ['search', 'research', 'web'],
|
|
70
|
+
inputModes: ['text/plain'],
|
|
71
|
+
outputModes: ['text/plain', 'text/markdown'],
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: 'coding',
|
|
75
|
+
name: 'Coding',
|
|
76
|
+
description: 'Write, review, and debug code',
|
|
77
|
+
tags: ['code', 'programming', 'development'],
|
|
78
|
+
inputModes: ['text/plain'],
|
|
79
|
+
outputModes: ['text/plain', 'text/markdown'],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: 'files',
|
|
83
|
+
name: 'File Operations',
|
|
84
|
+
description: 'Read, write, and manage files',
|
|
85
|
+
tags: ['files', 'documents'],
|
|
86
|
+
inputModes: ['text/plain', 'application/pdf', 'image/*'],
|
|
87
|
+
outputModes: ['text/plain', 'text/markdown'],
|
|
88
|
+
},
|
|
89
|
+
],
|
|
55
90
|
},
|
|
56
91
|
});
|
|
57
92
|
|
package/src/types.ts
CHANGED
|
@@ -15,12 +15,22 @@ export interface A2AMessage {
|
|
|
15
15
|
error?: string;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export interface
|
|
18
|
+
export interface A2ASkill {
|
|
19
19
|
id: string;
|
|
20
20
|
name: string;
|
|
21
21
|
description?: string;
|
|
22
|
-
|
|
22
|
+
tags?: string[];
|
|
23
|
+
examples?: string[];
|
|
24
|
+
inputModes?: string[];
|
|
25
|
+
outputModes?: string[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface A2AAgentCard {
|
|
29
|
+
name: string;
|
|
30
|
+
description?: string;
|
|
23
31
|
url?: string;
|
|
32
|
+
version?: string;
|
|
33
|
+
skills?: A2ASkill[];
|
|
24
34
|
}
|
|
25
35
|
|
|
26
36
|
export interface A2AResponse {
|
|
@@ -44,6 +54,7 @@ export interface A2AChannelConfig {
|
|
|
44
54
|
apiKey: string;
|
|
45
55
|
hubUrl?: string; // Default: wss://gopherhole.ai/ws
|
|
46
56
|
requestTimeoutMs?: number;
|
|
57
|
+
agentCard?: A2AAgentCard; // Custom agent card (overrides defaults)
|
|
47
58
|
};
|
|
48
59
|
auth?: {
|
|
49
60
|
token?: string;
|