@camelai/camelrun 0.11.2 → 0.13.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/dist/api.js +9 -4
- package/dist/cli.js +5 -4
- package/dist/config.js +2 -2
- package/dist/ops.js +2 -1
- package/dist/tools.js +5 -2
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* A refused call: the runtime's `error` message, with the HTTP status and its `code` when it gave one. The message
|
|
3
|
+
* suits every surface; `cliHint` is what to do about it with the CLI, which only the CLI shows (an MCP client's model
|
|
4
|
+
* would try to run it).
|
|
5
|
+
*/
|
|
2
6
|
export class ApiError extends Error {
|
|
3
7
|
status;
|
|
4
8
|
code;
|
|
5
|
-
|
|
9
|
+
cliHint;
|
|
10
|
+
constructor(status, message, code, cliHint) { super(message); this.status = status; this.code = code; this.cliHint = cliHint; }
|
|
6
11
|
}
|
|
7
12
|
/** SHA-256 as hex, with Web Crypto: the same in Node and browsers. */
|
|
8
13
|
async function sha256(text) {
|
|
@@ -39,7 +44,7 @@ export class Api {
|
|
|
39
44
|
}
|
|
40
45
|
if (!response.ok) {
|
|
41
46
|
const message = json?.error ?? json?.message ?? (text.slice(0, 300) || response.statusText);
|
|
42
|
-
throw new ApiError(response.status, response.status === 401 ?
|
|
47
|
+
throw new ApiError(response.status, message, json?.code, response.status === 401 ? "check your API key: camelrun login" : undefined);
|
|
43
48
|
}
|
|
44
49
|
return json;
|
|
45
50
|
}
|
|
@@ -66,7 +71,7 @@ export class Api {
|
|
|
66
71
|
const agents = await this.get("/v1/agents");
|
|
67
72
|
const found = agents.find(agent => agent.key === keyOrId);
|
|
68
73
|
if (!found)
|
|
69
|
-
throw new ApiError(404, `No agent with key ${JSON.stringify(keyOrId)}
|
|
74
|
+
throw new ApiError(404, `No agent with key ${JSON.stringify(keyOrId)} in this account`, undefined, "camelrun agents list shows them");
|
|
70
75
|
return found.id;
|
|
71
76
|
}
|
|
72
77
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
3
|
import { parseArgs } from "node:util";
|
|
4
|
-
import { Api, enc } from "./api.js";
|
|
4
|
+
import { Api, ApiError, enc } from "./api.js";
|
|
5
5
|
import { DEFAULT_URL, forget, resolve, save } from "./config.js";
|
|
6
6
|
import { DEFAULT_FILES, template } from "./manifest.js";
|
|
7
7
|
import { findManifest, loadManifests } from "./manifest-files.js";
|
|
@@ -51,7 +51,7 @@ MCP
|
|
|
51
51
|
|
|
52
52
|
Options
|
|
53
53
|
--json Print JSON (the default when stdout is not a terminal)
|
|
54
|
-
--api-key <key>, --url <url> Instead of CAMELAI_API_KEY /
|
|
54
|
+
--api-key <key>, --url <url> Instead of CAMELAI_API_KEY / CAMELAI_BASE_URL / the saved login
|
|
55
55
|
|
|
56
56
|
Docs: https://run.camelai.com/llms.txt`;
|
|
57
57
|
const OPTIONS = {
|
|
@@ -189,7 +189,8 @@ export async function main(argv, io = { out: text => process.stdout.write(text +
|
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
catch (error) {
|
|
192
|
-
|
|
192
|
+
const message = error.message + (error instanceof ApiError && error.cliHint ? ` (${error.cliHint})` : "");
|
|
193
|
+
io.err(json && !(error instanceof UsageError) ? JSON.stringify({ error: message, ...("status" in error ? { status: error.status, code: error.code } : {}) }) : `Error: ${message}`);
|
|
193
194
|
return 1;
|
|
194
195
|
}
|
|
195
196
|
}
|
|
@@ -202,7 +203,7 @@ async function login(flags, io, print) {
|
|
|
202
203
|
apiKey = (await prompt.question("API key (create one at https://run.camelai.com/console/tokens): ")).trim();
|
|
203
204
|
prompt.close();
|
|
204
205
|
}
|
|
205
|
-
const url = flags.url || io.env.CAMELAI_URL || DEFAULT_URL;
|
|
206
|
+
const url = flags.url || io.env.CAMELAI_BASE_URL || io.env.CAMELAI_URL || DEFAULT_URL;
|
|
206
207
|
const me = await new Api({ apiKey, url }).me();
|
|
207
208
|
const path = save({ apiKey, url }, io.env);
|
|
208
209
|
print({ tenant: me.tenant, url, saved: path }, () => `Logged in as ${me.login ?? me.tenant} on ${url} (key saved to ${path})`);
|
package/dist/config.js
CHANGED
|
@@ -32,11 +32,11 @@ export function forget(env = process.env) {
|
|
|
32
32
|
rmSync(path, { force: true });
|
|
33
33
|
return had ? path : undefined;
|
|
34
34
|
}
|
|
35
|
-
/** Flags first, then CAMELAI_API_KEY / CAMELAI_URL, then what `camelrun login` saved. */
|
|
35
|
+
/** Flags first, then CAMELAI_API_KEY / CAMELAI_BASE_URL (as the SDKs read it; CAMELAI_URL too), then what `camelrun login` saved. */
|
|
36
36
|
export function resolve(flags, env = process.env) {
|
|
37
37
|
const saved = readSaved(env);
|
|
38
38
|
const apiKey = flags.apiKey || env.CAMELAI_API_KEY || saved.apiKey;
|
|
39
39
|
if (!apiKey)
|
|
40
40
|
throw new Error("No API key: run `camelrun login`, or set CAMELAI_API_KEY. Create one at https://run.camelai.com/console/tokens. Coding agents: read https://run.camelai.com/SKILL.md");
|
|
41
|
-
return { apiKey, url: flags.url || env.CAMELAI_URL || saved.url || DEFAULT_URL };
|
|
41
|
+
return { apiKey, url: flags.url || env.CAMELAI_BASE_URL || env.CAMELAI_URL || saved.url || DEFAULT_URL };
|
|
42
42
|
}
|
package/dist/ops.js
CHANGED
|
@@ -51,7 +51,8 @@ export function summarize(agent, record) {
|
|
|
51
51
|
const result = outcome.result ?? {};
|
|
52
52
|
const failure = outcome.error ? { code: outcome.uncertain ? "uncertain" : "runtime_error", message: outcome.error }
|
|
53
53
|
: result.error ? { code: result.code ?? "model_error", message: result.error }
|
|
54
|
-
: result.stopped === "spend_limit" ? { code: "spend_limit", message: "The agent reached its spend limit; raise it to go on" }
|
|
54
|
+
: result.stopped === "spend_limit" ? { code: "spend_limit", message: "The agent reached its spend limit; raise it to go on" }
|
|
55
|
+
: result.stopped === "turn_limit" ? { code: "turn_limit", message: "The run reached its limit of model responses or time; send another message to continue" } : undefined;
|
|
55
56
|
const status = failure ? "failed" : result.stopped === "input_required" ? "input_required" : "completed";
|
|
56
57
|
return {
|
|
57
58
|
...base, status,
|
package/dist/tools.js
CHANGED
|
@@ -68,7 +68,10 @@ export function tools(api, options = {}) {
|
|
|
68
68
|
const client = api();
|
|
69
69
|
return client.call("DELETE", `/v1/definitions/${await client.definitionId(definition)}`);
|
|
70
70
|
}, destructive);
|
|
71
|
-
tool("list_agents", "List agents", "The account's agents: key, id, model, and whether
|
|
71
|
+
tool("list_agents", "List agents", "The account's agents: key, id, name and model. `loaded` is whether the agent is in a runtime's memory now, idle or not; it says nothing about whether a run is going (run_agent and get_run do). `toolsConnected` is whether an application serving its attached tools is connected. Changes nothing.", {}, async () => {
|
|
72
|
+
const list = await api().get("/v1/agents");
|
|
73
|
+
return list.map(({ id, key, name, model, running, connected, expiresAt }) => ({ key, id, name, model, loaded: running, toolsConnected: connected, expiresAt }));
|
|
74
|
+
}, read);
|
|
72
75
|
tool("get_agent", "Get agent", "An agent's configuration, the definition revision it has, and every source of its tools with what each offers. Changes nothing.", { agent }, async ({ agent }) => {
|
|
73
76
|
const client = api();
|
|
74
77
|
return client.get(`/v1/agents/${enc(await client.agentId(agent))}`);
|
|
@@ -129,7 +132,7 @@ export function tools(api, options = {}) {
|
|
|
129
132
|
}, async ({ agent, ...schedule }) => {
|
|
130
133
|
const client = api();
|
|
131
134
|
return client.call("POST", `/v1/agents/${enc(await client.agentId(agent))}/schedules`, schedule);
|
|
132
|
-
}, add);
|
|
135
|
+
}, { ...add, openWorldHint: true });
|
|
133
136
|
tool("delete_schedule", "Delete schedule", "Cancel a scheduled wake-up; this cannot be undone.", { agent, scheduleId: z.string() }, async ({ agent, scheduleId }) => {
|
|
134
137
|
const client = api();
|
|
135
138
|
return client.call("DELETE", `/v1/agents/${enc(await client.agentId(agent))}/schedules/${enc(scheduleId)}`);
|
package/package.json
CHANGED