@dharta/cli 0.6.77
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/LICENSE +21 -0
- package/README.md +167 -0
- package/dist/agent.d.ts +17 -0
- package/dist/agent.js +134 -0
- package/dist/agent.js.map +1 -0
- package/dist/api-error.d.ts +3 -0
- package/dist/api-error.js +80 -0
- package/dist/api-error.js.map +1 -0
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +19 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.js +1978 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agents.d.ts +131 -0
- package/dist/commands/agents.js +439 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/analytics.d.ts +25 -0
- package/dist/commands/analytics.js +166 -0
- package/dist/commands/analytics.js.map +1 -0
- package/dist/commands/api.d.ts +19 -0
- package/dist/commands/api.js +278 -0
- package/dist/commands/api.js.map +1 -0
- package/dist/commands/appearance.d.ts +19 -0
- package/dist/commands/appearance.js +63 -0
- package/dist/commands/appearance.js.map +1 -0
- package/dist/commands/artifact.d.ts +33 -0
- package/dist/commands/artifact.js +235 -0
- package/dist/commands/artifact.js.map +1 -0
- package/dist/commands/audit-log.d.ts +32 -0
- package/dist/commands/audit-log.js +102 -0
- package/dist/commands/audit-log.js.map +1 -0
- package/dist/commands/auth.d.ts +47 -0
- package/dist/commands/auth.js +117 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/caps.d.ts +82 -0
- package/dist/commands/caps.js +213 -0
- package/dist/commands/caps.js.map +1 -0
- package/dist/commands/create.d.ts +22 -0
- package/dist/commands/create.js +76 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/deploy.d.ts +45 -0
- package/dist/commands/deploy.js +892 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +33 -0
- package/dist/commands/dev.js +655 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/directories.d.ts +60 -0
- package/dist/commands/directories.js +83 -0
- package/dist/commands/directories.js.map +1 -0
- package/dist/commands/doctor.d.ts +13 -0
- package/dist/commands/doctor.js +123 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/embed-keys.d.ts +61 -0
- package/dist/commands/embed-keys.js +165 -0
- package/dist/commands/embed-keys.js.map +1 -0
- package/dist/commands/env.d.ts +59 -0
- package/dist/commands/env.js +300 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/files.d.ts +14 -0
- package/dist/commands/files.js +84 -0
- package/dist/commands/files.js.map +1 -0
- package/dist/commands/git-credential.d.ts +1 -0
- package/dist/commands/git-credential.js +70 -0
- package/dist/commands/git-credential.js.map +1 -0
- package/dist/commands/kartas.d.ts +101 -0
- package/dist/commands/kartas.js +289 -0
- package/dist/commands/kartas.js.map +1 -0
- package/dist/commands/keys.d.ts +33 -0
- package/dist/commands/keys.js +141 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/login.d.ts +22 -0
- package/dist/commands/login.js +78 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logs.d.ts +14 -0
- package/dist/commands/logs.js +89 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/members.d.ts +32 -0
- package/dist/commands/members.js +77 -0
- package/dist/commands/members.js.map +1 -0
- package/dist/commands/model-keys.d.ts +22 -0
- package/dist/commands/model-keys.js +222 -0
- package/dist/commands/model-keys.js.map +1 -0
- package/dist/commands/open.d.ts +29 -0
- package/dist/commands/open.js +119 -0
- package/dist/commands/open.js.map +1 -0
- package/dist/commands/parity.d.ts +15 -0
- package/dist/commands/parity.js +73 -0
- package/dist/commands/parity.js.map +1 -0
- package/dist/commands/rollback.d.ts +21 -0
- package/dist/commands/rollback.js +26 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/schedules.d.ts +52 -0
- package/dist/commands/schedules.js +231 -0
- package/dist/commands/schedules.js.map +1 -0
- package/dist/commands/scopes.d.ts +3 -0
- package/dist/commands/scopes.js +21 -0
- package/dist/commands/scopes.js.map +1 -0
- package/dist/commands/sessions.d.ts +53 -0
- package/dist/commands/sessions.js +142 -0
- package/dist/commands/sessions.js.map +1 -0
- package/dist/commands/setup.d.ts +28 -0
- package/dist/commands/setup.js +949 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +19 -0
- package/dist/commands/status.js +63 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +14 -0
- package/dist/commands/update.js +120 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/usage.d.ts +3 -0
- package/dist/commands/usage.js +37 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/commands/webhooks.d.ts +47 -0
- package/dist/commands/webhooks.js +156 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/commands/whoami.d.ts +7 -0
- package/dist/commands/whoami.js +17 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/completions.d.ts +13 -0
- package/dist/completions.js +120 -0
- package/dist/completions.js.map +1 -0
- package/dist/config.d.ts +20 -0
- package/dist/config.js +98 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +14 -0
- package/dist/context.js +38 -0
- package/dist/context.js.map +1 -0
- package/dist/device-flow.d.ts +9 -0
- package/dist/device-flow.js +127 -0
- package/dist/device-flow.js.map +1 -0
- package/dist/harness-preflight.d.ts +24 -0
- package/dist/harness-preflight.js +252 -0
- package/dist/harness-preflight.js.map +1 -0
- package/dist/harnesses.d.ts +11 -0
- package/dist/harnesses.js +112 -0
- package/dist/harnesses.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/login-offer.d.ts +9 -0
- package/dist/login-offer.js +36 -0
- package/dist/login-offer.js.map +1 -0
- package/dist/manifest.d.ts +15 -0
- package/dist/manifest.js +142 -0
- package/dist/manifest.js.map +1 -0
- package/dist/money.d.ts +1 -0
- package/dist/money.js +16 -0
- package/dist/money.js.map +1 -0
- package/dist/output.d.ts +2 -0
- package/dist/output.js +20 -0
- package/dist/output.js.map +1 -0
- package/dist/runtime.d.ts +19 -0
- package/dist/runtime.js +95 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scaffold.d.ts +16 -0
- package/dist/scaffold.js +74 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/setup-scan.d.ts +21 -0
- package/dist/setup-scan.js +127 -0
- package/dist/setup-scan.js.map +1 -0
- package/dist/templates.d.ts +14 -0
- package/dist/templates.js +65 -0
- package/dist/templates.js.map +1 -0
- package/dist/validators.d.ts +10 -0
- package/dist/validators.js +116 -0
- package/dist/validators.js.map +1 -0
- package/dist/version-check.d.ts +25 -0
- package/dist/version-check.js +68 -0
- package/dist/version-check.js.map +1 -0
- package/node_modules/@dharta/sdk/LICENSE +21 -0
- package/node_modules/@dharta/sdk/README.md +87 -0
- package/node_modules/@dharta/sdk/dist/errors.d.ts +20 -0
- package/node_modules/@dharta/sdk/dist/errors.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/errors.js +51 -0
- package/node_modules/@dharta/sdk/dist/errors.js.map +1 -0
- package/node_modules/@dharta/sdk/dist/http.d.ts +26 -0
- package/node_modules/@dharta/sdk/dist/http.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/http.js +136 -0
- package/node_modules/@dharta/sdk/dist/http.js.map +1 -0
- package/node_modules/@dharta/sdk/dist/index.d.ts +15 -0
- package/node_modules/@dharta/sdk/dist/index.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/index.js +21 -0
- package/node_modules/@dharta/sdk/dist/index.js.map +1 -0
- package/node_modules/@dharta/sdk/dist/resources.d.ts +48 -0
- package/node_modules/@dharta/sdk/dist/resources.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/resources.js +150 -0
- package/node_modules/@dharta/sdk/dist/resources.js.map +1 -0
- package/node_modules/@dharta/sdk/dist/types.d.ts +94 -0
- package/node_modules/@dharta/sdk/dist/types.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/types.js +59 -0
- package/node_modules/@dharta/sdk/dist/types.js.map +1 -0
- package/node_modules/@dharta/sdk/package.json +32 -0
- package/node_modules/@dharta/sdk/src/errors.ts +58 -0
- package/node_modules/@dharta/sdk/src/http.ts +166 -0
- package/node_modules/@dharta/sdk/src/index.ts +36 -0
- package/node_modules/@dharta/sdk/src/resources.ts +197 -0
- package/node_modules/@dharta/sdk/src/types.ts +179 -0
- package/package.json +38 -0
- package/src/agent.ts +147 -0
- package/src/api-error.ts +88 -0
- package/src/browser.ts +20 -0
- package/src/cli.ts +2339 -0
- package/src/commands/agents.ts +635 -0
- package/src/commands/analytics.ts +181 -0
- package/src/commands/api.ts +297 -0
- package/src/commands/appearance.ts +79 -0
- package/src/commands/artifact.ts +331 -0
- package/src/commands/audit-log.ts +125 -0
- package/src/commands/auth.ts +186 -0
- package/src/commands/caps.ts +302 -0
- package/src/commands/create.ts +114 -0
- package/src/commands/deploy.ts +1122 -0
- package/src/commands/dev.ts +792 -0
- package/src/commands/directories.ts +136 -0
- package/src/commands/doctor.ts +138 -0
- package/src/commands/embed-keys.ts +237 -0
- package/src/commands/env.ts +369 -0
- package/src/commands/files.ts +124 -0
- package/src/commands/git-credential.ts +78 -0
- package/src/commands/kartas.ts +439 -0
- package/src/commands/keys.ts +206 -0
- package/src/commands/login.ts +115 -0
- package/src/commands/logs.ts +111 -0
- package/src/commands/members.ts +109 -0
- package/src/commands/model-keys.ts +278 -0
- package/src/commands/open.ts +173 -0
- package/src/commands/parity.ts +96 -0
- package/src/commands/rollback.ts +45 -0
- package/src/commands/schedules.ts +290 -0
- package/src/commands/scopes.ts +22 -0
- package/src/commands/sessions.ts +225 -0
- package/src/commands/setup.ts +1176 -0
- package/src/commands/status.ts +94 -0
- package/src/commands/update.ts +157 -0
- package/src/commands/usage.ts +41 -0
- package/src/commands/webhooks.ts +200 -0
- package/src/commands/whoami.ts +24 -0
- package/src/completions.ts +168 -0
- package/src/config.ts +143 -0
- package/src/context.ts +59 -0
- package/src/device-flow.ts +174 -0
- package/src/harness-preflight.ts +293 -0
- package/src/harnesses.ts +117 -0
- package/src/index.ts +3 -0
- package/src/login-offer.ts +49 -0
- package/src/manifest.ts +153 -0
- package/src/money.ts +15 -0
- package/src/output.ts +22 -0
- package/src/runtime.ts +127 -0
- package/src/scaffold.ts +102 -0
- package/src/setup-scan.ts +154 -0
- package/src/templates.ts +85 -0
- package/src/validators.ts +124 -0
- package/src/version-check.ts +75 -0
- package/templates/blank/CLAUDE.md +21 -0
- package/templates/blank/dharta.toml +11 -0
- package/templates/faq-agent/CLAUDE.md +51 -0
- package/templates/faq-agent/dharta.toml +11 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { fmtTs, table } from "../output.js";
|
|
2
|
+
import { validateAgentSlug } from "../agent.js";
|
|
3
|
+
import { closestChoice, parseReleaseVersion } from "../validators.js";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
const AGENT_MODEL_SOURCES = ["inherit", "platform"];
|
|
6
|
+
const MAX_OUTPUT_TOKENS = 1_000_000;
|
|
7
|
+
export async function agentsListData(ctx) {
|
|
8
|
+
try {
|
|
9
|
+
const res = await ctx.http.request({
|
|
10
|
+
path: "/api/agents",
|
|
11
|
+
});
|
|
12
|
+
return res.data;
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
throw addAgentsListNotFoundGuidance(error);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function agentsList(ctx) {
|
|
19
|
+
const data = await agentsListData(ctx);
|
|
20
|
+
if (data.length === 0)
|
|
21
|
+
return "No agents yet. Create one with: dharta create";
|
|
22
|
+
return table(data.map((p) => ({
|
|
23
|
+
slug: p.slug,
|
|
24
|
+
name: p.name,
|
|
25
|
+
branch: p.deploy_branch,
|
|
26
|
+
current: p.current_version == null ? "—" : `v${p.current_version}`,
|
|
27
|
+
status: p.current_status ?? "—",
|
|
28
|
+
})));
|
|
29
|
+
}
|
|
30
|
+
export async function agentsShowData(ctx, slug) {
|
|
31
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
32
|
+
const shown = await ctx.http.request({
|
|
33
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}`,
|
|
34
|
+
});
|
|
35
|
+
const releasesResult = await agentsReleasesData(ctx, normalizedSlug)
|
|
36
|
+
.then((releases) => ({ releases, error: undefined }))
|
|
37
|
+
.catch((error) => {
|
|
38
|
+
if (isReleaseScopeError(error)) {
|
|
39
|
+
return { releases: [], error: error instanceof Error ? error.message : String(error) };
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
});
|
|
43
|
+
const releases = releasesResult.releases;
|
|
44
|
+
const current = releases.find((release) => release.current) ?? null;
|
|
45
|
+
return {
|
|
46
|
+
...shown.agent,
|
|
47
|
+
clone_url: shown.clone_url,
|
|
48
|
+
agent_url: shown.agent_url,
|
|
49
|
+
console_url: shown.console_url,
|
|
50
|
+
live_version: shown.live_version ?? null,
|
|
51
|
+
current_version: shown.live_version ?? current?.version ?? null,
|
|
52
|
+
current_status: current?.status ?? null,
|
|
53
|
+
releases,
|
|
54
|
+
releases_error: releasesResult.error,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export async function agentsShow(ctx, slug) {
|
|
58
|
+
const p = await agentsShowData(ctx, slug);
|
|
59
|
+
const current = p.current_version == null
|
|
60
|
+
? "—"
|
|
61
|
+
: p.current_status
|
|
62
|
+
? `v${p.current_version} (${p.current_status})`
|
|
63
|
+
: `v${p.current_version}`;
|
|
64
|
+
const head = [
|
|
65
|
+
`Agent: ${p.name} (${p.slug})`,
|
|
66
|
+
`Deploy branch: ${p.deploy_branch}`,
|
|
67
|
+
`Current release: ${current}`,
|
|
68
|
+
...(p.resolved_model ? [formatResolvedModel(p.resolved_model)] : []),
|
|
69
|
+
].join("\n");
|
|
70
|
+
const releases = p.releases_error
|
|
71
|
+
? `Unavailable: ${p.releases_error}`
|
|
72
|
+
: p.releases.length
|
|
73
|
+
? table(p.releases.map((r) => ({
|
|
74
|
+
version: `v${r.version}`,
|
|
75
|
+
status: r.status,
|
|
76
|
+
error: releaseError(r),
|
|
77
|
+
commit: r.commit_sha.slice(0, 8),
|
|
78
|
+
created: fmtTs(r.created_at),
|
|
79
|
+
})))
|
|
80
|
+
: `No releases yet. Deploy it with: dharta deploy ${p.slug}`;
|
|
81
|
+
return `${head}\n\nRecent releases:\n${releases}`;
|
|
82
|
+
}
|
|
83
|
+
function formatResolvedModel(route) {
|
|
84
|
+
const model = route.model_id ?? "provider default";
|
|
85
|
+
const connector = route.model_key_id == null ? "platform" : `connector ${route.model_key_id}`;
|
|
86
|
+
const parameters = Object.entries(route.parameters)
|
|
87
|
+
.map(([name, value]) => `${name}=${JSON.stringify(value)}`)
|
|
88
|
+
.join(", ");
|
|
89
|
+
return [
|
|
90
|
+
`Resolved model: ${route.provider}/${model} (${route.api_format}, ${connector})`,
|
|
91
|
+
route.endpoint_url ? `Model endpoint: ${route.endpoint_url}` : null,
|
|
92
|
+
parameters ? `Model parameters: ${parameters}` : null,
|
|
93
|
+
].filter((line) => line !== null).join("\n");
|
|
94
|
+
}
|
|
95
|
+
function isReleaseScopeError(error) {
|
|
96
|
+
if (!(error instanceof Error))
|
|
97
|
+
return false;
|
|
98
|
+
const status = error.status;
|
|
99
|
+
return status === 403 && /releases:read|releases:write|required scopes/i.test(error.message);
|
|
100
|
+
}
|
|
101
|
+
function addAgentsListNotFoundGuidance(error) {
|
|
102
|
+
if (error instanceof Error) {
|
|
103
|
+
const status = error.status;
|
|
104
|
+
if (status === 404 && !error.message.includes("Could not list agents")) {
|
|
105
|
+
const guided = new Error("Could not list agents: the active Dharta host returned 404 for /api/agents. " +
|
|
106
|
+
"Run `dharta auth status` to confirm DHARTA_BASE_URL points at the Dharta control API; " +
|
|
107
|
+
"if it does, the server needs the public API route deployed for this CLI version.");
|
|
108
|
+
guided.status = status;
|
|
109
|
+
guided.body = error.body;
|
|
110
|
+
return guided;
|
|
111
|
+
}
|
|
112
|
+
return error;
|
|
113
|
+
}
|
|
114
|
+
return new Error(String(error));
|
|
115
|
+
}
|
|
116
|
+
export async function agentsReleasesData(ctx, slug) {
|
|
117
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
118
|
+
const res = await ctx.http.request({
|
|
119
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/releases`,
|
|
120
|
+
});
|
|
121
|
+
return res.data;
|
|
122
|
+
}
|
|
123
|
+
export async function agentsReleases(ctx, slug) {
|
|
124
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
125
|
+
const data = await agentsReleasesData(ctx, normalizedSlug);
|
|
126
|
+
if (data.length === 0)
|
|
127
|
+
return `No releases for ${normalizedSlug}. Deploy it with: dharta deploy ${normalizedSlug}`;
|
|
128
|
+
return table(data.map((r) => ({
|
|
129
|
+
version: `v${r.version}`,
|
|
130
|
+
status: r.status,
|
|
131
|
+
error: releaseError(r),
|
|
132
|
+
commit: r.commit_sha.slice(0, 8),
|
|
133
|
+
created: fmtTs(r.created_at),
|
|
134
|
+
})));
|
|
135
|
+
}
|
|
136
|
+
function releaseError(release) {
|
|
137
|
+
if (release.status !== "failed" || !release.error_message)
|
|
138
|
+
return "";
|
|
139
|
+
const oneLine = release.error_message.replace(/\s+/g, " ").trim();
|
|
140
|
+
return oneLine.length > 96 ? `${oneLine.slice(0, 93)}...` : oneLine;
|
|
141
|
+
}
|
|
142
|
+
export async function agentsActivateReleaseData(ctx, slug, version) {
|
|
143
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
144
|
+
const releaseVersion = parseReleaseVersion(version, "release version");
|
|
145
|
+
return ctx.http.request({
|
|
146
|
+
method: "POST",
|
|
147
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/releases/${encodeURIComponent(releaseVersion)}/activate`,
|
|
148
|
+
headers: { "Idempotency-Key": randomUUID() },
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
export async function agentsActivateRelease(ctx, slug, version) {
|
|
152
|
+
const res = await agentsActivateReleaseData(ctx, slug, version);
|
|
153
|
+
const previous = res.previous_release ? ` Previous: v${res.previous_release.version}.` : "";
|
|
154
|
+
return `Activated ${res.agent.slug} v${res.release.version}.${previous}`;
|
|
155
|
+
}
|
|
156
|
+
export async function agentsServingSetData(ctx, slug, enabled) {
|
|
157
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
158
|
+
return ctx.http.request({
|
|
159
|
+
method: "PATCH",
|
|
160
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/serving`,
|
|
161
|
+
headers: { "Idempotency-Key": randomUUID() },
|
|
162
|
+
body: { enabled },
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
export async function agentsServingSet(ctx, slug, enabled) {
|
|
166
|
+
const res = await agentsServingSetData(ctx, slug, enabled);
|
|
167
|
+
const verb = enabled ? "serving" : "paused";
|
|
168
|
+
return `${res.agent.slug} is ${verb}${res.changed ? "" : " (unchanged)"}.`;
|
|
169
|
+
}
|
|
170
|
+
export async function agentsDashboardEditsSetData(ctx, slug, enabled) {
|
|
171
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
172
|
+
return ctx.http.request({
|
|
173
|
+
method: "PATCH",
|
|
174
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/dashboard_edits`,
|
|
175
|
+
headers: { "Idempotency-Key": randomUUID() },
|
|
176
|
+
body: { enabled },
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
export async function agentsDashboardEditsSet(ctx, slug, enabled) {
|
|
180
|
+
const res = await agentsDashboardEditsSetData(ctx, slug, enabled);
|
|
181
|
+
const state = enabled ? "enabled" : "disabled";
|
|
182
|
+
return `Dashboard edits ${state} for ${res.agent.slug}${res.changed ? "" : " (unchanged)"}.`;
|
|
183
|
+
}
|
|
184
|
+
export async function agentsModelSetData(ctx, slug, opts) {
|
|
185
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
186
|
+
const normalized = validateAgentModelSetOptions(opts);
|
|
187
|
+
const body = {};
|
|
188
|
+
if (normalized.source !== undefined || normalized.connectorId !== undefined) {
|
|
189
|
+
body.model_connector = modelConnector(normalized);
|
|
190
|
+
}
|
|
191
|
+
if (normalized.model !== undefined)
|
|
192
|
+
body.default_model_id = normalized.model;
|
|
193
|
+
const modelParameters = modelParameterPatch(normalized);
|
|
194
|
+
if (Object.keys(modelParameters).length > 0)
|
|
195
|
+
body.model_parameters = modelParameters;
|
|
196
|
+
return ctx.http.request({
|
|
197
|
+
method: "PATCH",
|
|
198
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/model`,
|
|
199
|
+
headers: { "Idempotency-Key": randomUUID() },
|
|
200
|
+
body,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
export async function agentsModelSet(ctx, slug, opts) {
|
|
204
|
+
const res = await agentsModelSetData(ctx, slug, opts);
|
|
205
|
+
const model = res.agent.model.model ? ` model ${res.agent.model.model}` : "";
|
|
206
|
+
return `Model override for ${res.agent.slug}: ${res.agent.model.source}${model}.`;
|
|
207
|
+
}
|
|
208
|
+
export function validateAgentModelSetOptions(opts) {
|
|
209
|
+
const normalized = normalizeModelSetOptions(opts);
|
|
210
|
+
validateModelSetOptions(normalized);
|
|
211
|
+
return normalized;
|
|
212
|
+
}
|
|
213
|
+
export async function agentsWorkspaceInspectableSetData(ctx, slug, enabled) {
|
|
214
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
215
|
+
return ctx.http.request({
|
|
216
|
+
method: "PATCH",
|
|
217
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/workspace_inspectable`,
|
|
218
|
+
headers: { "Idempotency-Key": randomUUID() },
|
|
219
|
+
body: { enabled },
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
export async function agentsWorkspaceInspectableSet(ctx, slug, enabled) {
|
|
223
|
+
const res = await agentsWorkspaceInspectableSetData(ctx, slug, enabled);
|
|
224
|
+
const state = enabled ? "enabled" : "disabled";
|
|
225
|
+
return `Workspace inspection ${state} for ${res.agent.slug}${res.changed ? "" : " (unchanged)"}.`;
|
|
226
|
+
}
|
|
227
|
+
// RFC 0060 D1 — the audience x channel grant matrix. The four dotted grants map
|
|
228
|
+
// onto the nested `workspace_access` shape the API PATCHes.
|
|
229
|
+
export const WORKSPACE_ACCESS_PATHS = [
|
|
230
|
+
"owners.git",
|
|
231
|
+
"owners.api",
|
|
232
|
+
"users.widget",
|
|
233
|
+
"users.agent_definition",
|
|
234
|
+
];
|
|
235
|
+
// Parse `path=on|off` assignments (e.g. "users.widget=on") into the nested patch
|
|
236
|
+
// the API merges. Unknown paths and non-on/off values fail loud with a suggestion.
|
|
237
|
+
export function parseWorkspaceAccessAssignments(assignments) {
|
|
238
|
+
if (assignments.length === 0) {
|
|
239
|
+
throw new Error("Provide at least one grant, e.g. users.widget=on");
|
|
240
|
+
}
|
|
241
|
+
const patch = {};
|
|
242
|
+
for (const raw of assignments) {
|
|
243
|
+
const eq = raw.indexOf("=");
|
|
244
|
+
if (eq === -1) {
|
|
245
|
+
throw new Error(`Invalid grant "${raw}". Use <path>=<on|off>, e.g. users.widget=on.`);
|
|
246
|
+
}
|
|
247
|
+
const path = raw.slice(0, eq).trim();
|
|
248
|
+
const value = raw.slice(eq + 1);
|
|
249
|
+
if (!WORKSPACE_ACCESS_PATHS.includes(path)) {
|
|
250
|
+
const suggestion = closestChoice(path, WORKSPACE_ACCESS_PATHS);
|
|
251
|
+
throw new Error(`Unknown grant "${path}". One of: ${WORKSPACE_ACCESS_PATHS.join(", ")}.` +
|
|
252
|
+
(suggestion ? ` Did you mean ${suggestion}?` : ""));
|
|
253
|
+
}
|
|
254
|
+
const [audience, channel] = path.split(".");
|
|
255
|
+
(patch[audience] ??= {})[channel] = parseGrantValue(value, path);
|
|
256
|
+
}
|
|
257
|
+
return patch;
|
|
258
|
+
}
|
|
259
|
+
function parseGrantValue(value, path) {
|
|
260
|
+
const normalized = value.trim().toLowerCase();
|
|
261
|
+
if (["on", "true", "enabled", "enable", "1"].includes(normalized))
|
|
262
|
+
return true;
|
|
263
|
+
if (["off", "false", "disabled", "disable", "0"].includes(normalized))
|
|
264
|
+
return false;
|
|
265
|
+
throw new Error(`Grant "${path}" must be on/off, enabled/disabled, or true/false (got "${value}").`);
|
|
266
|
+
}
|
|
267
|
+
export async function agentsWorkspaceAccessShowData(ctx, slug) {
|
|
268
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
269
|
+
const res = await ctx.http.request({
|
|
270
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}`,
|
|
271
|
+
});
|
|
272
|
+
const matrix = res.agent.workspace_access;
|
|
273
|
+
if (!matrix) {
|
|
274
|
+
throw new Error("This Dharta server does not report workspace access. Upgrade the server (RFC 0060).");
|
|
275
|
+
}
|
|
276
|
+
return matrix;
|
|
277
|
+
}
|
|
278
|
+
export async function agentsWorkspaceAccessShow(ctx, slug) {
|
|
279
|
+
const wa = await agentsWorkspaceAccessShowData(ctx, slug);
|
|
280
|
+
const onoff = (granted) => (granted ? "on" : "off");
|
|
281
|
+
return [
|
|
282
|
+
"Workspace access grants:",
|
|
283
|
+
` owners.git: ${onoff(wa.owners.git)}`,
|
|
284
|
+
` owners.api: ${onoff(wa.owners.api)}`,
|
|
285
|
+
` users.widget: ${onoff(wa.users.widget)}`,
|
|
286
|
+
` users.agent_definition: ${onoff(wa.users.agent_definition)}`,
|
|
287
|
+
].join("\n");
|
|
288
|
+
}
|
|
289
|
+
export async function agentsWorkspaceAccessSetData(ctx, slug, patch) {
|
|
290
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
291
|
+
return ctx.http.request({
|
|
292
|
+
method: "PATCH",
|
|
293
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/workspace_access`,
|
|
294
|
+
headers: { "Idempotency-Key": randomUUID() },
|
|
295
|
+
body: { workspace_access: patch },
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
export async function agentsWorkspaceAccessSet(ctx, slug, patch) {
|
|
299
|
+
const res = await agentsWorkspaceAccessSetData(ctx, slug, patch);
|
|
300
|
+
const paths = Object.entries(patch).flatMap(([audience, channels]) => Object.entries(channels).map(([channel, granted]) => `${audience}.${channel}=${granted ? "on" : "off"}`));
|
|
301
|
+
return `Workspace access updated for ${res.agent.slug}: ${paths.join(", ")}${res.changed ? "" : " (unchanged)"}.`;
|
|
302
|
+
}
|
|
303
|
+
export async function agentsDeleteData(ctx, slug) {
|
|
304
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
305
|
+
return ctx.http.request({
|
|
306
|
+
method: "DELETE",
|
|
307
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}`,
|
|
308
|
+
headers: { "Idempotency-Key": randomUUID() },
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
export async function agentsDelete(ctx, slug) {
|
|
312
|
+
const res = await agentsDeleteData(ctx, slug);
|
|
313
|
+
return `Archived ${res.agent.slug}.`;
|
|
314
|
+
}
|
|
315
|
+
function modelConnector(opts) {
|
|
316
|
+
if (opts.connectorId)
|
|
317
|
+
return `key:${opts.connectorId}`;
|
|
318
|
+
if (opts.source === "platform")
|
|
319
|
+
return "platform";
|
|
320
|
+
if (opts.source === "inherit" || !opts.source)
|
|
321
|
+
return "inherit";
|
|
322
|
+
throw new Error("--source must be inherit or platform.");
|
|
323
|
+
}
|
|
324
|
+
function validateModelSetOptions(opts) {
|
|
325
|
+
const hasSource = opts.source !== undefined;
|
|
326
|
+
const hasConnector = opts.connectorId !== undefined;
|
|
327
|
+
const hasModel = opts.model !== undefined;
|
|
328
|
+
const hasParameters = modelParameterOptionPresent(opts);
|
|
329
|
+
if (!hasSource && !hasConnector && !hasModel && !hasParameters) {
|
|
330
|
+
throw new Error("Pass at least one model option, connector option, or parameter option.");
|
|
331
|
+
}
|
|
332
|
+
if (hasSource && hasConnector) {
|
|
333
|
+
throw new Error("Use either --source or --connector-id, not both.");
|
|
334
|
+
}
|
|
335
|
+
if (hasSource && !AGENT_MODEL_SOURCES.includes(opts.source)) {
|
|
336
|
+
const suggestion = closestChoice(opts.source, AGENT_MODEL_SOURCES);
|
|
337
|
+
throw new Error(`Unknown --source ${opts.source}. Allowed sources: ${AGENT_MODEL_SOURCES.join(", ")}.` +
|
|
338
|
+
(suggestion ? ` Did you mean ${suggestion}?` : ""));
|
|
339
|
+
}
|
|
340
|
+
if (hasConnector && !isPositiveNumericId(opts.connectorId)) {
|
|
341
|
+
throw new Error("--connector-id must be a positive numeric model connector id from `dharta model-keys list`.");
|
|
342
|
+
}
|
|
343
|
+
validateParameterPair(opts.temperature, opts.clearTemperature, "--temperature", "--clear-temperature");
|
|
344
|
+
validateParameterPair(opts.topP, opts.clearTopP, "--top-p", "--clear-top-p");
|
|
345
|
+
validateParameterPair(opts.maxOutputTokens, opts.clearMaxOutputTokens, "--max-output-tokens", "--clear-max-output-tokens");
|
|
346
|
+
validateParameterPair(opts.reasoningEffort, opts.clearReasoningEffort, "--reasoning-effort", "--clear-reasoning-effort");
|
|
347
|
+
if (opts.temperature !== undefined)
|
|
348
|
+
parseBoundedNumber(opts.temperature, "--temperature", 0, 2, false);
|
|
349
|
+
if (opts.topP !== undefined)
|
|
350
|
+
parseBoundedNumber(opts.topP, "--top-p", 0, 1, true);
|
|
351
|
+
if (opts.maxOutputTokens !== undefined) {
|
|
352
|
+
const value = parsePositiveInteger(opts.maxOutputTokens, "--max-output-tokens");
|
|
353
|
+
if (value > MAX_OUTPUT_TOKENS) {
|
|
354
|
+
throw new Error(`--max-output-tokens must be at most ${MAX_OUTPUT_TOKENS}.`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (opts.reasoningEffort !== undefined && !["low", "medium", "high"].includes(opts.reasoningEffort)) {
|
|
358
|
+
throw new Error("--reasoning-effort must be low, medium, or high.");
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function isPositiveNumericId(value) {
|
|
362
|
+
if (!/^\d+$/.test(value))
|
|
363
|
+
return false;
|
|
364
|
+
const parsed = Number(value);
|
|
365
|
+
return Number.isSafeInteger(parsed) && parsed > 0;
|
|
366
|
+
}
|
|
367
|
+
function normalizeModelSetOptions(opts) {
|
|
368
|
+
return {
|
|
369
|
+
source: normalizeOptionalFlag(opts.source, "--source"),
|
|
370
|
+
connectorId: normalizeOptionalFlag(opts.connectorId, "--connector-id"),
|
|
371
|
+
model: normalizeOptionalFlag(opts.model, "--model"),
|
|
372
|
+
temperature: normalizeOptionalFlag(opts.temperature, "--temperature"),
|
|
373
|
+
clearTemperature: opts.clearTemperature,
|
|
374
|
+
topP: normalizeOptionalFlag(opts.topP, "--top-p"),
|
|
375
|
+
clearTopP: opts.clearTopP,
|
|
376
|
+
maxOutputTokens: normalizeOptionalFlag(opts.maxOutputTokens, "--max-output-tokens"),
|
|
377
|
+
clearMaxOutputTokens: opts.clearMaxOutputTokens,
|
|
378
|
+
reasoningEffort: normalizeOptionalFlag(opts.reasoningEffort, "--reasoning-effort"),
|
|
379
|
+
clearReasoningEffort: opts.clearReasoningEffort,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
function modelParameterOptionPresent(opts) {
|
|
383
|
+
return opts.temperature !== undefined || opts.clearTemperature === true ||
|
|
384
|
+
opts.topP !== undefined || opts.clearTopP === true ||
|
|
385
|
+
opts.maxOutputTokens !== undefined || opts.clearMaxOutputTokens === true ||
|
|
386
|
+
opts.reasoningEffort !== undefined || opts.clearReasoningEffort === true;
|
|
387
|
+
}
|
|
388
|
+
function modelParameterPatch(opts) {
|
|
389
|
+
const patch = {};
|
|
390
|
+
if (opts.temperature !== undefined)
|
|
391
|
+
patch.temperature = Number(opts.temperature);
|
|
392
|
+
if (opts.clearTemperature)
|
|
393
|
+
patch.temperature = null;
|
|
394
|
+
if (opts.topP !== undefined)
|
|
395
|
+
patch.top_p = Number(opts.topP);
|
|
396
|
+
if (opts.clearTopP)
|
|
397
|
+
patch.top_p = null;
|
|
398
|
+
if (opts.maxOutputTokens !== undefined)
|
|
399
|
+
patch.max_output_tokens = Number(opts.maxOutputTokens);
|
|
400
|
+
if (opts.clearMaxOutputTokens)
|
|
401
|
+
patch.max_output_tokens = null;
|
|
402
|
+
if (opts.reasoningEffort !== undefined)
|
|
403
|
+
patch.reasoning_effort = opts.reasoningEffort;
|
|
404
|
+
if (opts.clearReasoningEffort)
|
|
405
|
+
patch.reasoning_effort = null;
|
|
406
|
+
return patch;
|
|
407
|
+
}
|
|
408
|
+
function validateParameterPair(value, clear, setFlag, clearFlag) {
|
|
409
|
+
if (value !== undefined && clear)
|
|
410
|
+
throw new Error(`Use either ${setFlag} or ${clearFlag}, not both.`);
|
|
411
|
+
}
|
|
412
|
+
function parseBoundedNumber(value, flag, minimum, maximum, exclusiveMinimum) {
|
|
413
|
+
const parsed = Number(value);
|
|
414
|
+
const minimumOk = exclusiveMinimum ? parsed > minimum : parsed >= minimum;
|
|
415
|
+
if (!Number.isFinite(parsed) || !minimumOk || parsed > maximum) {
|
|
416
|
+
const lower = exclusiveMinimum ? `greater than ${minimum}` : `at least ${minimum}`;
|
|
417
|
+
throw new Error(`${flag} must be a finite number ${lower} and at most ${maximum}.`);
|
|
418
|
+
}
|
|
419
|
+
return parsed;
|
|
420
|
+
}
|
|
421
|
+
function parsePositiveInteger(value, flag) {
|
|
422
|
+
const parsed = Number(value);
|
|
423
|
+
if (!Number.isSafeInteger(parsed) || parsed <= 0) {
|
|
424
|
+
throw new Error(`${flag} must be a positive whole number.`);
|
|
425
|
+
}
|
|
426
|
+
return parsed;
|
|
427
|
+
}
|
|
428
|
+
function normalizeOptionalFlag(value, flag) {
|
|
429
|
+
if (value === undefined)
|
|
430
|
+
return undefined;
|
|
431
|
+
const normalized = value.trim();
|
|
432
|
+
if (normalized.length === 0)
|
|
433
|
+
throw new Error(`${flag} cannot be blank.`);
|
|
434
|
+
return normalized;
|
|
435
|
+
}
|
|
436
|
+
function normalizeAgentSlug(slug) {
|
|
437
|
+
return validateAgentSlug(slug, "agent slug");
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CliContext } from "../context.js";
|
|
2
|
+
export type AnalyticsView = "agents" | "users" | "instances" | "sessions" | "models" | "cost";
|
|
3
|
+
export declare const ENTITY_ANALYTICS_RANGES: readonly ["7d", "30d", "90d"];
|
|
4
|
+
export declare const COST_ANALYTICS_RANGES: readonly ["mtd", "7d", "30d", "90d", "last_month", "custom"];
|
|
5
|
+
export declare const COST_ANALYTICS_GROUPS: readonly ["agent", "karta", "session", "user", "model"];
|
|
6
|
+
export interface AnalyticsOptions {
|
|
7
|
+
range?: string;
|
|
8
|
+
groupBy?: string;
|
|
9
|
+
from?: string;
|
|
10
|
+
to?: string;
|
|
11
|
+
limit?: string;
|
|
12
|
+
}
|
|
13
|
+
interface AnalyticsResponse {
|
|
14
|
+
view: string;
|
|
15
|
+
range: string;
|
|
16
|
+
from: string;
|
|
17
|
+
to: string;
|
|
18
|
+
summary?: Record<string, unknown>;
|
|
19
|
+
totals?: Record<string, unknown>;
|
|
20
|
+
data: Array<Record<string, unknown>>;
|
|
21
|
+
}
|
|
22
|
+
export declare function analyticsData(ctx: CliContext, view: AnalyticsView, opts?: AnalyticsOptions): Promise<AnalyticsResponse>;
|
|
23
|
+
export declare function analytics(ctx: CliContext, view: AnalyticsView, opts?: AnalyticsOptions): Promise<string>;
|
|
24
|
+
export declare function normalizeAnalyticsOptions(view: AnalyticsView, opts: AnalyticsOptions): AnalyticsOptions;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { table } from "../output.js";
|
|
2
|
+
import { closestChoice, normalizeDateOnly, parsePositiveInteger } from "../validators.js";
|
|
3
|
+
export const ENTITY_ANALYTICS_RANGES = ["7d", "30d", "90d"];
|
|
4
|
+
export const COST_ANALYTICS_RANGES = ["mtd", "7d", "30d", "90d", "last_month", "custom"];
|
|
5
|
+
export const COST_ANALYTICS_GROUPS = ["agent", "karta", "session", "user", "model"];
|
|
6
|
+
export async function analyticsData(ctx, view, opts = {}) {
|
|
7
|
+
const normalized = normalizeAnalyticsOptions(view, opts);
|
|
8
|
+
const params = new URLSearchParams();
|
|
9
|
+
if (normalized.range)
|
|
10
|
+
params.set("range", normalized.range);
|
|
11
|
+
if (normalized.groupBy)
|
|
12
|
+
params.set("group_by", normalized.groupBy);
|
|
13
|
+
if (normalized.from)
|
|
14
|
+
params.set("from", normalized.from);
|
|
15
|
+
if (normalized.to)
|
|
16
|
+
params.set("to", normalized.to);
|
|
17
|
+
if (normalized.limit)
|
|
18
|
+
params.set("limit", normalized.limit);
|
|
19
|
+
const qs = params.toString();
|
|
20
|
+
return ctx.http.request({ path: `/api/analytics/${view}${qs ? `?${qs}` : ""}` });
|
|
21
|
+
}
|
|
22
|
+
export async function analytics(ctx, view, opts = {}) {
|
|
23
|
+
const res = await analyticsData(ctx, view, opts);
|
|
24
|
+
const lines = [`${title(view)} (${res.from} to ${res.to})`];
|
|
25
|
+
const summary = res.totals ?? res.summary;
|
|
26
|
+
if (summary) {
|
|
27
|
+
for (const [key, value] of Object.entries(summary)) {
|
|
28
|
+
lines.push(`${formatSummaryKey(key)}: ${formatSummaryValue(key, value)}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (res.data.length === 0)
|
|
32
|
+
return lines.join("\n");
|
|
33
|
+
lines.push("");
|
|
34
|
+
lines.push(table(res.data.map((row) => compactRow(view, row))));
|
|
35
|
+
return lines.join("\n");
|
|
36
|
+
}
|
|
37
|
+
export function normalizeAnalyticsOptions(view, opts) {
|
|
38
|
+
const normalized = { ...opts };
|
|
39
|
+
if (normalized.range !== undefined)
|
|
40
|
+
normalized.range = normalizeRequiredFilter(normalized.range, "--range");
|
|
41
|
+
if (normalized.groupBy !== undefined)
|
|
42
|
+
normalized.groupBy = normalizeRequiredFilter(normalized.groupBy, "--group-by");
|
|
43
|
+
if (normalized.from !== undefined)
|
|
44
|
+
normalized.from = normalizeDateOnly(normalized.from, "--from");
|
|
45
|
+
if (normalized.to !== undefined)
|
|
46
|
+
normalized.to = normalizeDateOnly(normalized.to, "--to");
|
|
47
|
+
if (normalized.limit !== undefined)
|
|
48
|
+
normalized.limit = normalizeRequiredFilter(normalized.limit, "--limit");
|
|
49
|
+
if (view === "cost" && (normalized.from !== undefined || normalized.to !== undefined)) {
|
|
50
|
+
if (normalized.range === undefined) {
|
|
51
|
+
normalized.range = "custom";
|
|
52
|
+
}
|
|
53
|
+
else if (normalized.range !== "custom") {
|
|
54
|
+
throw new Error("--from/--to require --range custom.");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (normalized.range) {
|
|
58
|
+
const allowed = view === "cost" ? COST_ANALYTICS_RANGES : ENTITY_ANALYTICS_RANGES;
|
|
59
|
+
if (!allowed.includes(normalized.range)) {
|
|
60
|
+
const suggestion = closestChoice(normalized.range, allowed);
|
|
61
|
+
throw new Error(`--range must be one of: ${allowed.join(", ")}.` +
|
|
62
|
+
(suggestion ? ` Did you mean ${suggestion}?` : ""));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (normalized.groupBy !== undefined) {
|
|
66
|
+
if (view !== "cost")
|
|
67
|
+
throw new Error("--group-by is only supported for analytics cost.");
|
|
68
|
+
if (!COST_ANALYTICS_GROUPS.includes(normalized.groupBy)) {
|
|
69
|
+
const suggestion = closestChoice(normalized.groupBy, COST_ANALYTICS_GROUPS);
|
|
70
|
+
throw new Error(`--group-by must be one of: ${COST_ANALYTICS_GROUPS.join(", ")}.` +
|
|
71
|
+
(suggestion ? ` Did you mean ${suggestion}?` : ""));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (normalized.limit !== undefined) {
|
|
75
|
+
parsePositiveInteger(normalized.limit, "--limit");
|
|
76
|
+
}
|
|
77
|
+
return normalized;
|
|
78
|
+
}
|
|
79
|
+
function normalizeRequiredFilter(value, flag) {
|
|
80
|
+
const normalized = value.trim();
|
|
81
|
+
if (!normalized)
|
|
82
|
+
throw new Error(`${flag} cannot be blank.`);
|
|
83
|
+
return normalized;
|
|
84
|
+
}
|
|
85
|
+
function title(view) {
|
|
86
|
+
if (view === "cost")
|
|
87
|
+
return "Analytics cost";
|
|
88
|
+
return `Analytics ${view}`;
|
|
89
|
+
}
|
|
90
|
+
function formatSummaryKey(key) {
|
|
91
|
+
if (key.endsWith("_micros"))
|
|
92
|
+
return key.slice(0, -"_micros".length);
|
|
93
|
+
if (key.endsWith("_pct"))
|
|
94
|
+
return key.slice(0, -"_pct".length);
|
|
95
|
+
return key;
|
|
96
|
+
}
|
|
97
|
+
function formatSummaryValue(key, value) {
|
|
98
|
+
if (key.endsWith("_micros"))
|
|
99
|
+
return formatMicros(value);
|
|
100
|
+
if (key.endsWith("_pct"))
|
|
101
|
+
return formatPercent(value);
|
|
102
|
+
return String(value);
|
|
103
|
+
}
|
|
104
|
+
function compactRow(view, row) {
|
|
105
|
+
if (view === "cost") {
|
|
106
|
+
return {
|
|
107
|
+
label: String(row.label ?? row.id ?? ""),
|
|
108
|
+
tokens: String(row.tokens ?? 0),
|
|
109
|
+
total: formatMicros(row.total_micros),
|
|
110
|
+
share: formatPercent(row.share_pct),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (view === "agents") {
|
|
114
|
+
return {
|
|
115
|
+
slug: String(row.slug ?? ""),
|
|
116
|
+
tokens: String(row.tokens ?? 0),
|
|
117
|
+
sessions: String(row.sessions_count ?? 0),
|
|
118
|
+
spend: formatMicros(row.spend_micros),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (view === "sessions") {
|
|
122
|
+
return {
|
|
123
|
+
id: String(row.id ?? ""),
|
|
124
|
+
agent: String(row.agent_slug ?? ""),
|
|
125
|
+
turns: String(row.turns ?? 0),
|
|
126
|
+
tokens: String(row.tokens ?? row.input_tokens ?? 0),
|
|
127
|
+
spend: formatMicros(row.spend_micros ?? row.cost_micros),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (view === "models") {
|
|
131
|
+
return {
|
|
132
|
+
model: String(row.id ?? row.model ?? ""),
|
|
133
|
+
tokens: String(row.tokens ?? 0),
|
|
134
|
+
sessions: String(row.sessions_count ?? 0),
|
|
135
|
+
spend: formatMicros(row.spend_micros ?? row.cost_micros),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (view === "instances") {
|
|
139
|
+
return {
|
|
140
|
+
id: String(row.id ?? ""),
|
|
141
|
+
agent: String(row.agent_slug ?? ""),
|
|
142
|
+
tokens: String(row.tokens ?? row.input_tokens ?? 0),
|
|
143
|
+
sessions: String(row.sessions_count ?? 0),
|
|
144
|
+
spend: formatMicros(row.spend_micros ?? row.cost_micros),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
id: String(row.id ?? ""),
|
|
149
|
+
tokens: String(row.tokens ?? row.input_tokens ?? 0),
|
|
150
|
+
sessions: String(row.sessions_count ?? 0),
|
|
151
|
+
spend: formatMicros(row.spend_micros ?? row.cost_micros),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function formatMicros(value) {
|
|
155
|
+
const micros = Number(value ?? 0);
|
|
156
|
+
if (!Number.isFinite(micros))
|
|
157
|
+
return "$0.0000";
|
|
158
|
+
return `$${(micros / 100_000_000).toFixed(4)}`;
|
|
159
|
+
}
|
|
160
|
+
function formatPercent(value) {
|
|
161
|
+
const percent = Number(value ?? 0);
|
|
162
|
+
if (!Number.isFinite(percent))
|
|
163
|
+
return "0%";
|
|
164
|
+
return `${percent}%`;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=analytics.js.map
|