@annals/agent-mesh 0.14.0 → 0.15.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/dist/index.js +310 -185
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1007,7 +1007,6 @@ var SENSITIVE_PATHS = [
|
|
|
1007
1007
|
// contains ah_ platform token
|
|
1008
1008
|
"~/.agent-mesh/pids",
|
|
1009
1009
|
"~/.agent-mesh/logs",
|
|
1010
|
-
"~/.codex",
|
|
1011
1010
|
// Package manager tokens
|
|
1012
1011
|
"~/.npmrc",
|
|
1013
1012
|
"~/.yarnrc",
|
|
@@ -1027,16 +1026,6 @@ var SANDBOX_PRESETS = {
|
|
|
1027
1026
|
allowWrite: [".", "/tmp"],
|
|
1028
1027
|
denyWrite: [".env", ".env.*"]
|
|
1029
1028
|
},
|
|
1030
|
-
codex: {
|
|
1031
|
-
denyRead: [...SENSITIVE_PATHS],
|
|
1032
|
-
allowWrite: [".", "/tmp"],
|
|
1033
|
-
denyWrite: [".env", ".env.*"]
|
|
1034
|
-
},
|
|
1035
|
-
gemini: {
|
|
1036
|
-
denyRead: [...SENSITIVE_PATHS],
|
|
1037
|
-
allowWrite: [".", "/tmp"],
|
|
1038
|
-
denyWrite: [".env", ".env.*"]
|
|
1039
|
-
},
|
|
1040
1029
|
openclaw: {
|
|
1041
1030
|
denyRead: [...SENSITIVE_PATHS],
|
|
1042
1031
|
allowWrite: ["/tmp"],
|
|
@@ -1748,34 +1737,6 @@ var ClaudeAdapter = class extends AgentAdapter {
|
|
|
1748
1737
|
}
|
|
1749
1738
|
};
|
|
1750
1739
|
|
|
1751
|
-
// src/adapters/codex.ts
|
|
1752
|
-
var CodexAdapter = class extends AgentAdapter {
|
|
1753
|
-
type = "codex";
|
|
1754
|
-
displayName = "Codex CLI";
|
|
1755
|
-
async isAvailable() {
|
|
1756
|
-
return false;
|
|
1757
|
-
}
|
|
1758
|
-
createSession(_id, _config) {
|
|
1759
|
-
throw new Error("Codex adapter not yet implemented");
|
|
1760
|
-
}
|
|
1761
|
-
destroySession(_id) {
|
|
1762
|
-
}
|
|
1763
|
-
};
|
|
1764
|
-
|
|
1765
|
-
// src/adapters/gemini.ts
|
|
1766
|
-
var GeminiAdapter = class extends AgentAdapter {
|
|
1767
|
-
type = "gemini";
|
|
1768
|
-
displayName = "Gemini CLI";
|
|
1769
|
-
async isAvailable() {
|
|
1770
|
-
return false;
|
|
1771
|
-
}
|
|
1772
|
-
createSession(_id, _config) {
|
|
1773
|
-
throw new Error("Gemini adapter not yet implemented");
|
|
1774
|
-
}
|
|
1775
|
-
destroySession(_id) {
|
|
1776
|
-
}
|
|
1777
|
-
};
|
|
1778
|
-
|
|
1779
1740
|
// src/commands/connect.ts
|
|
1780
1741
|
var DEFAULT_BRIDGE_URL = "wss://bridge.agents.hot/ws";
|
|
1781
1742
|
function logWorkspaceHint(slug, projectPath) {
|
|
@@ -1791,12 +1752,8 @@ function createAdapter(type, config) {
|
|
|
1791
1752
|
return new OpenClawAdapter(config);
|
|
1792
1753
|
case "claude":
|
|
1793
1754
|
return new ClaudeAdapter(config);
|
|
1794
|
-
case "codex":
|
|
1795
|
-
return new CodexAdapter(config);
|
|
1796
|
-
case "gemini":
|
|
1797
|
-
return new GeminiAdapter(config);
|
|
1798
1755
|
default:
|
|
1799
|
-
throw new Error(`Unknown agent type: ${type}. Supported: openclaw, claude
|
|
1756
|
+
throw new Error(`Unknown agent type: ${type}. Supported: openclaw, claude`);
|
|
1800
1757
|
}
|
|
1801
1758
|
}
|
|
1802
1759
|
function registerConnectCommand(program2) {
|
|
@@ -1962,11 +1919,7 @@ function registerConnectCommand(program2) {
|
|
|
1962
1919
|
log.info(`Checking ${adapter.displayName} availability...`);
|
|
1963
1920
|
const available = await adapter.isAvailable();
|
|
1964
1921
|
if (!available) {
|
|
1965
|
-
|
|
1966
|
-
log.error(`${adapter.displayName} adapter is not yet implemented. Supported adapters: openclaw, claude`);
|
|
1967
|
-
} else {
|
|
1968
|
-
log.error(`${adapter.displayName} is not available. Make sure it is installed and running.`);
|
|
1969
|
-
}
|
|
1922
|
+
log.error(`${adapter.displayName} is not available. Make sure it is installed and running.`);
|
|
1970
1923
|
process.exit(1);
|
|
1971
1924
|
}
|
|
1972
1925
|
log.success(`${adapter.displayName} is available`);
|
|
@@ -2208,7 +2161,7 @@ function registerStatusCommand(program2) {
|
|
|
2208
2161
|
}
|
|
2209
2162
|
console.log("\nTo connect an agent, run:");
|
|
2210
2163
|
console.log(" agent-mesh connect <type> --agent-id <id>");
|
|
2211
|
-
console.log("\nSupported types: openclaw, claude
|
|
2164
|
+
console.log("\nSupported types: openclaw, claude");
|
|
2212
2165
|
});
|
|
2213
2166
|
}
|
|
2214
2167
|
|
|
@@ -2943,18 +2896,18 @@ async function asyncChat(opts) {
|
|
|
2943
2896
|
}
|
|
2944
2897
|
throw new Error(msg);
|
|
2945
2898
|
}
|
|
2946
|
-
const {
|
|
2899
|
+
const { request_id, status, error_message, error_code } = await res.json();
|
|
2947
2900
|
if (status === "failed") {
|
|
2948
2901
|
throw new Error(`Task failed: ${error_message || error_code}`);
|
|
2949
2902
|
}
|
|
2950
|
-
process.stderr.write(`${GRAY}[async]
|
|
2903
|
+
process.stderr.write(`${GRAY}[async] request=${request_id.slice(0, 8)}... polling${RESET}`);
|
|
2951
2904
|
const maxWait = 5 * 60 * 1e3;
|
|
2952
2905
|
const pollInterval = 2e3;
|
|
2953
2906
|
const startTime = Date.now();
|
|
2954
2907
|
while (Date.now() - startTime < maxWait) {
|
|
2955
2908
|
if (opts.signal?.aborted) throw new Error("Aborted");
|
|
2956
2909
|
await sleep4(pollInterval);
|
|
2957
|
-
const pollRes = await fetch(`${opts.baseUrl}/api/
|
|
2910
|
+
const pollRes = await fetch(`${opts.baseUrl}/api/agents/${opts.agentId}/task-status/${request_id}`, {
|
|
2958
2911
|
headers: { Authorization: `Bearer ${opts.token}` },
|
|
2959
2912
|
signal: opts.signal
|
|
2960
2913
|
});
|
|
@@ -2980,7 +2933,7 @@ async function asyncChat(opts) {
|
|
|
2980
2933
|
throw new Error("Task timed out waiting for result");
|
|
2981
2934
|
}
|
|
2982
2935
|
async function streamChat(opts) {
|
|
2983
|
-
if (
|
|
2936
|
+
if (opts.mode === "async") {
|
|
2984
2937
|
return asyncChat(opts);
|
|
2985
2938
|
}
|
|
2986
2939
|
const res = await fetch(`${opts.baseUrl}/api/agents/${opts.agentId}/chat`, {
|
|
@@ -3083,7 +3036,7 @@ ${"\x1B[31m"}Error: ${event.errorText}${RESET}
|
|
|
3083
3036
|
}
|
|
3084
3037
|
}
|
|
3085
3038
|
function registerChatCommand(program2) {
|
|
3086
|
-
program2.command("chat <agent> [message]").description("Chat with an agent through the platform (for debugging)").option("--no-thinking", "Hide thinking/reasoning output").option("--
|
|
3039
|
+
program2.command("chat <agent> [message]").description("Chat with an agent through the platform (for debugging)").option("--no-thinking", "Hide thinking/reasoning output").option("--async", "Use async polling mode (default is stream)").option("--base-url <url>", "Platform base URL", DEFAULT_BASE_URL3).action(async (agentInput, inlineMessage, opts) => {
|
|
3087
3040
|
const token = loadToken();
|
|
3088
3041
|
if (!token) {
|
|
3089
3042
|
log.error("Not authenticated. Run `agent-mesh login` first.");
|
|
@@ -3100,7 +3053,7 @@ function registerChatCommand(program2) {
|
|
|
3100
3053
|
log.error(err.message);
|
|
3101
3054
|
process.exit(1);
|
|
3102
3055
|
}
|
|
3103
|
-
const mode = opts.
|
|
3056
|
+
const mode = opts.async ? "async" : "stream";
|
|
3104
3057
|
if (inlineMessage) {
|
|
3105
3058
|
log.info(`Chatting with ${BOLD}${agentName}${RESET} (${mode})`);
|
|
3106
3059
|
try {
|
|
@@ -3853,6 +3806,9 @@ function registerDiscoverCommand(program2) {
|
|
|
3853
3806
|
// src/commands/call.ts
|
|
3854
3807
|
import { readFileSync, writeFileSync as writeFileSync2 } from "fs";
|
|
3855
3808
|
var DEFAULT_BASE_URL4 = "https://agents.hot";
|
|
3809
|
+
function sleep5(ms) {
|
|
3810
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
3811
|
+
}
|
|
3856
3812
|
function handleError2(err) {
|
|
3857
3813
|
if (err instanceof PlatformApiError) {
|
|
3858
3814
|
log.error(err.message);
|
|
@@ -3861,8 +3817,228 @@ function handleError2(err) {
|
|
|
3861
3817
|
}
|
|
3862
3818
|
process.exit(1);
|
|
3863
3819
|
}
|
|
3820
|
+
async function asyncCall(opts) {
|
|
3821
|
+
const selfAgentId = process.env.AGENT_BRIDGE_AGENT_ID;
|
|
3822
|
+
const res = await fetch(`${DEFAULT_BASE_URL4}/api/agents/${opts.id}/call`, {
|
|
3823
|
+
method: "POST",
|
|
3824
|
+
headers: {
|
|
3825
|
+
Authorization: `Bearer ${opts.token}`,
|
|
3826
|
+
"Content-Type": "application/json",
|
|
3827
|
+
...selfAgentId ? { "X-Caller-Agent-Id": selfAgentId } : {}
|
|
3828
|
+
},
|
|
3829
|
+
body: JSON.stringify({ task_description: opts.taskDescription, mode: "async" }),
|
|
3830
|
+
signal: opts.signal
|
|
3831
|
+
});
|
|
3832
|
+
if (!res.ok) {
|
|
3833
|
+
let msg = `HTTP ${res.status}`;
|
|
3834
|
+
let errorCode = "";
|
|
3835
|
+
try {
|
|
3836
|
+
const body = await res.json();
|
|
3837
|
+
errorCode = body.error || "";
|
|
3838
|
+
msg = body.message || body.error || msg;
|
|
3839
|
+
} catch {
|
|
3840
|
+
}
|
|
3841
|
+
if (errorCode === "subscription_required") {
|
|
3842
|
+
log.error("This is a private agent.");
|
|
3843
|
+
console.error(` Subscribe first: agent-mesh subscribe <author-login>`);
|
|
3844
|
+
} else {
|
|
3845
|
+
log.error(msg);
|
|
3846
|
+
}
|
|
3847
|
+
process.exit(1);
|
|
3848
|
+
}
|
|
3849
|
+
const { request_id, call_id, status, error_message, error_code } = await res.json();
|
|
3850
|
+
if (status === "failed") {
|
|
3851
|
+
log.error(`Call failed: ${error_message || error_code}`);
|
|
3852
|
+
process.exit(1);
|
|
3853
|
+
}
|
|
3854
|
+
if (!opts.json) {
|
|
3855
|
+
process.stderr.write(`${GRAY}[async] call=${call_id.slice(0, 8)}... request=${request_id.slice(0, 8)}... polling${RESET}`);
|
|
3856
|
+
}
|
|
3857
|
+
const pollInterval = 2e3;
|
|
3858
|
+
const startTime = Date.now();
|
|
3859
|
+
while (Date.now() - startTime < opts.timeoutMs) {
|
|
3860
|
+
if (opts.signal?.aborted) {
|
|
3861
|
+
log.error("Aborted");
|
|
3862
|
+
process.exit(1);
|
|
3863
|
+
}
|
|
3864
|
+
await sleep5(pollInterval);
|
|
3865
|
+
const pollRes = await fetch(`${DEFAULT_BASE_URL4}/api/agents/${opts.id}/task-status/${request_id}`, {
|
|
3866
|
+
headers: { Authorization: `Bearer ${opts.token}` },
|
|
3867
|
+
signal: opts.signal
|
|
3868
|
+
});
|
|
3869
|
+
if (!pollRes.ok) {
|
|
3870
|
+
log.error(`Poll failed: HTTP ${pollRes.status}`);
|
|
3871
|
+
process.exit(1);
|
|
3872
|
+
}
|
|
3873
|
+
const task = await pollRes.json();
|
|
3874
|
+
if (task.status === "completed") {
|
|
3875
|
+
if (!opts.json) {
|
|
3876
|
+
process.stderr.write(` done
|
|
3877
|
+
`);
|
|
3878
|
+
}
|
|
3879
|
+
const result = task.result || "";
|
|
3880
|
+
if (opts.json) {
|
|
3881
|
+
console.log(JSON.stringify({ call_id, request_id, status: "completed", result }));
|
|
3882
|
+
} else {
|
|
3883
|
+
process.stdout.write(result + "\n");
|
|
3884
|
+
}
|
|
3885
|
+
if (opts.outputFile && result) {
|
|
3886
|
+
writeFileSync2(opts.outputFile, result);
|
|
3887
|
+
if (!opts.json) log.info(`Saved to ${opts.outputFile}`);
|
|
3888
|
+
}
|
|
3889
|
+
return;
|
|
3890
|
+
}
|
|
3891
|
+
if (task.status === "failed") {
|
|
3892
|
+
if (!opts.json) {
|
|
3893
|
+
process.stderr.write(` failed
|
|
3894
|
+
`);
|
|
3895
|
+
}
|
|
3896
|
+
log.error(`Call failed: ${task.error_message || task.error_code}`);
|
|
3897
|
+
process.exit(1);
|
|
3898
|
+
}
|
|
3899
|
+
if (!opts.json) {
|
|
3900
|
+
process.stderr.write(".");
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
if (!opts.json) {
|
|
3904
|
+
process.stderr.write(` timeout
|
|
3905
|
+
`);
|
|
3906
|
+
}
|
|
3907
|
+
log.error("Call timed out waiting for result");
|
|
3908
|
+
process.exit(1);
|
|
3909
|
+
}
|
|
3910
|
+
async function streamCall(opts) {
|
|
3911
|
+
const selfAgentId = process.env.AGENT_BRIDGE_AGENT_ID;
|
|
3912
|
+
const res = await fetch(`${DEFAULT_BASE_URL4}/api/agents/${opts.id}/call`, {
|
|
3913
|
+
method: "POST",
|
|
3914
|
+
headers: {
|
|
3915
|
+
Authorization: `Bearer ${opts.token}`,
|
|
3916
|
+
"Content-Type": "application/json",
|
|
3917
|
+
Accept: "text/event-stream",
|
|
3918
|
+
...selfAgentId ? { "X-Caller-Agent-Id": selfAgentId } : {}
|
|
3919
|
+
},
|
|
3920
|
+
body: JSON.stringify({ task_description: opts.taskDescription }),
|
|
3921
|
+
signal: opts.signal
|
|
3922
|
+
});
|
|
3923
|
+
if (!res.ok) {
|
|
3924
|
+
let msg = `HTTP ${res.status}`;
|
|
3925
|
+
let errorCode = "";
|
|
3926
|
+
try {
|
|
3927
|
+
const body = await res.json();
|
|
3928
|
+
errorCode = body.error || "";
|
|
3929
|
+
msg = body.message || body.error || msg;
|
|
3930
|
+
} catch {
|
|
3931
|
+
}
|
|
3932
|
+
if (errorCode === "subscription_required") {
|
|
3933
|
+
log.error("This is a private agent.");
|
|
3934
|
+
console.error(` Subscribe first: agent-mesh subscribe <author-login>`);
|
|
3935
|
+
} else {
|
|
3936
|
+
log.error(msg);
|
|
3937
|
+
}
|
|
3938
|
+
process.exit(1);
|
|
3939
|
+
}
|
|
3940
|
+
const contentType = res.headers.get("Content-Type") || "";
|
|
3941
|
+
if (contentType.includes("application/json")) {
|
|
3942
|
+
const result = await res.json();
|
|
3943
|
+
if (opts.json) {
|
|
3944
|
+
console.log(JSON.stringify(result));
|
|
3945
|
+
} else {
|
|
3946
|
+
console.log("");
|
|
3947
|
+
log.success(`Call created for ${BOLD}${opts.name}${RESET}`);
|
|
3948
|
+
console.log(` ${GRAY}Call ID${RESET} ${result.call_id}`);
|
|
3949
|
+
console.log(` ${GRAY}Status${RESET} ${result.status}`);
|
|
3950
|
+
console.log(` ${GRAY}Created${RESET} ${result.created_at}`);
|
|
3951
|
+
console.log("");
|
|
3952
|
+
}
|
|
3953
|
+
return;
|
|
3954
|
+
}
|
|
3955
|
+
if (!res.body) {
|
|
3956
|
+
log.error("Empty response body");
|
|
3957
|
+
process.exit(1);
|
|
3958
|
+
}
|
|
3959
|
+
if (!opts.json) {
|
|
3960
|
+
log.info(`Calling ${BOLD}${opts.name}${RESET}...`);
|
|
3961
|
+
console.log("");
|
|
3962
|
+
}
|
|
3963
|
+
const reader = res.body.getReader();
|
|
3964
|
+
const decoder = new TextDecoder();
|
|
3965
|
+
let buffer = "";
|
|
3966
|
+
let outputBuffer = "";
|
|
3967
|
+
let inThinkingBlock = false;
|
|
3968
|
+
while (true) {
|
|
3969
|
+
const { done, value } = await reader.read();
|
|
3970
|
+
if (done) break;
|
|
3971
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
3972
|
+
const parsed = parseSseChunk(chunk, buffer);
|
|
3973
|
+
buffer = parsed.carry;
|
|
3974
|
+
for (const data of parsed.events) {
|
|
3975
|
+
if (data === "[DONE]") continue;
|
|
3976
|
+
try {
|
|
3977
|
+
const event = JSON.parse(data);
|
|
3978
|
+
if (opts.json) {
|
|
3979
|
+
console.log(JSON.stringify(event));
|
|
3980
|
+
} else {
|
|
3981
|
+
if (event.type === "chunk" && event.delta) {
|
|
3982
|
+
process.stdout.write(event.delta);
|
|
3983
|
+
if (!event.kind || event.kind === "text") {
|
|
3984
|
+
const delta = event.delta;
|
|
3985
|
+
if (delta.startsWith("{") && delta.includes('"type":')) {
|
|
3986
|
+
if (delta.includes('"type":"thinking"') && delta.includes("content_block_start")) {
|
|
3987
|
+
inThinkingBlock = true;
|
|
3988
|
+
} else if (delta.includes('"type":"text"') && delta.includes("content_block_start")) {
|
|
3989
|
+
inThinkingBlock = false;
|
|
3990
|
+
}
|
|
3991
|
+
} else if (!inThinkingBlock) {
|
|
3992
|
+
outputBuffer += delta;
|
|
3993
|
+
}
|
|
3994
|
+
}
|
|
3995
|
+
} else if (event.type === "done" && event.attachments?.length) {
|
|
3996
|
+
console.log("");
|
|
3997
|
+
for (const att of event.attachments) {
|
|
3998
|
+
log.info(` ${GRAY}File:${RESET} ${att.name} ${GRAY}${att.url}${RESET}`);
|
|
3999
|
+
}
|
|
4000
|
+
} else if (event.type === "error") {
|
|
4001
|
+
process.stderr.write(`
|
|
4002
|
+
Error: ${event.message}
|
|
4003
|
+
`);
|
|
4004
|
+
}
|
|
4005
|
+
}
|
|
4006
|
+
} catch {
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
}
|
|
4010
|
+
if (buffer.trim()) {
|
|
4011
|
+
const parsed = parseSseChunk("\n\n", buffer);
|
|
4012
|
+
for (const data of parsed.events) {
|
|
4013
|
+
if (data === "[DONE]") continue;
|
|
4014
|
+
try {
|
|
4015
|
+
const event = JSON.parse(data);
|
|
4016
|
+
if (opts.json) {
|
|
4017
|
+
console.log(JSON.stringify(event));
|
|
4018
|
+
} else if (event.type === "chunk" && event.delta) {
|
|
4019
|
+
process.stdout.write(event.delta);
|
|
4020
|
+
if (!event.kind || event.kind === "text") {
|
|
4021
|
+
const delta = event.delta;
|
|
4022
|
+
if (!(delta.startsWith("{") && delta.includes('"type":')) && !inThinkingBlock) {
|
|
4023
|
+
outputBuffer += delta;
|
|
4024
|
+
}
|
|
4025
|
+
}
|
|
4026
|
+
}
|
|
4027
|
+
} catch {
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
if (opts.outputFile && outputBuffer) {
|
|
4032
|
+
writeFileSync2(opts.outputFile, outputBuffer);
|
|
4033
|
+
if (!opts.json) log.info(`Saved to ${opts.outputFile}`);
|
|
4034
|
+
}
|
|
4035
|
+
if (!opts.json) {
|
|
4036
|
+
console.log("\n");
|
|
4037
|
+
log.success("Call completed");
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
3864
4040
|
function registerCallCommand(program2) {
|
|
3865
|
-
program2.command("call <agent>").description("Call an agent on the A2A network").requiredOption("--task <description>", "Task description").option("--input-file <path>", "Read file and append to task description").option("--output-file <path>", "Save response text to file").option("--json", "Output JSONL events").option("--timeout <seconds>", "Timeout in seconds", "300").action(async (agentInput, opts) => {
|
|
4041
|
+
program2.command("call <agent>").description("Call an agent on the A2A network (default: async polling)").requiredOption("--task <description>", "Task description").option("--input-file <path>", "Read file and append to task description").option("--output-file <path>", "Save response text to file").option("--stream", "Use SSE streaming instead of async polling").option("--json", "Output JSONL events").option("--timeout <seconds>", "Timeout in seconds", "300").action(async (agentInput, opts) => {
|
|
3866
4042
|
try {
|
|
3867
4043
|
const token = loadToken();
|
|
3868
4044
|
if (!token) {
|
|
@@ -3883,136 +4059,22 @@ ${content}`;
|
|
|
3883
4059
|
const timeoutMs = parseInt(opts.timeout || "300", 10) * 1e3;
|
|
3884
4060
|
const abortController = new AbortController();
|
|
3885
4061
|
const timer = setTimeout(() => abortController.abort(), timeoutMs);
|
|
3886
|
-
const
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
},
|
|
3895
|
-
body: JSON.stringify({ task_description: taskDescription }),
|
|
4062
|
+
const callOpts = {
|
|
4063
|
+
id,
|
|
4064
|
+
name,
|
|
4065
|
+
token,
|
|
4066
|
+
taskDescription,
|
|
4067
|
+
timeoutMs,
|
|
4068
|
+
json: opts.json,
|
|
4069
|
+
outputFile: opts.outputFile,
|
|
3896
4070
|
signal: abortController.signal
|
|
3897
|
-
}
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
try {
|
|
3903
|
-
const body = await res.json();
|
|
3904
|
-
errorCode = body.error || "";
|
|
3905
|
-
msg = body.message || body.error || msg;
|
|
3906
|
-
} catch {
|
|
3907
|
-
}
|
|
3908
|
-
if (errorCode === "subscription_required") {
|
|
3909
|
-
log.error("This is a private agent.");
|
|
3910
|
-
console.error(` Subscribe first: agent-mesh subscribe <author-login>`);
|
|
3911
|
-
console.error(` Then retry: agent-mesh call ${agentInput} --task "..."`);
|
|
3912
|
-
} else {
|
|
3913
|
-
log.error(msg);
|
|
3914
|
-
}
|
|
3915
|
-
process.exit(1);
|
|
3916
|
-
}
|
|
3917
|
-
const contentType = res.headers.get("Content-Type") || "";
|
|
3918
|
-
if (contentType.includes("application/json")) {
|
|
3919
|
-
const result = await res.json();
|
|
3920
|
-
if (opts.json) {
|
|
3921
|
-
console.log(JSON.stringify(result));
|
|
3922
|
-
} else {
|
|
3923
|
-
console.log("");
|
|
3924
|
-
log.success(`Call created for ${BOLD}${name}${RESET}`);
|
|
3925
|
-
console.log(` ${GRAY}Call ID${RESET} ${result.call_id}`);
|
|
3926
|
-
console.log(` ${GRAY}Status${RESET} ${result.status}`);
|
|
3927
|
-
console.log(` ${GRAY}Created${RESET} ${result.created_at}`);
|
|
3928
|
-
console.log("");
|
|
3929
|
-
}
|
|
3930
|
-
return;
|
|
3931
|
-
}
|
|
3932
|
-
if (!res.body) {
|
|
3933
|
-
log.error("Empty response body");
|
|
3934
|
-
process.exit(1);
|
|
3935
|
-
}
|
|
3936
|
-
if (!opts.json) {
|
|
3937
|
-
log.info(`Calling ${BOLD}${name}${RESET}...`);
|
|
3938
|
-
console.log("");
|
|
3939
|
-
}
|
|
3940
|
-
const reader = res.body.getReader();
|
|
3941
|
-
const decoder = new TextDecoder();
|
|
3942
|
-
let buffer = "";
|
|
3943
|
-
let outputBuffer = "";
|
|
3944
|
-
let inThinkingBlock = false;
|
|
3945
|
-
while (true) {
|
|
3946
|
-
const { done, value } = await reader.read();
|
|
3947
|
-
if (done) break;
|
|
3948
|
-
const chunk = decoder.decode(value, { stream: true });
|
|
3949
|
-
const parsed = parseSseChunk(chunk, buffer);
|
|
3950
|
-
buffer = parsed.carry;
|
|
3951
|
-
for (const data of parsed.events) {
|
|
3952
|
-
if (data === "[DONE]") continue;
|
|
3953
|
-
try {
|
|
3954
|
-
const event = JSON.parse(data);
|
|
3955
|
-
if (opts.json) {
|
|
3956
|
-
console.log(JSON.stringify(event));
|
|
3957
|
-
} else {
|
|
3958
|
-
if (event.type === "chunk" && event.delta) {
|
|
3959
|
-
process.stdout.write(event.delta);
|
|
3960
|
-
if (!event.kind || event.kind === "text") {
|
|
3961
|
-
const delta = event.delta;
|
|
3962
|
-
if (delta.startsWith("{") && delta.includes('"type":')) {
|
|
3963
|
-
if (delta.includes('"type":"thinking"') && delta.includes("content_block_start")) {
|
|
3964
|
-
inThinkingBlock = true;
|
|
3965
|
-
} else if (delta.includes('"type":"text"') && delta.includes("content_block_start")) {
|
|
3966
|
-
inThinkingBlock = false;
|
|
3967
|
-
}
|
|
3968
|
-
} else if (!inThinkingBlock) {
|
|
3969
|
-
outputBuffer += delta;
|
|
3970
|
-
}
|
|
3971
|
-
}
|
|
3972
|
-
} else if (event.type === "done" && event.attachments?.length) {
|
|
3973
|
-
console.log("");
|
|
3974
|
-
for (const att of event.attachments) {
|
|
3975
|
-
log.info(` ${GRAY}File:${RESET} ${att.name} ${GRAY}${att.url}${RESET}`);
|
|
3976
|
-
}
|
|
3977
|
-
} else if (event.type === "error") {
|
|
3978
|
-
process.stderr.write(`
|
|
3979
|
-
Error: ${event.message}
|
|
3980
|
-
`);
|
|
3981
|
-
}
|
|
3982
|
-
}
|
|
3983
|
-
} catch {
|
|
3984
|
-
}
|
|
3985
|
-
}
|
|
3986
|
-
}
|
|
3987
|
-
if (buffer.trim()) {
|
|
3988
|
-
const parsed = parseSseChunk("\n\n", buffer);
|
|
3989
|
-
for (const data of parsed.events) {
|
|
3990
|
-
if (data === "[DONE]") continue;
|
|
3991
|
-
try {
|
|
3992
|
-
const event = JSON.parse(data);
|
|
3993
|
-
if (opts.json) {
|
|
3994
|
-
console.log(JSON.stringify(event));
|
|
3995
|
-
} else if (event.type === "chunk" && event.delta) {
|
|
3996
|
-
process.stdout.write(event.delta);
|
|
3997
|
-
if (!event.kind || event.kind === "text") {
|
|
3998
|
-
const delta = event.delta;
|
|
3999
|
-
if (!(delta.startsWith("{") && delta.includes('"type":')) && !inThinkingBlock) {
|
|
4000
|
-
outputBuffer += delta;
|
|
4001
|
-
}
|
|
4002
|
-
}
|
|
4003
|
-
}
|
|
4004
|
-
} catch {
|
|
4005
|
-
}
|
|
4006
|
-
}
|
|
4007
|
-
}
|
|
4008
|
-
if (opts.outputFile && outputBuffer) {
|
|
4009
|
-
writeFileSync2(opts.outputFile, outputBuffer);
|
|
4010
|
-
if (!opts.json) log.info(`Saved to ${opts.outputFile}`);
|
|
4011
|
-
}
|
|
4012
|
-
if (!opts.json) {
|
|
4013
|
-
console.log("\n");
|
|
4014
|
-
log.success("Call completed");
|
|
4071
|
+
};
|
|
4072
|
+
if (opts.stream) {
|
|
4073
|
+
await streamCall(callOpts);
|
|
4074
|
+
} else {
|
|
4075
|
+
await asyncCall(callOpts);
|
|
4015
4076
|
}
|
|
4077
|
+
clearTimeout(timer);
|
|
4016
4078
|
} catch (err) {
|
|
4017
4079
|
if (err.name === "AbortError") {
|
|
4018
4080
|
log.error("Call timed out");
|
|
@@ -4250,6 +4312,68 @@ function registerSubscribeCommand(program2) {
|
|
|
4250
4312
|
});
|
|
4251
4313
|
}
|
|
4252
4314
|
|
|
4315
|
+
// src/commands/register.ts
|
|
4316
|
+
var DEFAULT_BASE_URL5 = "https://agents.hot";
|
|
4317
|
+
var VALID_AGENT_TYPES = ["openclaw", "claude-code", "cursor", "windsurf", "custom"];
|
|
4318
|
+
function registerRegisterCommand(program2) {
|
|
4319
|
+
program2.command("register").description("Register a new agent on the platform and get an API key").requiredOption("--name <name>", "Agent name (alphanumeric + hyphens, 3-64 chars)").option("--type <type>", "Agent type", "claude-code").option("--description <text>", "Agent description").option("--capabilities <list>", "Comma-separated capabilities").option("--base-url <url>", "Platform base URL", DEFAULT_BASE_URL5).action(async (opts) => {
|
|
4320
|
+
if (!VALID_AGENT_TYPES.includes(opts.type)) {
|
|
4321
|
+
log.error(`Invalid agent type: ${opts.type}. Must be one of: ${VALID_AGENT_TYPES.join(", ")}`);
|
|
4322
|
+
process.exit(1);
|
|
4323
|
+
}
|
|
4324
|
+
const capabilities = opts.capabilities ? opts.capabilities.split(",").map((c) => c.trim()).filter(Boolean) : [];
|
|
4325
|
+
log.info(`Registering agent ${BOLD}${opts.name}${RESET}...`);
|
|
4326
|
+
let res;
|
|
4327
|
+
try {
|
|
4328
|
+
res = await fetch(`${opts.baseUrl}/api/auth/agent/register`, {
|
|
4329
|
+
method: "POST",
|
|
4330
|
+
headers: { "Content-Type": "application/json" },
|
|
4331
|
+
body: JSON.stringify({
|
|
4332
|
+
agent_name: opts.name,
|
|
4333
|
+
agent_type: opts.type,
|
|
4334
|
+
description: opts.description,
|
|
4335
|
+
capabilities
|
|
4336
|
+
})
|
|
4337
|
+
});
|
|
4338
|
+
} catch (err) {
|
|
4339
|
+
log.error(`Network error: ${err.message}`);
|
|
4340
|
+
process.exit(1);
|
|
4341
|
+
}
|
|
4342
|
+
if (!res.ok) {
|
|
4343
|
+
let msg = `HTTP ${res.status}`;
|
|
4344
|
+
try {
|
|
4345
|
+
const body = await res.json();
|
|
4346
|
+
msg = body.message || body.error || msg;
|
|
4347
|
+
} catch {
|
|
4348
|
+
}
|
|
4349
|
+
log.error(msg);
|
|
4350
|
+
process.exit(1);
|
|
4351
|
+
}
|
|
4352
|
+
const data = await res.json();
|
|
4353
|
+
if (!hasToken()) {
|
|
4354
|
+
saveToken(data.api_key);
|
|
4355
|
+
log.info("Saved API key as platform token (auto-login)");
|
|
4356
|
+
}
|
|
4357
|
+
const slug = uniqueSlug(opts.name);
|
|
4358
|
+
const workspaceDir = getAgentWorkspaceDir(slug);
|
|
4359
|
+
addAgent(slug, {
|
|
4360
|
+
agentId: data.agent_id,
|
|
4361
|
+
agentType: opts.type,
|
|
4362
|
+
bridgeUrl: opts.baseUrl.replace("https://", "wss://").replace("http://", "ws://") + "/ws",
|
|
4363
|
+
projectPath: workspaceDir,
|
|
4364
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4365
|
+
});
|
|
4366
|
+
log.success(`Agent registered: ${BOLD}${data.agent_name}${RESET}`);
|
|
4367
|
+
console.log("");
|
|
4368
|
+
console.log(` Agent ID: ${data.agent_id}`);
|
|
4369
|
+
console.log(` API Key: ${data.api_key}`);
|
|
4370
|
+
console.log(` Type: ${data.agent_type}`);
|
|
4371
|
+
console.log(` Workspace: ${workspaceDir}`);
|
|
4372
|
+
console.log("");
|
|
4373
|
+
console.log(`${GRAY}Next: agent-mesh connect ${slug}${RESET}`);
|
|
4374
|
+
});
|
|
4375
|
+
}
|
|
4376
|
+
|
|
4253
4377
|
// src/index.ts
|
|
4254
4378
|
var require2 = createRequire(import.meta.url);
|
|
4255
4379
|
var { version } = require2("../package.json");
|
|
@@ -4277,4 +4401,5 @@ registerCallCommand(program);
|
|
|
4277
4401
|
registerConfigCommand(program);
|
|
4278
4402
|
registerStatsCommand(program);
|
|
4279
4403
|
registerSubscribeCommand(program);
|
|
4404
|
+
registerRegisterCommand(program);
|
|
4280
4405
|
program.parse();
|