@agentconnect/sdk 0.1.7 → 0.2.1
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 +17 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +4 -2
- package/package.json +1 -6
- package/dist/host.d.ts +0 -10
- package/dist/host.js +0 -184
package/README.md
CHANGED
|
@@ -91,6 +91,23 @@ await session.close();
|
|
|
91
91
|
client.close();
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
## Embedded host (Node backend)
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { AgentConnect } from '@agentconnect/sdk';
|
|
98
|
+
import { createHostBridge } from '@agentconnect/host';
|
|
99
|
+
|
|
100
|
+
globalThis.__AGENTCONNECT_BRIDGE__ = createHostBridge({
|
|
101
|
+
mode: 'embedded',
|
|
102
|
+
basePath: process.cwd(),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const client = await AgentConnect.connect({ preferInjected: true });
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
If your SDK runs in the browser, expose a WebSocket host from your backend using
|
|
109
|
+
`startDevHost` and connect with `AgentConnect.connect({ host: 'ws://...' })`.
|
|
110
|
+
|
|
94
111
|
## Provider and model helpers
|
|
95
112
|
|
|
96
113
|
```ts
|
package/dist/index.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export type SessionEvent = {
|
|
|
46
46
|
} | {
|
|
47
47
|
type: 'final';
|
|
48
48
|
text: string;
|
|
49
|
+
cancelled?: boolean;
|
|
49
50
|
providerSessionId?: string | null;
|
|
50
51
|
providerDetail?: ProviderDetail;
|
|
51
52
|
} | {
|
|
@@ -62,6 +63,7 @@ export type SessionEvent = {
|
|
|
62
63
|
} | {
|
|
63
64
|
type: 'error';
|
|
64
65
|
message: string;
|
|
66
|
+
cancelled?: boolean;
|
|
65
67
|
providerSessionId?: string | null;
|
|
66
68
|
providerDetail?: ProviderDetail;
|
|
67
69
|
} | {
|
|
@@ -116,7 +118,8 @@ export type AgentConnectConnectOptions = {
|
|
|
116
118
|
webSocket?: WebSocketConstructor;
|
|
117
119
|
};
|
|
118
120
|
export type SessionCreateOptions = {
|
|
119
|
-
model
|
|
121
|
+
model?: string;
|
|
122
|
+
provider?: ProviderId;
|
|
120
123
|
reasoningEffort?: string;
|
|
121
124
|
system?: string;
|
|
122
125
|
metadata?: Record<string, unknown>;
|
|
@@ -163,7 +166,10 @@ export interface AgentConnectClient {
|
|
|
163
166
|
close(): void;
|
|
164
167
|
providers: {
|
|
165
168
|
list(): Promise<ProviderInfo[]>;
|
|
166
|
-
status(provider: ProviderId
|
|
169
|
+
status(provider: ProviderId, options?: {
|
|
170
|
+
fast?: boolean;
|
|
171
|
+
force?: boolean;
|
|
172
|
+
}): Promise<ProviderInfo>;
|
|
167
173
|
ensureInstalled(provider: ProviderId): Promise<InstallResult>;
|
|
168
174
|
update(provider: ProviderId): Promise<ProviderInfo>;
|
|
169
175
|
login(provider: ProviderId, options?: ProviderLoginOptions): Promise<{
|
package/dist/index.js
CHANGED
|
@@ -268,6 +268,7 @@ class AgentConnectClientImpl {
|
|
|
268
268
|
return {
|
|
269
269
|
type: 'final',
|
|
270
270
|
text: String(data?.text ?? ''),
|
|
271
|
+
cancelled: typeof data?.cancelled === 'boolean' ? data.cancelled : undefined,
|
|
271
272
|
providerSessionId,
|
|
272
273
|
...(providerDetail && { providerDetail }),
|
|
273
274
|
};
|
|
@@ -295,6 +296,7 @@ class AgentConnectClientImpl {
|
|
|
295
296
|
return {
|
|
296
297
|
type: 'error',
|
|
297
298
|
message: String(data?.message ?? 'Unknown error'),
|
|
299
|
+
cancelled: typeof data?.cancelled === 'boolean' ? data.cancelled : undefined,
|
|
298
300
|
providerSessionId,
|
|
299
301
|
...(providerDetail && { providerDetail }),
|
|
300
302
|
};
|
|
@@ -386,8 +388,8 @@ class AgentConnectClientImpl {
|
|
|
386
388
|
const res = (await this.request('acp.providers.list'));
|
|
387
389
|
return res.providers ?? [];
|
|
388
390
|
},
|
|
389
|
-
status: async (provider) => {
|
|
390
|
-
const res = (await this.request('acp.providers.status', { provider }));
|
|
391
|
+
status: async (provider, options) => {
|
|
392
|
+
const res = (await this.request('acp.providers.status', { provider, options }));
|
|
391
393
|
return res.provider;
|
|
392
394
|
},
|
|
393
395
|
update: async (provider) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentconnect/sdk",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/rayzhudev/agent-connect",
|
|
@@ -19,11 +19,6 @@
|
|
|
19
19
|
"import": "./dist/index.js",
|
|
20
20
|
"types": "./dist/index.d.ts",
|
|
21
21
|
"default": "./dist/index.js"
|
|
22
|
-
},
|
|
23
|
-
"./host": {
|
|
24
|
-
"import": "./dist/host.js",
|
|
25
|
-
"types": "./dist/host.d.ts",
|
|
26
|
-
"default": "./dist/host.js"
|
|
27
22
|
}
|
|
28
23
|
},
|
|
29
24
|
"files": [
|
package/dist/host.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export type EnsureHostOptions = {
|
|
2
|
-
host?: string;
|
|
3
|
-
port?: number;
|
|
4
|
-
appPath?: string;
|
|
5
|
-
cliPackage?: string;
|
|
6
|
-
runtime?: string;
|
|
7
|
-
timeoutMs?: number;
|
|
8
|
-
debug?: boolean;
|
|
9
|
-
};
|
|
10
|
-
export declare function ensureAgentConnectHost(options?: EnsureHostOptions): Promise<void>;
|
package/dist/host.js
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import net from 'net';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { spawn } from 'child_process';
|
|
5
|
-
const HOST_KEY = '__agentconnectHostState__';
|
|
6
|
-
function getState() {
|
|
7
|
-
const globalAny = globalThis;
|
|
8
|
-
if (!globalAny[HOST_KEY]) {
|
|
9
|
-
globalAny[HOST_KEY] = { status: 'idle' };
|
|
10
|
-
}
|
|
11
|
-
return globalAny[HOST_KEY];
|
|
12
|
-
}
|
|
13
|
-
function findExecutable(name) {
|
|
14
|
-
const envPath = process.env.PATH || '';
|
|
15
|
-
const extensions = process.platform === 'win32' ? ['.exe', '.cmd', '.bat', ''] : [''];
|
|
16
|
-
for (const entry of envPath.split(path.delimiter)) {
|
|
17
|
-
if (!entry)
|
|
18
|
-
continue;
|
|
19
|
-
for (const ext of extensions) {
|
|
20
|
-
const candidate = path.join(entry, `${name}${ext}`);
|
|
21
|
-
try {
|
|
22
|
-
fs.accessSync(candidate, fs.constants.X_OK);
|
|
23
|
-
return candidate;
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
function findPackageRoot(startDir, pkgName) {
|
|
33
|
-
let current = startDir;
|
|
34
|
-
while (true) {
|
|
35
|
-
const candidate = path.join(current, 'node_modules', pkgName, 'package.json');
|
|
36
|
-
if (fs.existsSync(candidate))
|
|
37
|
-
return path.dirname(candidate);
|
|
38
|
-
const parent = path.dirname(current);
|
|
39
|
-
if (parent === current)
|
|
40
|
-
break;
|
|
41
|
-
current = parent;
|
|
42
|
-
}
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
function resolveCliEntry(appPath, cliPackage) {
|
|
46
|
-
const pkgRoot = findPackageRoot(appPath, cliPackage);
|
|
47
|
-
if (!pkgRoot) {
|
|
48
|
-
throw new Error(`AgentConnect CLI not found. Install ${cliPackage} and retry.`);
|
|
49
|
-
}
|
|
50
|
-
const pkgJsonPath = path.join(pkgRoot, 'package.json');
|
|
51
|
-
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
|
|
52
|
-
let entry = pkg.main || 'dist/index.js';
|
|
53
|
-
if (typeof pkg.bin === 'string') {
|
|
54
|
-
entry = pkg.bin;
|
|
55
|
-
}
|
|
56
|
-
else if (pkg.bin && typeof pkg.bin === 'object') {
|
|
57
|
-
entry = pkg.bin.agentconnect || entry;
|
|
58
|
-
}
|
|
59
|
-
const resolved = path.join(pkgRoot, entry);
|
|
60
|
-
if (!fs.existsSync(resolved)) {
|
|
61
|
-
throw new Error(`AgentConnect CLI entry not found at ${resolved}`);
|
|
62
|
-
}
|
|
63
|
-
return resolved;
|
|
64
|
-
}
|
|
65
|
-
function resolveRuntime(runtime) {
|
|
66
|
-
if (runtime)
|
|
67
|
-
return runtime;
|
|
68
|
-
const override = process.env.AGENTCONNECT_NODE;
|
|
69
|
-
if (override)
|
|
70
|
-
return override;
|
|
71
|
-
if (!process.execPath.toLowerCase().includes('bun'))
|
|
72
|
-
return process.execPath;
|
|
73
|
-
return findExecutable('node') || 'node';
|
|
74
|
-
}
|
|
75
|
-
function isPortOpen(host, port, timeoutMs = 300) {
|
|
76
|
-
return new Promise((resolve) => {
|
|
77
|
-
const socket = new net.Socket();
|
|
78
|
-
const finalize = (result) => {
|
|
79
|
-
socket.destroy();
|
|
80
|
-
resolve(result);
|
|
81
|
-
};
|
|
82
|
-
socket.setTimeout(timeoutMs);
|
|
83
|
-
socket.once('error', () => finalize(false));
|
|
84
|
-
socket.once('timeout', () => finalize(false));
|
|
85
|
-
socket.connect(port, host, () => finalize(true));
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
async function waitForPort(host, port, child, timeoutMs) {
|
|
89
|
-
const start = Date.now();
|
|
90
|
-
while (Date.now() - start < timeoutMs) {
|
|
91
|
-
if (await isPortOpen(host, port))
|
|
92
|
-
return true;
|
|
93
|
-
if (child?.exitCode !== null)
|
|
94
|
-
return false;
|
|
95
|
-
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
96
|
-
}
|
|
97
|
-
return isPortOpen(host, port);
|
|
98
|
-
}
|
|
99
|
-
function registerCleanup(state) {
|
|
100
|
-
if (state.cleanupRegistered)
|
|
101
|
-
return;
|
|
102
|
-
state.cleanupRegistered = true;
|
|
103
|
-
process.on('exit', () => {
|
|
104
|
-
state.child?.kill('SIGTERM');
|
|
105
|
-
});
|
|
106
|
-
process.on('SIGINT', () => {
|
|
107
|
-
state.child?.kill('SIGTERM');
|
|
108
|
-
process.exit(0);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
async function startHost(options, state) {
|
|
112
|
-
const cliPath = resolveCliEntry(options.appPath, options.cliPackage);
|
|
113
|
-
const args = [
|
|
114
|
-
cliPath,
|
|
115
|
-
'dev',
|
|
116
|
-
'--host',
|
|
117
|
-
options.host,
|
|
118
|
-
'--port',
|
|
119
|
-
String(options.port),
|
|
120
|
-
'--app',
|
|
121
|
-
options.appPath,
|
|
122
|
-
];
|
|
123
|
-
const runtime = resolveRuntime(options.runtime);
|
|
124
|
-
if (options.debug) {
|
|
125
|
-
console.info('[AgentConnect][Host] starting', { runtime, args });
|
|
126
|
-
}
|
|
127
|
-
const child = spawn(runtime, args, { stdio: options.debug ? 'pipe' : 'ignore' });
|
|
128
|
-
state.child = child;
|
|
129
|
-
state.status = 'starting';
|
|
130
|
-
registerCleanup(state);
|
|
131
|
-
if (options.debug) {
|
|
132
|
-
child.stdout?.on('data', (chunk) => {
|
|
133
|
-
console.info('[AgentConnect][Host]', String(chunk).trim());
|
|
134
|
-
});
|
|
135
|
-
child.stderr?.on('data', (chunk) => {
|
|
136
|
-
console.error('[AgentConnect][Host]', String(chunk).trim());
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
child.on('error', (error) => {
|
|
140
|
-
if (options.debug) {
|
|
141
|
-
console.error('[AgentConnect][Host] spawn error', error);
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
child.on('exit', () => {
|
|
145
|
-
if (state.child === child) {
|
|
146
|
-
state.status = 'idle';
|
|
147
|
-
state.child = undefined;
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
const started = await waitForPort(options.host, options.port, child, options.timeoutMs);
|
|
151
|
-
if (!started) {
|
|
152
|
-
child.kill('SIGTERM');
|
|
153
|
-
throw new Error('AgentConnect host failed to start. Ensure Node.js 20+ is installed.');
|
|
154
|
-
}
|
|
155
|
-
state.status = 'running';
|
|
156
|
-
}
|
|
157
|
-
export async function ensureAgentConnectHost(options = {}) {
|
|
158
|
-
const state = getState();
|
|
159
|
-
const resolvedOptions = {
|
|
160
|
-
host: options.host || process.env.AGENTCONNECT_HOST || '127.0.0.1',
|
|
161
|
-
port: options.port || Number(process.env.AGENTCONNECT_PORT || 9630),
|
|
162
|
-
appPath: options.appPath || process.env.AGENTCONNECT_APP_PATH || process.cwd(),
|
|
163
|
-
cliPackage: options.cliPackage || process.env.AGENTCONNECT_CLI_PACKAGE || '@agentconnect/cli',
|
|
164
|
-
runtime: options.runtime || '',
|
|
165
|
-
timeoutMs: options.timeoutMs || 8000,
|
|
166
|
-
debug: options.debug ?? process.env.AGENTCONNECT_DEBUG === '1',
|
|
167
|
-
};
|
|
168
|
-
if (await isPortOpen(resolvedOptions.host, resolvedOptions.port)) {
|
|
169
|
-
state.status = 'running';
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
if (state.startPromise)
|
|
173
|
-
return state.startPromise;
|
|
174
|
-
state.startPromise = startHost(resolvedOptions, state)
|
|
175
|
-
.catch((error) => {
|
|
176
|
-
state.status = 'idle';
|
|
177
|
-
state.child = undefined;
|
|
178
|
-
throw error;
|
|
179
|
-
})
|
|
180
|
-
.finally(() => {
|
|
181
|
-
state.startPromise = undefined;
|
|
182
|
-
});
|
|
183
|
-
return state.startPromise;
|
|
184
|
-
}
|