@dharta/cli 0.6.77 → 0.6.78
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 +1 -1
- package/README.md +215 -11
- package/dist/agent.js +3 -2
- package/dist/agent.js.map +1 -1
- package/dist/api-error.js +6 -6
- package/dist/api-error.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +860 -149
- package/dist/cli.js.map +1 -1
- package/dist/command-tree.d.ts +3 -0
- package/dist/command-tree.js +10 -0
- package/dist/command-tree.js.map +1 -0
- package/dist/commands/agents.d.ts +54 -17
- package/dist/commands/agents.js +246 -136
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/analytics.js +6 -5
- package/dist/commands/analytics.js.map +1 -1
- package/dist/commands/api.js +71 -86
- package/dist/commands/api.js.map +1 -1
- package/dist/commands/appearance.js +5 -6
- package/dist/commands/appearance.js.map +1 -1
- package/dist/commands/artifact.js +7 -6
- package/dist/commands/artifact.js.map +1 -1
- package/dist/commands/audit-log.js +2 -1
- package/dist/commands/audit-log.js.map +1 -1
- package/dist/commands/auth.js +26 -6
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/caps.js +11 -15
- package/dist/commands/caps.js.map +1 -1
- package/dist/commands/deploy.js +25 -10
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.d.ts +10 -1
- package/dist/commands/dev.js +56 -25
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +60 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/embed-keys.js +4 -13
- package/dist/commands/embed-keys.js.map +1 -1
- package/dist/commands/env.js +4 -7
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/files.js +3 -4
- package/dist/commands/files.js.map +1 -1
- package/dist/commands/fleet.d.ts +129 -0
- package/dist/commands/fleet.js +408 -0
- package/dist/commands/fleet.js.map +1 -0
- package/dist/commands/genui.d.ts +2 -0
- package/dist/commands/genui.js +53 -0
- package/dist/commands/genui.js.map +1 -0
- package/dist/commands/git-credential.js +2 -3
- package/dist/commands/git-credential.js.map +1 -1
- package/dist/commands/kartas.d.ts +9 -0
- package/dist/commands/kartas.js +33 -11
- package/dist/commands/kartas.js.map +1 -1
- package/dist/commands/keys.d.ts +17 -18
- package/dist/commands/keys.js +108 -19
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/login.js +2 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/members.d.ts +10 -0
- package/dist/commands/members.js +20 -6
- package/dist/commands/members.js.map +1 -1
- package/dist/commands/model-connections.d.ts +44 -0
- package/dist/commands/model-connections.js +435 -0
- package/dist/commands/model-connections.js.map +1 -0
- package/dist/commands/open.d.ts +2 -2
- package/dist/commands/open.js +4 -3
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/org.d.ts +9 -0
- package/dist/commands/org.js +42 -0
- package/dist/commands/org.js.map +1 -0
- package/dist/commands/organization.d.ts +16 -0
- package/dist/commands/organization.js +118 -0
- package/dist/commands/organization.js.map +1 -0
- package/dist/commands/parity.js +1 -3
- package/dist/commands/parity.js.map +1 -1
- package/dist/commands/repos.d.ts +4 -0
- package/dist/commands/repos.js +17 -0
- package/dist/commands/repos.js.map +1 -0
- package/dist/commands/rollback.js +2 -3
- package/dist/commands/rollback.js.map +1 -1
- package/dist/commands/schedules.js +26 -21
- package/dist/commands/schedules.js.map +1 -1
- package/dist/commands/scopes.js +8 -1
- package/dist/commands/scopes.js.map +1 -1
- package/dist/commands/sessions.js +9 -3
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/setup.js +5 -4
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/update.d.ts +1 -0
- package/dist/commands/update.js +24 -11
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/webhooks.d.ts +4 -1
- package/dist/commands/webhooks.js +21 -16
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/completions.js +24 -13
- package/dist/completions.js.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.js +121 -7
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +2 -0
- package/dist/context.js +23 -7
- package/dist/context.js.map +1 -1
- package/dist/docs/cli-reference.d.ts +2 -0
- package/dist/docs/cli-reference.js +191 -0
- package/dist/docs/cli-reference.js.map +1 -0
- package/dist/exit-codes.d.ts +25 -0
- package/dist/exit-codes.js +107 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/genui.d.ts +178 -0
- package/dist/genui.js +1130 -0
- package/dist/genui.js.map +1 -0
- package/dist/harnesses.js +2 -1
- package/dist/harnesses.js.map +1 -1
- package/dist/jq.d.ts +4 -0
- package/dist/jq.js +91 -0
- package/dist/jq.js.map +1 -0
- package/dist/login-offer.js +6 -2
- package/dist/login-offer.js.map +1 -1
- package/dist/manifest.d.ts +12 -0
- package/dist/manifest.js +126 -0
- package/dist/manifest.js.map +1 -1
- package/dist/model-auth.d.ts +29 -0
- package/dist/model-auth.js +117 -0
- package/dist/model-auth.js.map +1 -0
- package/dist/model-settings.d.ts +23 -0
- package/dist/model-settings.js +186 -0
- package/dist/model-settings.js.map +1 -0
- package/dist/money.js +2 -1
- package/dist/money.js.map +1 -1
- package/dist/output.d.ts +6 -0
- package/dist/output.js +54 -0
- package/dist/output.js.map +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +1 -1
- package/dist/scaffold.js +2 -1
- package/dist/scaffold.js.map +1 -1
- package/dist/validators.js +17 -11
- package/dist/validators.js.map +1 -1
- package/dist/version-check.d.ts +1 -1
- package/dist/version-check.js +1 -1
- package/dist/version-check.js.map +1 -1
- package/node_modules/@dharta/contracts/LICENSE +21 -0
- package/node_modules/@dharta/contracts/README.md +45 -0
- package/node_modules/@dharta/contracts/artifact-runtime.json +750 -0
- package/node_modules/@dharta/contracts/dist/activity.d.ts +62 -0
- package/node_modules/@dharta/contracts/dist/activity.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/activity.js +178 -0
- package/node_modules/@dharta/contracts/dist/activity.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-formats.d.ts +20 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-formats.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-formats.js +53 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-formats.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-validators.generated.d.ts +37 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-validators.generated.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-validators.generated.js +5107 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime-validators.generated.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.d.ts +154 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.generated.d.ts +1670 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.generated.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.generated.js +1903 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.generated.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.js +377 -0
- package/node_modules/@dharta/contracts/dist/artifact-runtime.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/index.d.ts +6 -0
- package/node_modules/@dharta/contracts/dist/index.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/index.js +6 -0
- package/node_modules/@dharta/contracts/dist/index.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/model-auth.d.ts +31 -0
- package/node_modules/@dharta/contracts/dist/model-auth.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/model-auth.js +45 -0
- package/node_modules/@dharta/contracts/dist/model-auth.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/tasks.d.ts +44 -0
- package/node_modules/@dharta/contracts/dist/tasks.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/tasks.js +127 -0
- package/node_modules/@dharta/contracts/dist/tasks.js.map +1 -0
- package/node_modules/@dharta/contracts/dist/wire-events.d.ts +71 -0
- package/node_modules/@dharta/contracts/dist/wire-events.d.ts.map +1 -0
- package/node_modules/@dharta/contracts/dist/wire-events.js +48 -0
- package/node_modules/@dharta/contracts/dist/wire-events.js.map +1 -0
- package/node_modules/@dharta/contracts/model-auth-capabilities-v1.json +168 -0
- package/node_modules/@dharta/contracts/model-auth-reasons-v1.json +38 -0
- package/node_modules/@dharta/contracts/package.json +44 -0
- package/node_modules/@dharta/contracts/src/activity.ts +215 -0
- package/node_modules/@dharta/contracts/src/artifact-runtime-formats.ts +54 -0
- package/node_modules/@dharta/contracts/src/artifact-runtime-validators.generated.ts +29 -0
- package/node_modules/@dharta/contracts/src/artifact-runtime.generated.ts +2093 -0
- package/node_modules/@dharta/contracts/src/artifact-runtime.ts +520 -0
- package/node_modules/@dharta/contracts/src/index.ts +5 -0
- package/node_modules/@dharta/contracts/src/model-auth.ts +82 -0
- package/node_modules/@dharta/contracts/src/tasks.ts +142 -0
- package/node_modules/@dharta/contracts/src/wire-events.ts +150 -0
- package/node_modules/@dharta/contracts/wire-events.json +29 -0
- package/node_modules/@dharta/sdk/LICENSE +1 -1
- package/node_modules/@dharta/sdk/README.md +22 -8
- package/node_modules/@dharta/sdk/dist/errors.d.ts +9 -7
- package/node_modules/@dharta/sdk/dist/errors.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/errors.js +36 -18
- package/node_modules/@dharta/sdk/dist/errors.js.map +1 -1
- package/node_modules/@dharta/sdk/dist/fleet.d.ts +69 -0
- package/node_modules/@dharta/sdk/dist/fleet.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/fleet.js +240 -0
- package/node_modules/@dharta/sdk/dist/fleet.js.map +1 -0
- package/node_modules/@dharta/sdk/dist/http.d.ts +6 -2
- package/node_modules/@dharta/sdk/dist/http.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/http.js +71 -12
- package/node_modules/@dharta/sdk/dist/http.js.map +1 -1
- package/node_modules/@dharta/sdk/dist/idempotency.d.ts +12 -0
- package/node_modules/@dharta/sdk/dist/idempotency.d.ts.map +1 -0
- package/node_modules/@dharta/sdk/dist/idempotency.js +72 -0
- package/node_modules/@dharta/sdk/dist/idempotency.js.map +1 -0
- package/node_modules/@dharta/sdk/dist/index.d.ts +20 -6
- package/node_modules/@dharta/sdk/dist/index.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/index.js +27 -4
- package/node_modules/@dharta/sdk/dist/index.js.map +1 -1
- package/node_modules/@dharta/sdk/dist/resources.d.ts +108 -13
- package/node_modules/@dharta/sdk/dist/resources.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/resources.js +403 -57
- package/node_modules/@dharta/sdk/dist/resources.js.map +1 -1
- package/node_modules/@dharta/sdk/dist/types.d.ts +436 -16
- package/node_modules/@dharta/sdk/dist/types.d.ts.map +1 -1
- package/node_modules/@dharta/sdk/dist/types.js +31 -2
- package/node_modules/@dharta/sdk/dist/types.js.map +1 -1
- package/node_modules/@dharta/sdk/package.json +9 -3
- package/node_modules/@dharta/sdk/src/errors.ts +41 -18
- package/node_modules/@dharta/sdk/src/fleet.ts +339 -0
- package/node_modules/@dharta/sdk/src/http.ts +110 -17
- package/node_modules/@dharta/sdk/src/idempotency.ts +101 -0
- package/node_modules/@dharta/sdk/src/index.ts +50 -11
- package/node_modules/@dharta/sdk/src/resources.ts +549 -68
- package/node_modules/@dharta/sdk/src/types.ts +629 -20
- package/package.json +16 -6
- package/src/agent.ts +3 -2
- package/src/api-error.ts +6 -5
- package/src/cli.ts +978 -163
- package/src/command-tree.ts +13 -0
- package/src/commands/agents.ts +365 -167
- package/src/commands/analytics.ts +6 -5
- package/src/commands/api.ts +73 -92
- package/src/commands/appearance.ts +5 -6
- package/src/commands/artifact.ts +7 -6
- package/src/commands/audit-log.ts +2 -1
- package/src/commands/auth.ts +25 -5
- package/src/commands/caps.ts +11 -15
- package/src/commands/deploy.ts +18 -4
- package/src/commands/dev.ts +86 -25
- package/src/commands/doctor.ts +69 -0
- package/src/commands/embed-keys.ts +4 -14
- package/src/commands/env.ts +4 -7
- package/src/commands/files.ts +3 -4
- package/src/commands/fleet.ts +672 -0
- package/src/commands/genui.ts +59 -0
- package/src/commands/git-credential.ts +2 -3
- package/src/commands/kartas.ts +45 -11
- package/src/commands/keys.ts +152 -35
- package/src/commands/login.ts +2 -1
- package/src/commands/members.ts +31 -6
- package/src/commands/model-connections.ts +547 -0
- package/src/commands/open.ts +5 -4
- package/src/commands/org.ts +57 -0
- package/src/commands/organization.ts +153 -0
- package/src/commands/parity.ts +1 -3
- package/src/commands/repos.ts +23 -0
- package/src/commands/rollback.ts +2 -3
- package/src/commands/schedules.ts +33 -22
- package/src/commands/scopes.ts +8 -1
- package/src/commands/sessions.ts +9 -3
- package/src/commands/setup.ts +5 -4
- package/src/commands/update.ts +28 -12
- package/src/commands/webhooks.ts +30 -19
- package/src/completions.ts +25 -13
- package/src/config.ts +141 -9
- package/src/context.ts +34 -7
- package/src/docs/cli-reference.ts +206 -0
- package/src/exit-codes.ts +122 -0
- package/src/genui.ts +1398 -0
- package/src/harnesses.ts +2 -1
- package/src/jq.ts +109 -0
- package/src/login-offer.ts +6 -2
- package/src/manifest.ts +134 -0
- package/src/model-auth.ts +173 -0
- package/src/model-settings.ts +222 -0
- package/src/money.ts +5 -1
- package/src/output.ts +60 -0
- package/src/runtime.ts +1 -1
- package/src/scaffold.ts +2 -1
- package/src/validators.ts +18 -11
- package/src/version-check.ts +1 -1
- package/dist/commands/model-keys.d.ts +0 -22
- package/dist/commands/model-keys.js +0 -222
- package/dist/commands/model-keys.js.map +0 -1
- package/src/commands/model-keys.ts +0 -278
package/src/commands/agents.ts
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import type { CliContext } from "../context.js";
|
|
2
|
+
import type {
|
|
3
|
+
AgentChangeResponse,
|
|
4
|
+
AgentCreateParams,
|
|
5
|
+
AgentCreateResponse,
|
|
6
|
+
AgentDeployResponse,
|
|
7
|
+
AgentFromTemplateParams,
|
|
8
|
+
AgentFromTemplateResponse,
|
|
9
|
+
AgentLinkGithubResponse,
|
|
10
|
+
GithubRepository,
|
|
11
|
+
ReleaseRetryResponse,
|
|
12
|
+
} from "@dharta/sdk";
|
|
13
|
+
import { isAgentLinkGithubResponse } from "@dharta/sdk";
|
|
2
14
|
import { fmtTs, table } from "../output.js";
|
|
3
15
|
import { validateAgentSlug } from "../agent.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
16
|
+
import { CliUsageError } from "../exit-codes.js";
|
|
17
|
+
import { closestChoice, normalizeNonBlank, parsePositiveInteger, parseReleaseVersion } from "../validators.js";
|
|
18
|
+
import {
|
|
19
|
+
type ModelParameterOptions,
|
|
20
|
+
formatModelParameters,
|
|
21
|
+
modelParameterOptionPresent,
|
|
22
|
+
modelParameterPatch,
|
|
23
|
+
normalizeConnectorSlug,
|
|
24
|
+
normalizeModelParameterOptions,
|
|
25
|
+
normalizeModelReference,
|
|
26
|
+
parseConnectorOrder,
|
|
27
|
+
validateModelParameterOptions,
|
|
28
|
+
} from "../model-settings.js";
|
|
9
29
|
|
|
10
30
|
export interface AgentSummary {
|
|
11
31
|
id: string | number;
|
|
@@ -38,16 +58,35 @@ export interface AgentDetail extends AgentSummary {
|
|
|
38
58
|
resolved_model?: ResolvedAgentModel;
|
|
39
59
|
}
|
|
40
60
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
// Either the route resolved, or it carries a stable failure code and nothing
|
|
62
|
+
// else. Narrow on `error` before reading the rest, the same way the SDK's
|
|
63
|
+
// ResolvedOrganizationModel is read.
|
|
64
|
+
export type ResolvedAgentModel =
|
|
65
|
+
| {
|
|
66
|
+
error?: never;
|
|
67
|
+
model_id: string | null;
|
|
68
|
+
model_connection_id: number | null;
|
|
69
|
+
// The selected connector's slug, or `karta` for the platform connector.
|
|
70
|
+
connector: string | null;
|
|
71
|
+
credential_kind: string;
|
|
72
|
+
provider: string;
|
|
73
|
+
endpoint_url: string | null;
|
|
74
|
+
api_format: string;
|
|
75
|
+
custom_endpoint: boolean;
|
|
76
|
+
parameters: Record<string, unknown>;
|
|
77
|
+
}
|
|
78
|
+
| {
|
|
79
|
+
error: string;
|
|
80
|
+
model_id?: never;
|
|
81
|
+
model_connection_id?: never;
|
|
82
|
+
connector?: never;
|
|
83
|
+
credential_kind?: never;
|
|
84
|
+
provider?: never;
|
|
85
|
+
endpoint_url?: never;
|
|
86
|
+
api_format?: never;
|
|
87
|
+
custom_endpoint?: never;
|
|
88
|
+
parameters?: never;
|
|
89
|
+
};
|
|
51
90
|
|
|
52
91
|
interface AgentShowEnvelope {
|
|
53
92
|
agent: {
|
|
@@ -79,9 +118,11 @@ export interface AgentSettingsAgent {
|
|
|
79
118
|
workspace_access?: WorkspaceAccessMatrix;
|
|
80
119
|
model: {
|
|
81
120
|
source: string;
|
|
82
|
-
|
|
121
|
+
model_connection_id: number | null;
|
|
83
122
|
model: string | null;
|
|
84
123
|
parameters: Record<string, unknown>;
|
|
124
|
+
connector_order: string[];
|
|
125
|
+
model_reference: string;
|
|
85
126
|
};
|
|
86
127
|
}
|
|
87
128
|
|
|
@@ -182,11 +223,14 @@ export async function agentsShow(ctx: CliContext, slug: string): Promise<string>
|
|
|
182
223
|
}
|
|
183
224
|
|
|
184
225
|
function formatResolvedModel(route: ResolvedAgentModel): string {
|
|
226
|
+
// An organization with no resolvable model still has agents worth reading.
|
|
227
|
+
// Say which failure it is rather than printing a route made of blanks.
|
|
228
|
+
if (route.error !== undefined) {
|
|
229
|
+
return `Resolved model: unavailable (${route.error})`;
|
|
230
|
+
}
|
|
185
231
|
const model = route.model_id ?? "provider default";
|
|
186
|
-
const connector = route
|
|
187
|
-
const parameters =
|
|
188
|
-
.map(([name, value]) => `${name}=${JSON.stringify(value)}`)
|
|
189
|
-
.join(", ");
|
|
232
|
+
const connector = resolvedConnectorLabel(route);
|
|
233
|
+
const parameters = formatModelParameters(route.parameters);
|
|
190
234
|
return [
|
|
191
235
|
`Resolved model: ${route.provider}/${model} (${route.api_format}, ${connector})`,
|
|
192
236
|
route.endpoint_url ? `Model endpoint: ${route.endpoint_url}` : null,
|
|
@@ -194,6 +238,14 @@ function formatResolvedModel(route: ResolvedAgentModel): string {
|
|
|
194
238
|
].filter((line): line is string => line !== null).join("\n");
|
|
195
239
|
}
|
|
196
240
|
|
|
241
|
+
// Name the connector the way every other command does: by slug, which is
|
|
242
|
+
// also what `--connector` and a model reference accept.
|
|
243
|
+
function resolvedConnectorLabel(route: ResolvedAgentModel): string {
|
|
244
|
+
return route.connector === "karta" || route.connector === null
|
|
245
|
+
? "platform"
|
|
246
|
+
: `connector ${route.connector}`;
|
|
247
|
+
}
|
|
248
|
+
|
|
197
249
|
function isReleaseScopeError(error: unknown): boolean {
|
|
198
250
|
if (!(error instanceof Error)) return false;
|
|
199
251
|
const status = (error as Error & { status?: unknown }).status;
|
|
@@ -263,7 +315,6 @@ export async function agentsActivateReleaseData(
|
|
|
263
315
|
return ctx.http.request<{ agent: ActivationAgent; release: ReleaseSummary; previous_release: ReleaseSummary | null }>({
|
|
264
316
|
method: "POST",
|
|
265
317
|
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/releases/${encodeURIComponent(releaseVersion)}/activate`,
|
|
266
|
-
headers: { "Idempotency-Key": randomUUID() },
|
|
267
318
|
});
|
|
268
319
|
}
|
|
269
320
|
|
|
@@ -282,7 +333,6 @@ export async function agentsServingSetData(
|
|
|
282
333
|
return ctx.http.request<{ agent: AgentSettingsAgent; changed: boolean }>({
|
|
283
334
|
method: "PATCH",
|
|
284
335
|
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/serving`,
|
|
285
|
-
headers: { "Idempotency-Key": randomUUID() },
|
|
286
336
|
body: { enabled },
|
|
287
337
|
});
|
|
288
338
|
}
|
|
@@ -302,7 +352,6 @@ export async function agentsDashboardEditsSetData(
|
|
|
302
352
|
return ctx.http.request<{ agent: AgentSettingsAgent; changed: boolean }>({
|
|
303
353
|
method: "PATCH",
|
|
304
354
|
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/dashboard_edits`,
|
|
305
|
-
headers: { "Idempotency-Key": randomUUID() },
|
|
306
355
|
body: { enabled },
|
|
307
356
|
});
|
|
308
357
|
}
|
|
@@ -313,18 +362,9 @@ export async function agentsDashboardEditsSet(ctx: CliContext, slug: string, ena
|
|
|
313
362
|
return `Dashboard edits ${state} for ${res.agent.slug}${res.changed ? "" : " (unchanged)"}.`;
|
|
314
363
|
}
|
|
315
364
|
|
|
316
|
-
export interface AgentModelSetOptions {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
model?: string;
|
|
320
|
-
temperature?: string;
|
|
321
|
-
clearTemperature?: boolean;
|
|
322
|
-
topP?: string;
|
|
323
|
-
clearTopP?: boolean;
|
|
324
|
-
maxOutputTokens?: string;
|
|
325
|
-
clearMaxOutputTokens?: boolean;
|
|
326
|
-
reasoningEffort?: string;
|
|
327
|
-
clearReasoningEffort?: boolean;
|
|
365
|
+
export interface AgentModelSetOptions extends ModelParameterOptions {
|
|
366
|
+
connector?: string;
|
|
367
|
+
modelRef?: string;
|
|
328
368
|
}
|
|
329
369
|
|
|
330
370
|
export async function agentsModelSetData(
|
|
@@ -335,16 +375,17 @@ export async function agentsModelSetData(
|
|
|
335
375
|
const normalizedSlug = normalizeAgentSlug(slug);
|
|
336
376
|
const normalized = validateAgentModelSetOptions(opts);
|
|
337
377
|
const body: Record<string, unknown> = {};
|
|
338
|
-
if (normalized.
|
|
339
|
-
body.
|
|
378
|
+
if (normalized.connector !== undefined) {
|
|
379
|
+
body.connector_order = parseConnectorOrder(normalized.connector, "--connector");
|
|
380
|
+
}
|
|
381
|
+
if (normalized.modelRef !== undefined) {
|
|
382
|
+
body.model_reference = normalizeModelReference(normalized.modelRef, "--model-ref");
|
|
340
383
|
}
|
|
341
|
-
if (normalized.model !== undefined) body.default_model_id = normalized.model;
|
|
342
384
|
const modelParameters = modelParameterPatch(normalized);
|
|
343
385
|
if (Object.keys(modelParameters).length > 0) body.model_parameters = modelParameters;
|
|
344
386
|
return ctx.http.request<{ agent: AgentSettingsAgent }>({
|
|
345
387
|
method: "PATCH",
|
|
346
388
|
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/model`,
|
|
347
|
-
headers: { "Idempotency-Key": randomUUID() },
|
|
348
389
|
body,
|
|
349
390
|
});
|
|
350
391
|
}
|
|
@@ -352,7 +393,9 @@ export async function agentsModelSetData(
|
|
|
352
393
|
export async function agentsModelSet(ctx: CliContext, slug: string, opts: AgentModelSetOptions): Promise<string> {
|
|
353
394
|
const res = await agentsModelSetData(ctx, slug, opts);
|
|
354
395
|
const model = res.agent.model.model ? ` model ${res.agent.model.model}` : "";
|
|
355
|
-
|
|
396
|
+
const order = res.agent.model.connector_order;
|
|
397
|
+
const source = order.length > 0 ? order.join(", ") : res.agent.model.source;
|
|
398
|
+
return `Model override for ${res.agent.slug}: ${source}${model}.`;
|
|
356
399
|
}
|
|
357
400
|
|
|
358
401
|
export function validateAgentModelSetOptions(opts: AgentModelSetOptions): AgentModelSetOptions {
|
|
@@ -370,7 +413,6 @@ export async function agentsWorkspaceInspectableSetData(
|
|
|
370
413
|
return ctx.http.request<{ agent: AgentSettingsAgent; changed: boolean }>({
|
|
371
414
|
method: "PATCH",
|
|
372
415
|
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/workspace_inspectable`,
|
|
373
|
-
headers: { "Idempotency-Key": randomUUID() },
|
|
374
416
|
body: { enabled },
|
|
375
417
|
});
|
|
376
418
|
}
|
|
@@ -396,19 +438,19 @@ export type WorkspaceAccessPatch = Record<string, Record<string, boolean>>;
|
|
|
396
438
|
// the API merges. Unknown paths and non-on/off values fail loud with a suggestion.
|
|
397
439
|
export function parseWorkspaceAccessAssignments(assignments: string[]): WorkspaceAccessPatch {
|
|
398
440
|
if (assignments.length === 0) {
|
|
399
|
-
throw new
|
|
441
|
+
throw new CliUsageError("Provide at least one grant, e.g. users.widget=on");
|
|
400
442
|
}
|
|
401
443
|
const patch: WorkspaceAccessPatch = {};
|
|
402
444
|
for (const raw of assignments) {
|
|
403
445
|
const eq = raw.indexOf("=");
|
|
404
446
|
if (eq === -1) {
|
|
405
|
-
throw new
|
|
447
|
+
throw new CliUsageError(`Invalid grant "${raw}". Use <path>=<on|off>, e.g. users.widget=on.`);
|
|
406
448
|
}
|
|
407
449
|
const path = raw.slice(0, eq).trim();
|
|
408
450
|
const value = raw.slice(eq + 1);
|
|
409
451
|
if (!WORKSPACE_ACCESS_PATHS.includes(path as (typeof WORKSPACE_ACCESS_PATHS)[number])) {
|
|
410
452
|
const suggestion = closestChoice(path, WORKSPACE_ACCESS_PATHS);
|
|
411
|
-
throw new
|
|
453
|
+
throw new CliUsageError(
|
|
412
454
|
`Unknown grant "${path}". One of: ${WORKSPACE_ACCESS_PATHS.join(", ")}.` +
|
|
413
455
|
(suggestion ? ` Did you mean ${suggestion}?` : ""),
|
|
414
456
|
);
|
|
@@ -423,7 +465,7 @@ function parseGrantValue(value: string, path: string): boolean {
|
|
|
423
465
|
const normalized = value.trim().toLowerCase();
|
|
424
466
|
if (["on", "true", "enabled", "enable", "1"].includes(normalized)) return true;
|
|
425
467
|
if (["off", "false", "disabled", "disable", "0"].includes(normalized)) return false;
|
|
426
|
-
throw new
|
|
468
|
+
throw new CliUsageError(`Grant "${path}" must be on/off, enabled/disabled, or true/false (got "${value}").`);
|
|
427
469
|
}
|
|
428
470
|
|
|
429
471
|
export async function agentsWorkspaceAccessShowData(ctx: CliContext, slug: string): Promise<WorkspaceAccessMatrix> {
|
|
@@ -459,7 +501,6 @@ export async function agentsWorkspaceAccessSetData(
|
|
|
459
501
|
return ctx.http.request<{ agent: AgentSettingsAgent; changed: boolean }>({
|
|
460
502
|
method: "PATCH",
|
|
461
503
|
path: `/api/agents/${encodeURIComponent(normalizedSlug)}/workspace_access`,
|
|
462
|
-
headers: { "Idempotency-Key": randomUUID() },
|
|
463
504
|
body: { workspace_access: patch },
|
|
464
505
|
});
|
|
465
506
|
}
|
|
@@ -476,160 +517,317 @@ export async function agentsWorkspaceAccessSet(
|
|
|
476
517
|
return `Workspace access updated for ${res.agent.slug}: ${paths.join(", ")}${res.changed ? "" : " (unchanged)"}.`;
|
|
477
518
|
}
|
|
478
519
|
|
|
479
|
-
|
|
520
|
+
// RFC 0048 P4. From here down the commands go through the SDK resource rather
|
|
521
|
+
// than a hand-built request: every new endpoint ships an @dharta/sdk method and
|
|
522
|
+
// the curated command calls it, so the wire shape and the idempotency header
|
|
523
|
+
// have one owner.
|
|
524
|
+
|
|
525
|
+
export async function agentsRenameData(
|
|
526
|
+
ctx: CliContext,
|
|
527
|
+
slug: string,
|
|
528
|
+
name: string,
|
|
529
|
+
): Promise<AgentChangeResponse> {
|
|
480
530
|
const normalizedSlug = normalizeAgentSlug(slug);
|
|
481
|
-
return ctx.
|
|
482
|
-
method: "DELETE",
|
|
483
|
-
path: `/api/agents/${encodeURIComponent(normalizedSlug)}`,
|
|
484
|
-
headers: { "Idempotency-Key": randomUUID() },
|
|
485
|
-
});
|
|
531
|
+
return ctx.sdk.agents.rename(normalizedSlug, normalizeAgentName(name));
|
|
486
532
|
}
|
|
487
533
|
|
|
488
|
-
export async function
|
|
489
|
-
const res = await
|
|
490
|
-
|
|
534
|
+
export async function agentsRename(ctx: CliContext, slug: string, name: string): Promise<string> {
|
|
535
|
+
const res = await agentsRenameData(ctx, slug, name);
|
|
536
|
+
const unchanged = res.changed ? "" : " (unchanged)";
|
|
537
|
+
return `${res.agent.slug} is now displayed as ${JSON.stringify(res.agent.name)}${unchanged}. The slug is unchanged.`;
|
|
491
538
|
}
|
|
492
539
|
|
|
493
|
-
function
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
540
|
+
export async function agentsDurableWorkspaceSetData(
|
|
541
|
+
ctx: CliContext,
|
|
542
|
+
slug: string,
|
|
543
|
+
enabled: boolean,
|
|
544
|
+
): Promise<AgentChangeResponse> {
|
|
545
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
546
|
+
return ctx.sdk.agents.setDurableWorkspace(normalizedSlug, enabled);
|
|
498
547
|
}
|
|
499
548
|
|
|
500
|
-
function
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
549
|
+
export async function agentsDurableWorkspaceSet(
|
|
550
|
+
ctx: CliContext,
|
|
551
|
+
slug: string,
|
|
552
|
+
enabled: boolean,
|
|
553
|
+
): Promise<string> {
|
|
554
|
+
const res = await agentsDurableWorkspaceSetData(ctx, slug, enabled);
|
|
555
|
+
const state = enabled ? "enabled" : "disabled";
|
|
556
|
+
if (!res.changed) return `Durable workspace already ${state} for ${res.agent.slug}.`;
|
|
557
|
+
const effect = enabled
|
|
558
|
+
? "Takes effect on the next release."
|
|
559
|
+
: "Takes effect on the next release; stored data is kept.";
|
|
560
|
+
return `Durable workspace ${state} for ${res.agent.slug}. ${effect}`;
|
|
561
|
+
}
|
|
505
562
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
563
|
+
export interface AgentCreateOptions {
|
|
564
|
+
slug?: string;
|
|
565
|
+
githubRepo?: string;
|
|
566
|
+
branch?: string;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
export async function agentsCreateData(
|
|
570
|
+
ctx: CliContext,
|
|
571
|
+
name: string | undefined,
|
|
572
|
+
opts: AgentCreateOptions = {},
|
|
573
|
+
): Promise<AgentCreateResponse | AgentLinkGithubResponse> {
|
|
574
|
+
const params = validateAgentCreateInput(name, opts);
|
|
575
|
+
if (typeof params.githubRepositoryId === "string") {
|
|
576
|
+
params.githubRepositoryId = await resolveGithubRepositoryId(ctx, params.githubRepositoryId);
|
|
513
577
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
578
|
+
return ctx.sdk.agents.create(params);
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// `--github-repo` takes either the numeric id or the owner/name a person can
|
|
582
|
+
// actually read off GitHub. The name is resolved through the same listing
|
|
583
|
+
// `dharta agent github-repos` prints, so an unknown one names the alternatives
|
|
584
|
+
// rather than reaching the server as a 404.
|
|
585
|
+
async function resolveGithubRepositoryId(ctx: CliContext, fullName: string): Promise<number> {
|
|
586
|
+
let data: GithubRepository[];
|
|
587
|
+
try {
|
|
588
|
+
({ data } = await ctx.sdk.githubRepositories.list());
|
|
589
|
+
} catch (error) {
|
|
590
|
+
// The listing rides source_repos:read, which a deploy key holding only
|
|
591
|
+
// agents:write does not have. Without this the command fails naming a scope
|
|
592
|
+
// the user never asked for, on a step they did not know it was taking.
|
|
593
|
+
if ((error as { status?: number }).status === 403) {
|
|
594
|
+
throw new CliUsageError(
|
|
595
|
+
`Resolving --github-repo ${fullName} needs the source_repos:read scope, because it looks the ` +
|
|
596
|
+
"repository up in your installations. This key does not have it. Pass the numeric id " +
|
|
597
|
+
"instead, which needs no extra scope, or use a key with source_repos:read.",
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
throw error;
|
|
520
601
|
}
|
|
521
|
-
|
|
522
|
-
|
|
602
|
+
const wanted = fullName.toLowerCase();
|
|
603
|
+
const match = data.find((repo) => repo.full_name.toLowerCase() === wanted);
|
|
604
|
+
if (match) return match.id;
|
|
605
|
+
|
|
606
|
+
const known = data.map((repo) => repo.full_name);
|
|
607
|
+
const suggestion = closestChoice(fullName, known);
|
|
608
|
+
const tail = suggestion
|
|
609
|
+
? ` Did you mean ${suggestion}?`
|
|
610
|
+
: known.length > 0
|
|
611
|
+
? ` Installed: ${known.slice(0, 10).join(", ")}.`
|
|
612
|
+
: " No repositories are installed for this organization; install the Dharta GitHub App first.";
|
|
613
|
+
// A usage error, not a failure: the user typed a name that does not exist, so
|
|
614
|
+
// this exits 2 like every other bad-argument path rather than 1.
|
|
615
|
+
throw new CliUsageError(`${fullName} is not an installed GitHub repository.${tail}`);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
export async function agentsGithubReposData(ctx: CliContext): Promise<{ data: GithubRepository[] }> {
|
|
619
|
+
return ctx.sdk.githubRepositories.list();
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
export async function agentsGithubRepos(ctx: CliContext): Promise<string> {
|
|
623
|
+
const { data } = await agentsGithubReposData(ctx);
|
|
624
|
+
if (data.length === 0) {
|
|
625
|
+
return "No GitHub repositories are installed for this organization. Install the Dharta GitHub App, then try again.";
|
|
523
626
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
validateParameterPair(
|
|
533
|
-
opts.reasoningEffort,
|
|
534
|
-
opts.clearReasoningEffort,
|
|
535
|
-
"--reasoning-effort",
|
|
536
|
-
"--clear-reasoning-effort",
|
|
627
|
+
return table(
|
|
628
|
+
data.map((repo) => ({
|
|
629
|
+
id: String(repo.id),
|
|
630
|
+
repository: repo.full_name,
|
|
631
|
+
branch: repo.default_branch,
|
|
632
|
+
account: repo.installation?.account_login ?? "-",
|
|
633
|
+
linked: repo.linked ? "yes" : "no",
|
|
634
|
+
})),
|
|
537
635
|
);
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
export async function agentsCreate(
|
|
639
|
+
ctx: CliContext,
|
|
640
|
+
name: string | undefined,
|
|
641
|
+
opts: AgentCreateOptions = {},
|
|
642
|
+
): Promise<string> {
|
|
643
|
+
const res = await agentsCreateData(ctx, name, opts);
|
|
644
|
+
if (isAgentLinkGithubResponse(res)) {
|
|
645
|
+
const verb = res.created ? "Linked" : "Re-linked";
|
|
646
|
+
// A sync that could not be queued is a 503 from the server, so it never
|
|
647
|
+
// reaches here: it throws, and the command exits non-zero. Re-running the
|
|
648
|
+
// command is the right retry - the server never stores a 5xx, so a retry
|
|
649
|
+
// re-drives the sync whether it reuses the key or mints a new one.
|
|
650
|
+
return [
|
|
651
|
+
`${verb} ${res.source_repo.github_repository} as ${res.source_repo.slug} ` +
|
|
652
|
+
`(branch ${res.source_repo.deploy_branch}).`,
|
|
653
|
+
"An agent appears after the sync, when the deploy branch has exactly one enabled dharta.toml.",
|
|
654
|
+
"Watch for it with: dharta agent list",
|
|
655
|
+
].join("\n");
|
|
656
|
+
}
|
|
657
|
+
const verb = res.created ? "Created" : "Already exists:";
|
|
658
|
+
return [
|
|
659
|
+
`${verb} ${res.agent.slug} (branch ${res.agent.deploy_branch}).`,
|
|
660
|
+
`Clone: ${res.clone_url}`,
|
|
661
|
+
].join("\n");
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// Exported so the command layer can reject bad input before it costs a request.
|
|
665
|
+
export function validateAgentCreateInput(
|
|
666
|
+
name: string | undefined,
|
|
667
|
+
opts: AgentCreateOptions = {},
|
|
668
|
+
): AgentCreateParams {
|
|
669
|
+
const params: AgentCreateParams = {};
|
|
670
|
+
if (opts.githubRepo !== undefined) {
|
|
671
|
+
// An owner/name is kept as a string and resolved against the installed
|
|
672
|
+
// listing later; a bare number is validated here so a typo costs no request.
|
|
673
|
+
params.githubRepositoryId = opts.githubRepo.includes("/")
|
|
674
|
+
? normalizeGithubFullName(opts.githubRepo)
|
|
675
|
+
: parsePositiveInteger(opts.githubRepo, "--github-repo");
|
|
676
|
+
}
|
|
677
|
+
if (name !== undefined) params.name = normalizeAgentName(name);
|
|
678
|
+
if (params.name === undefined && params.githubRepositoryId === undefined) {
|
|
679
|
+
throw new CliUsageError("Pass a name, or --github-repo <id> to link an installed GitHub repository.");
|
|
545
680
|
}
|
|
546
|
-
if (opts.
|
|
547
|
-
|
|
681
|
+
if (opts.slug !== undefined) params.slug = normalizeAgentSlug(opts.slug);
|
|
682
|
+
if (opts.branch !== undefined) {
|
|
683
|
+
if (opts.githubRepo === undefined) {
|
|
684
|
+
throw new CliUsageError("--branch needs --github-repo: the deploy branch belongs to the linked repository.");
|
|
685
|
+
}
|
|
686
|
+
params.deployBranch = normalizeNonBlank(opts.branch, "--branch");
|
|
548
687
|
}
|
|
688
|
+
return params;
|
|
549
689
|
}
|
|
550
690
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
691
|
+
export interface AgentCreateFromTemplateOptions {
|
|
692
|
+
slug?: string;
|
|
693
|
+
description?: string;
|
|
694
|
+
harness?: string;
|
|
695
|
+
harnessVersion?: string;
|
|
555
696
|
}
|
|
556
697
|
|
|
557
|
-
function
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
698
|
+
export async function agentsCreateFromTemplateData(
|
|
699
|
+
ctx: CliContext,
|
|
700
|
+
template: string,
|
|
701
|
+
name: string,
|
|
702
|
+
opts: AgentCreateFromTemplateOptions = {},
|
|
703
|
+
): Promise<AgentFromTemplateResponse> {
|
|
704
|
+
const params = validateAgentCreateFromTemplateInput(template, name, opts);
|
|
705
|
+
return ctx.sdk.agents.createFromTemplate(params);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
export async function agentsCreateFromTemplate(
|
|
709
|
+
ctx: CliContext,
|
|
710
|
+
template: string,
|
|
711
|
+
name: string,
|
|
712
|
+
opts: AgentCreateFromTemplateOptions = {},
|
|
713
|
+
): Promise<string> {
|
|
714
|
+
const res = await agentsCreateFromTemplateData(ctx, template, name, opts);
|
|
715
|
+
const version = res.release ? `v${res.release.version}` : "the first release";
|
|
716
|
+
const state = res.release?.status === "active" && !res.state
|
|
717
|
+
? `${version} is live.`
|
|
718
|
+
: `${version} is still building - watch it with \`dharta agent releases ${res.agent.slug}\`.`;
|
|
719
|
+
return [
|
|
720
|
+
`Created ${res.agent.slug} from the '${normalizeNonBlank(template, "template")}' template. ${state}`,
|
|
721
|
+
`Clone: ${res.clone_url}`,
|
|
722
|
+
`Open it with: dharta open ${res.agent.slug}`,
|
|
723
|
+
].join("\n");
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// Exported so the command layer can reject bad input before it costs a request.
|
|
727
|
+
export function validateAgentCreateFromTemplateInput(
|
|
728
|
+
template: string,
|
|
729
|
+
name: string,
|
|
730
|
+
opts: AgentCreateFromTemplateOptions = {},
|
|
731
|
+
): AgentFromTemplateParams {
|
|
732
|
+
const params: AgentFromTemplateParams = {
|
|
733
|
+
template: normalizeNonBlank(template, "template"),
|
|
734
|
+
name: normalizeAgentName(name),
|
|
570
735
|
};
|
|
736
|
+
if (opts.slug !== undefined) params.slug = normalizeAgentSlug(opts.slug);
|
|
737
|
+
if (opts.description !== undefined) params.description = normalizeNonBlank(opts.description, "--description");
|
|
738
|
+
if (opts.harness !== undefined) params.harness = normalizeNonBlank(opts.harness, "--harness");
|
|
739
|
+
if (opts.harnessVersion !== undefined) {
|
|
740
|
+
if (opts.harness === undefined) {
|
|
741
|
+
throw new CliUsageError("--harness-version needs --harness: a version belongs to one harness.");
|
|
742
|
+
}
|
|
743
|
+
params.harnessVersion = normalizeNonBlank(opts.harnessVersion, "--harness-version");
|
|
744
|
+
}
|
|
745
|
+
return params;
|
|
571
746
|
}
|
|
572
747
|
|
|
573
|
-
function
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
opts.maxOutputTokens !== undefined || opts.clearMaxOutputTokens === true ||
|
|
577
|
-
opts.reasoningEffort !== undefined || opts.clearReasoningEffort === true;
|
|
748
|
+
export async function agentsRedeployData(ctx: CliContext, slug: string): Promise<AgentDeployResponse> {
|
|
749
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
750
|
+
return ctx.sdk.agents.deploy(normalizedSlug);
|
|
578
751
|
}
|
|
579
752
|
|
|
580
|
-
function
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
if (opts.clearMaxOutputTokens) patch.max_output_tokens = null;
|
|
588
|
-
if (opts.reasoningEffort !== undefined) patch.reasoning_effort = opts.reasoningEffort;
|
|
589
|
-
if (opts.clearReasoningEffort) patch.reasoning_effort = null;
|
|
590
|
-
return patch;
|
|
753
|
+
export async function agentsRedeploy(ctx: CliContext, slug: string): Promise<string> {
|
|
754
|
+
const res = await agentsRedeployData(ctx, slug);
|
|
755
|
+
const repo = res.source_repo.github_repository ?? res.source_repo.slug;
|
|
756
|
+
return [
|
|
757
|
+
`Re-sync queued for ${repo}; ${res.agent.slug} rebuilds from ${res.source_repo.deploy_branch}.`,
|
|
758
|
+
`Watch it with: dharta agent releases ${res.agent.slug}`,
|
|
759
|
+
].join("\n");
|
|
591
760
|
}
|
|
592
761
|
|
|
593
|
-
function
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
exclusiveMinimum: boolean,
|
|
608
|
-
): number {
|
|
609
|
-
const parsed = Number(value);
|
|
610
|
-
const minimumOk = exclusiveMinimum ? parsed > minimum : parsed >= minimum;
|
|
611
|
-
if (!Number.isFinite(parsed) || !minimumOk || parsed > maximum) {
|
|
612
|
-
const lower = exclusiveMinimum ? `greater than ${minimum}` : `at least ${minimum}`;
|
|
613
|
-
throw new Error(`${flag} must be a finite number ${lower} and at most ${maximum}.`);
|
|
614
|
-
}
|
|
615
|
-
return parsed;
|
|
762
|
+
export async function agentsRetryReleaseData(
|
|
763
|
+
ctx: CliContext,
|
|
764
|
+
slug: string,
|
|
765
|
+
version: string,
|
|
766
|
+
): Promise<ReleaseRetryResponse> {
|
|
767
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
768
|
+
const releaseVersion = parseReleaseVersion(version, "release version");
|
|
769
|
+
return ctx.sdk.releases.retry(normalizedSlug, releaseVersion);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
export async function agentsRetryRelease(ctx: CliContext, slug: string, version: string): Promise<string> {
|
|
773
|
+
const res = await agentsRetryReleaseData(ctx, slug, version);
|
|
774
|
+
const state = res.state === "pending" ? "is still building" : "is built";
|
|
775
|
+
return `Retried v${res.retried_release.version} as v${res.release.version}, which ${state}.`;
|
|
616
776
|
}
|
|
617
777
|
|
|
618
|
-
function
|
|
619
|
-
const
|
|
620
|
-
if (
|
|
621
|
-
throw new
|
|
778
|
+
function normalizeGithubFullName(value: string): string {
|
|
779
|
+
const normalized = normalizeNonBlank(value, "--github-repo");
|
|
780
|
+
if (!/^[^/\s]+\/[^/\s]+$/.test(normalized)) {
|
|
781
|
+
throw new CliUsageError("--github-repo must be a repository id or an owner/name, e.g. acme-eng/support-bot.");
|
|
622
782
|
}
|
|
623
|
-
return
|
|
783
|
+
return normalized;
|
|
624
784
|
}
|
|
625
785
|
|
|
626
|
-
function
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
if (normalized.length === 0) throw new Error(`${flag} cannot be blank.`);
|
|
786
|
+
function normalizeAgentName(name: string): string {
|
|
787
|
+
const normalized = normalizeNonBlank(name, "agent name");
|
|
788
|
+
if (normalized.length > 100) throw new CliUsageError("Agent name must be 1-100 characters.");
|
|
630
789
|
return normalized;
|
|
631
790
|
}
|
|
632
791
|
|
|
792
|
+
export async function agentsDeleteData(ctx: CliContext, slug: string): Promise<{ agent: AgentSettingsAgent; archived: boolean }> {
|
|
793
|
+
const normalizedSlug = normalizeAgentSlug(slug);
|
|
794
|
+
return ctx.http.request<{ agent: AgentSettingsAgent; archived: boolean }>({
|
|
795
|
+
method: "DELETE",
|
|
796
|
+
path: `/api/agents/${encodeURIComponent(normalizedSlug)}`,
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
export async function agentsDelete(ctx: CliContext, slug: string): Promise<string> {
|
|
801
|
+
const res = await agentsDeleteData(ctx, slug);
|
|
802
|
+
return `Archived ${res.agent.slug}.`;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
function validateModelSetOptions(opts: AgentModelSetOptions): void {
|
|
806
|
+
const hasConnector = opts.connector !== undefined;
|
|
807
|
+
const hasModelRef = opts.modelRef !== undefined;
|
|
808
|
+
const hasParameters = modelParameterOptionPresent(opts);
|
|
809
|
+
|
|
810
|
+
if (!hasConnector && !hasModelRef && !hasParameters) {
|
|
811
|
+
throw new CliUsageError(
|
|
812
|
+
"Pass at least one connector option, model reference option, or parameter option.",
|
|
813
|
+
);
|
|
814
|
+
}
|
|
815
|
+
if (hasConnector) parseConnectorOrder(opts.connector as string, "--connector");
|
|
816
|
+
if (hasModelRef) normalizeModelReference(opts.modelRef as string, "--model-ref");
|
|
817
|
+
validateModelParameterOptions(opts);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
function normalizeModelSetOptions(opts: AgentModelSetOptions): AgentModelSetOptions {
|
|
821
|
+
return {
|
|
822
|
+
...normalizeModelParameterOptions(opts),
|
|
823
|
+
// `--connector ""` and `--model-ref ""` are meaningful: an empty
|
|
824
|
+
// connector order inherits from the organization, and an empty model
|
|
825
|
+
// reference falls back to the connector default.
|
|
826
|
+
connector: opts.connector?.trim(),
|
|
827
|
+
modelRef: opts.modelRef?.trim(),
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
|
|
633
831
|
function normalizeAgentSlug(slug: string): string {
|
|
634
832
|
return validateAgentSlug(slug, "agent slug");
|
|
635
833
|
}
|