@alpacakit/agents-conventions 0.1.0-beta.36 → 0.1.0-beta.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -10
- package/dist/cli-output.d.ts +209 -0
- package/dist/cli-output.d.ts.map +1 -0
- package/dist/cli-output.js +208 -0
- package/dist/cli.d.ts +186 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +307 -0
- package/dist/home.d.ts +65 -0
- package/dist/home.d.ts.map +1 -0
- package/dist/home.js +105 -0
- package/dist/index.d.ts +23 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -56
- package/dist/names.d.ts +38 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +41 -0
- package/dist/paths.d.ts +41 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +72 -0
- package/dist/register.d.ts +122 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +212 -0
- package/dist/remove.d.ts +40 -0
- package/dist/remove.d.ts.map +1 -0
- package/dist/remove.js +73 -0
- package/dist/values.d.ts +30 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +28 -0
- package/package.json +15 -4
package/README.md
CHANGED
|
@@ -1,12 +1,119 @@
|
|
|
1
1
|
# @alpacakit/agents-conventions
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
3
|
+
The AlpacaKit family's **shared agents home**: where it lives, how an agent is
|
|
4
|
+
registered into it, and the `agent` command every family product mounts.
|
|
5
|
+
|
|
6
|
+
This lives outside the neutral [`@alpacakit/agents`](../agents) package on
|
|
7
|
+
purpose. It encodes the family's `ALPACA_AGENTS_HOME` / `~/.alpaca/agents`
|
|
8
|
+
config root, the `alpaca.agents` keychain service, the managed-home layout, and
|
|
9
|
+
— the part that matters most — the **order and failure policy** of registering
|
|
10
|
+
a credential. It is a plain consumer of the agents package's public API: the
|
|
11
|
+
same shape any third party would write for their own convention. The general
|
|
12
|
+
library ships a convention-neutral `@alpacakit/agents/config/xdg` preset; this
|
|
13
|
+
package is the AlpacaKit-specific instance.
|
|
14
|
+
|
|
15
|
+
## Procedures
|
|
16
|
+
|
|
17
|
+
Every procedure takes `{ homeDir, env }` and opens the same shared home.
|
|
18
|
+
`ports` and `keyring` are injectable so tests drive the real path without a
|
|
19
|
+
subprocess or a real keychain. Expected outcomes come back as a result type
|
|
20
|
+
with a `kind`; only faults throw.
|
|
21
|
+
|
|
22
|
+
| Procedure | Result kinds |
|
|
23
|
+
|---|---|
|
|
24
|
+
| `listAgentsHome` | `{ agentsHome, entries }` — every candidate with its readiness |
|
|
25
|
+
| `loginManagedHome` | `registered` / `profile_exists` / `unknown_agent` / `unsupported` / `login_failed` |
|
|
26
|
+
| `addApiKeyProfile` | `registered` / `profile_exists` / `empty_key` |
|
|
27
|
+
| `addAgentConfig` | `added` / `exists` |
|
|
28
|
+
| `removeAgentsHomeEntry` | `removed_profile` / `removed_agent_config` / `not_found` |
|
|
29
|
+
|
|
30
|
+
Every procedure that takes a record name can also answer `invalid_name`
|
|
31
|
+
(carrying the `rule` in words, so a product need not restate the grammar).
|
|
32
|
+
|
|
33
|
+
The policies these procedures own, so no product re-decides them:
|
|
34
|
+
|
|
35
|
+
- **`listAgentsHome`** probes a profile-backed candidate with that profile's
|
|
36
|
+
environment applied — the same `auth.toEnv` patch a run gets — so it can
|
|
37
|
+
never report the ambient login for a profile that has its own credential. An
|
|
38
|
+
agent that declares no availability probe reports `null`, not a guess.
|
|
39
|
+
- **`loginManagedHome`** writes no profile when the sign-in fails, but keeps
|
|
40
|
+
the managed home so a retry resumes from it. A sign-in that succeeds and then
|
|
41
|
+
cannot be recorded is a **fault**, not a result: discarding a completed
|
|
42
|
+
browser flow would leave a live credential nobody knows about. An id this
|
|
43
|
+
home does not have (`unknown_agent`) is kept apart from a method the agent
|
|
44
|
+
does not offer (`unsupported`) — the two have different fixes.
|
|
45
|
+
- **`addApiKeyProfile`** rejects a blank key (`empty_key`) before touching the
|
|
46
|
+
keychain, stores the key trimmed so a piped newline never reaches the
|
|
47
|
+
provider, then references it — and removes the stored key again if the
|
|
48
|
+
reference cannot be written.
|
|
49
|
+
- **`addAgentConfig`** dispatches on `input.kind`, the same discriminator
|
|
50
|
+
`agent add --kind` carries, so the CLI projection is the input verbatim.
|
|
51
|
+
- **Record names** (profile ids, agent config ids) match
|
|
52
|
+
`^[a-z0-9][a-z0-9._-]{0,63}$`. A name is not free text: it becomes a path
|
|
53
|
+
segment under `managed-homes/` and a segment of a keychain account, so an
|
|
54
|
+
unconstrained one would decide where this package writes and what it deletes.
|
|
55
|
+
`/cli` rejects it at the codec and the procedures repeat the check for
|
|
56
|
+
callers that skip the CLI; `resolveManagedHomePath` throws rather than build
|
|
57
|
+
a path outside the shared home.
|
|
58
|
+
- **`removeAgentsHomeEntry`** removes the record first, then only the artifacts
|
|
59
|
+
this package created. A home the operator pointed at themselves, and a secret
|
|
60
|
+
behind someone else's resolver, are left alone.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { loginManagedHome } from "@alpacakit/agents-conventions";
|
|
64
|
+
|
|
65
|
+
const result = await loginManagedHome({
|
|
66
|
+
homeDir: os.homedir(),
|
|
67
|
+
env: process.env,
|
|
68
|
+
profileId: "judge-codex",
|
|
69
|
+
agentId: "codex",
|
|
70
|
+
method: "oauth",
|
|
71
|
+
onEvent: (event) => render(event),
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## `@alpacakit/agents-conventions/cli`
|
|
76
|
+
|
|
77
|
+
The `agent` command surface, as **data** — no `bin`, no handler, no I/O. It
|
|
78
|
+
owns the command paths, the flags, the projection into a procedure input, and
|
|
79
|
+
the JSON each result must be, so `alpacaloop agent login` and
|
|
80
|
+
`promptopt agent login` are the same command.
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
agent list
|
|
84
|
+
agent login <PROFILE> --agent <claude|codex> [--method oauth|device]
|
|
85
|
+
agent credential add <PROFILE> --agent <ID> --stdin (--stdin is required)
|
|
86
|
+
agent add <ID> --kind openai-compatible --base-url <URL> --model <M>
|
|
87
|
+
[--api-key-env <VAR>] [--engine fetch|pi]
|
|
88
|
+
agent remove <NAME>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Mount the node in the product's tree and bind a handler per endpoint — call the
|
|
92
|
+
procedure, render the result:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { AGENT_CLI_SURFACE } from "@alpacakit/agents-conventions/cli";
|
|
96
|
+
import { loginManagedHome } from "@alpacakit/agents-conventions";
|
|
97
|
+
import { handleCliEndpoint } from "@alpacakit/channels/cli";
|
|
98
|
+
|
|
99
|
+
// 1. mount: put AGENT_CLI_SURFACE.node among the product root's children.
|
|
100
|
+
// 2. bind:
|
|
101
|
+
handleCliEndpoint(AGENT_CLI_SURFACE.endpoints.login, async ({ projection }) =>
|
|
102
|
+
render(await loginManagedHome({ ...projection, homeDir, env })),
|
|
103
|
+
);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Each endpoint's projection is the matching procedure's input verbatim, so the
|
|
107
|
+
handler never re-maps fields: `endpoints.add` projects `{ kind, id, baseUrl,
|
|
108
|
+
model, apiKeyEnv?, engine? }` straight into `addAgentConfig`. Optional flags
|
|
109
|
+
stay absent when unset — `--engine` is defaulted once, by the agent-config
|
|
110
|
+
payload that persists it, never a second time by the command surface. The addable kinds
|
|
111
|
+
(`AGENT_ADD_KIND`) live on the root export, next to the procedure that acts on
|
|
112
|
+
them — `/cli` only spells them as a flag.
|
|
113
|
+
|
|
114
|
+
`AGENT_CLI_SURFACE.outputs` carries the same contracts for products that emit
|
|
115
|
+
machine-readable output.
|
|
116
|
+
|
|
117
|
+
`@alpacakit/channels` and `zod` are **peer** dependencies of this package: they
|
|
118
|
+
are needed only by `/cli`, so importing the procedures never drags a CLI
|
|
119
|
+
framework in.
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The JSON shape of every `agent` command result. These are the CONTRACT, not
|
|
3
|
+
* a convenience: an app may render the result any way it likes, but what it
|
|
4
|
+
* emits as data is fixed here so `alpacaloop agent list --json` and
|
|
5
|
+
* `promptopt agent list --json` are the same document.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
export declare const profileSchema: z.ZodObject<{
|
|
9
|
+
id: z.ZodString;
|
|
10
|
+
agentId: z.ZodString;
|
|
11
|
+
material: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
12
|
+
kind: z.ZodLiteral<"home-dir">;
|
|
13
|
+
path: z.ZodString;
|
|
14
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
15
|
+
kind: z.ZodLiteral<"api-key">;
|
|
16
|
+
secret: z.ZodObject<{
|
|
17
|
+
resolver: z.ZodString;
|
|
18
|
+
id: z.ZodString;
|
|
19
|
+
}, z.core.$strict>;
|
|
20
|
+
}, z.core.$strict>], "kind">;
|
|
21
|
+
}, z.core.$strict>;
|
|
22
|
+
export declare const agentConfigSchema: z.ZodObject<{
|
|
23
|
+
id: z.ZodString;
|
|
24
|
+
kind: z.ZodString;
|
|
25
|
+
enabled: z.ZodBoolean;
|
|
26
|
+
payload: z.ZodRecord<z.ZodString, z.ZodType<import("@alpacakit/agents").JsonValue, unknown, z.core.$ZodTypeInternals<import("@alpacakit/agents").JsonValue, unknown>>>;
|
|
27
|
+
}, z.core.$strict>;
|
|
28
|
+
/** `null` when the agent declares no availability probe at all. */
|
|
29
|
+
export declare const availabilitySchema: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
30
|
+
status: z.ZodLiteral<"runnable">;
|
|
31
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
32
|
+
status: z.ZodLiteral<"unavailable">;
|
|
33
|
+
reason: z.ZodEnum<{
|
|
34
|
+
command_missing: "command_missing";
|
|
35
|
+
authentication_required: "authentication_required";
|
|
36
|
+
}>;
|
|
37
|
+
remediation: z.ZodNullable<z.ZodObject<{
|
|
38
|
+
detail: z.ZodString;
|
|
39
|
+
command: z.ZodNullable<z.ZodObject<{
|
|
40
|
+
executable: z.ZodString;
|
|
41
|
+
args: z.ZodArray<z.ZodString>;
|
|
42
|
+
}, z.core.$strict>>;
|
|
43
|
+
}, z.core.$strict>>;
|
|
44
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
45
|
+
status: z.ZodLiteral<"indeterminate">;
|
|
46
|
+
reason: z.ZodEnum<{
|
|
47
|
+
probe_timeout: "probe_timeout";
|
|
48
|
+
probe_fault: "probe_fault";
|
|
49
|
+
}>;
|
|
50
|
+
detail: z.ZodString;
|
|
51
|
+
}, z.core.$strict>], "status">>;
|
|
52
|
+
export declare const agentListOutputSchema: z.ZodObject<{
|
|
53
|
+
agentsHome: z.ZodString;
|
|
54
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
55
|
+
agentId: z.ZodString;
|
|
56
|
+
agentConfigId: z.ZodString;
|
|
57
|
+
kind: z.ZodString;
|
|
58
|
+
source: z.ZodEnum<{
|
|
59
|
+
profile: "profile";
|
|
60
|
+
ambient: "ambient";
|
|
61
|
+
configured: "configured";
|
|
62
|
+
}>;
|
|
63
|
+
profileId: z.ZodNullable<z.ZodString>;
|
|
64
|
+
availability: z.ZodNullable<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
65
|
+
status: z.ZodLiteral<"runnable">;
|
|
66
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
67
|
+
status: z.ZodLiteral<"unavailable">;
|
|
68
|
+
reason: z.ZodEnum<{
|
|
69
|
+
command_missing: "command_missing";
|
|
70
|
+
authentication_required: "authentication_required";
|
|
71
|
+
}>;
|
|
72
|
+
remediation: z.ZodNullable<z.ZodObject<{
|
|
73
|
+
detail: z.ZodString;
|
|
74
|
+
command: z.ZodNullable<z.ZodObject<{
|
|
75
|
+
executable: z.ZodString;
|
|
76
|
+
args: z.ZodArray<z.ZodString>;
|
|
77
|
+
}, z.core.$strict>>;
|
|
78
|
+
}, z.core.$strict>>;
|
|
79
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
80
|
+
status: z.ZodLiteral<"indeterminate">;
|
|
81
|
+
reason: z.ZodEnum<{
|
|
82
|
+
probe_timeout: "probe_timeout";
|
|
83
|
+
probe_fault: "probe_fault";
|
|
84
|
+
}>;
|
|
85
|
+
detail: z.ZodString;
|
|
86
|
+
}, z.core.$strict>], "status">>;
|
|
87
|
+
}, z.core.$strict>>;
|
|
88
|
+
}, z.core.$strict>;
|
|
89
|
+
export declare const agentLoginOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
90
|
+
kind: z.ZodLiteral<"registered">;
|
|
91
|
+
profile: z.ZodObject<{
|
|
92
|
+
id: z.ZodString;
|
|
93
|
+
agentId: z.ZodString;
|
|
94
|
+
material: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
95
|
+
kind: z.ZodLiteral<"home-dir">;
|
|
96
|
+
path: z.ZodString;
|
|
97
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
98
|
+
kind: z.ZodLiteral<"api-key">;
|
|
99
|
+
secret: z.ZodObject<{
|
|
100
|
+
resolver: z.ZodString;
|
|
101
|
+
id: z.ZodString;
|
|
102
|
+
}, z.core.$strict>;
|
|
103
|
+
}, z.core.$strict>], "kind">;
|
|
104
|
+
}, z.core.$strict>;
|
|
105
|
+
managedHome: z.ZodString;
|
|
106
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
107
|
+
kind: z.ZodLiteral<"profile_exists">;
|
|
108
|
+
profileId: z.ZodString;
|
|
109
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
110
|
+
kind: z.ZodLiteral<"unknown_agent">;
|
|
111
|
+
agentId: z.ZodString;
|
|
112
|
+
known: z.ZodArray<z.ZodString>;
|
|
113
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
114
|
+
kind: z.ZodLiteral<"unsupported">;
|
|
115
|
+
agentId: z.ZodString;
|
|
116
|
+
method: z.ZodString;
|
|
117
|
+
supported: z.ZodArray<z.ZodString>;
|
|
118
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
119
|
+
kind: z.ZodLiteral<"login_failed">;
|
|
120
|
+
detail: z.ZodString;
|
|
121
|
+
managedHome: z.ZodString;
|
|
122
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
123
|
+
kind: z.ZodLiteral<"invalid_name">;
|
|
124
|
+
name: z.ZodString;
|
|
125
|
+
rule: z.ZodString;
|
|
126
|
+
}, z.core.$strict>], "kind">;
|
|
127
|
+
export declare const agentCredentialAddOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
128
|
+
kind: z.ZodLiteral<"registered">;
|
|
129
|
+
profile: z.ZodObject<{
|
|
130
|
+
id: z.ZodString;
|
|
131
|
+
agentId: z.ZodString;
|
|
132
|
+
material: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
133
|
+
kind: z.ZodLiteral<"home-dir">;
|
|
134
|
+
path: z.ZodString;
|
|
135
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
136
|
+
kind: z.ZodLiteral<"api-key">;
|
|
137
|
+
secret: z.ZodObject<{
|
|
138
|
+
resolver: z.ZodString;
|
|
139
|
+
id: z.ZodString;
|
|
140
|
+
}, z.core.$strict>;
|
|
141
|
+
}, z.core.$strict>], "kind">;
|
|
142
|
+
}, z.core.$strict>;
|
|
143
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
144
|
+
kind: z.ZodLiteral<"profile_exists">;
|
|
145
|
+
profileId: z.ZodString;
|
|
146
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
147
|
+
kind: z.ZodLiteral<"empty_key">;
|
|
148
|
+
profileId: z.ZodString;
|
|
149
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
150
|
+
kind: z.ZodLiteral<"invalid_name">;
|
|
151
|
+
name: z.ZodString;
|
|
152
|
+
rule: z.ZodString;
|
|
153
|
+
}, z.core.$strict>], "kind">;
|
|
154
|
+
export declare const agentAddOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
155
|
+
kind: z.ZodLiteral<"added">;
|
|
156
|
+
agentConfig: z.ZodObject<{
|
|
157
|
+
id: z.ZodString;
|
|
158
|
+
kind: z.ZodString;
|
|
159
|
+
enabled: z.ZodBoolean;
|
|
160
|
+
payload: z.ZodRecord<z.ZodString, z.ZodType<import("@alpacakit/agents").JsonValue, unknown, z.core.$ZodTypeInternals<import("@alpacakit/agents").JsonValue, unknown>>>;
|
|
161
|
+
}, z.core.$strict>;
|
|
162
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
163
|
+
kind: z.ZodLiteral<"exists">;
|
|
164
|
+
id: z.ZodString;
|
|
165
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
166
|
+
kind: z.ZodLiteral<"invalid_name">;
|
|
167
|
+
name: z.ZodString;
|
|
168
|
+
rule: z.ZodString;
|
|
169
|
+
}, z.core.$strict>], "kind">;
|
|
170
|
+
export declare const agentRemoveOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
171
|
+
kind: z.ZodLiteral<"removed_profile">;
|
|
172
|
+
profile: z.ZodObject<{
|
|
173
|
+
id: z.ZodString;
|
|
174
|
+
agentId: z.ZodString;
|
|
175
|
+
material: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
176
|
+
kind: z.ZodLiteral<"home-dir">;
|
|
177
|
+
path: z.ZodString;
|
|
178
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
179
|
+
kind: z.ZodLiteral<"api-key">;
|
|
180
|
+
secret: z.ZodObject<{
|
|
181
|
+
resolver: z.ZodString;
|
|
182
|
+
id: z.ZodString;
|
|
183
|
+
}, z.core.$strict>;
|
|
184
|
+
}, z.core.$strict>], "kind">;
|
|
185
|
+
}, z.core.$strict>;
|
|
186
|
+
removedManagedHome: z.ZodNullable<z.ZodString>;
|
|
187
|
+
removedSecret: z.ZodBoolean;
|
|
188
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
189
|
+
kind: z.ZodLiteral<"removed_agent_config">;
|
|
190
|
+
agentConfig: z.ZodObject<{
|
|
191
|
+
id: z.ZodString;
|
|
192
|
+
kind: z.ZodString;
|
|
193
|
+
enabled: z.ZodBoolean;
|
|
194
|
+
payload: z.ZodRecord<z.ZodString, z.ZodType<import("@alpacakit/agents").JsonValue, unknown, z.core.$ZodTypeInternals<import("@alpacakit/agents").JsonValue, unknown>>>;
|
|
195
|
+
}, z.core.$strict>;
|
|
196
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
197
|
+
kind: z.ZodLiteral<"not_found">;
|
|
198
|
+
name: z.ZodString;
|
|
199
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
200
|
+
kind: z.ZodLiteral<"invalid_name">;
|
|
201
|
+
name: z.ZodString;
|
|
202
|
+
rule: z.ZodString;
|
|
203
|
+
}, z.core.$strict>], "kind">;
|
|
204
|
+
export type AgentListOutput = z.infer<typeof agentListOutputSchema>;
|
|
205
|
+
export type AgentLoginOutput = z.infer<typeof agentLoginOutputSchema>;
|
|
206
|
+
export type AgentCredentialAddOutput = z.infer<typeof agentCredentialAddOutputSchema>;
|
|
207
|
+
export type AgentAddOutput = z.infer<typeof agentAddOutputSchema>;
|
|
208
|
+
export type AgentRemoveOutput = z.infer<typeof agentRemoveOutputSchema>;
|
|
209
|
+
//# sourceMappingURL=cli-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-output.d.ts","sourceRoot":"","sources":["../src/cli-output.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA+BxB,eAAO,MAAM,aAAa;;;;;;;;;;;;;kBAMf,CAAC;AAEZ,eAAO,MAAM,iBAAiB;;;;;kBAOnB,CAAC;AAYZ,mEAAmE;AACnE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;+BA0BlB,CAAC;AAWd,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoBvB,CAAC;AAEZ,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAwClC,CAAC;AAEF,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;4BAuB1C,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;4BAc/B,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAyBnC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACtE,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAC5C,OAAO,8BAA8B,CACtC,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The JSON shape of every `agent` command result. These are the CONTRACT, not
|
|
3
|
+
* a convenience: an app may render the result any way it likes, but what it
|
|
4
|
+
* emits as data is fixed here so `alpacaloop agent list --json` and
|
|
5
|
+
* `promptopt agent list --json` are the same document.
|
|
6
|
+
*/
|
|
7
|
+
import { AGENT_AVAILABILITY_STATUS, AGENT_INDETERMINATE_REASON, AGENT_UNAVAILABLE_REASON, AUTH_MATERIAL_KIND, } from "@alpacakit/agents";
|
|
8
|
+
import { CANDIDATE_SOURCE_KIND } from "@alpacakit/agents/config";
|
|
9
|
+
import { jsonValueSchema } from "@alpacakit/core";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { ADD_AGENT_CONFIG_RESULT, ADD_API_KEY_PROFILE_RESULT, LOGIN_MANAGED_HOME_RESULT, } from "./register.js";
|
|
12
|
+
import { INVALID_NAME_RESULT_KIND } from "./names.js";
|
|
13
|
+
import { REMOVE_AGENTS_HOME_ENTRY_RESULT } from "./remove.js";
|
|
14
|
+
const RESULT_DISCRIMINATOR = "kind";
|
|
15
|
+
const AVAILABILITY_DISCRIMINATOR = "status";
|
|
16
|
+
const secretRefSchema = z
|
|
17
|
+
.object({ resolver: z.string(), id: z.string() })
|
|
18
|
+
.strict();
|
|
19
|
+
const authMaterialSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
|
|
20
|
+
z
|
|
21
|
+
.object({
|
|
22
|
+
kind: z.literal(AUTH_MATERIAL_KIND.homeDir),
|
|
23
|
+
path: z.string(),
|
|
24
|
+
})
|
|
25
|
+
.strict(),
|
|
26
|
+
z
|
|
27
|
+
.object({
|
|
28
|
+
kind: z.literal(AUTH_MATERIAL_KIND.apiKey),
|
|
29
|
+
secret: secretRefSchema,
|
|
30
|
+
})
|
|
31
|
+
.strict(),
|
|
32
|
+
]);
|
|
33
|
+
export const profileSchema = z
|
|
34
|
+
.object({
|
|
35
|
+
id: z.string(),
|
|
36
|
+
agentId: z.string(),
|
|
37
|
+
material: authMaterialSchema,
|
|
38
|
+
})
|
|
39
|
+
.strict();
|
|
40
|
+
export const agentConfigSchema = z
|
|
41
|
+
.object({
|
|
42
|
+
id: z.string(),
|
|
43
|
+
kind: z.string(),
|
|
44
|
+
enabled: z.boolean(),
|
|
45
|
+
payload: z.record(z.string(), jsonValueSchema),
|
|
46
|
+
})
|
|
47
|
+
.strict();
|
|
48
|
+
const remediationSchema = z
|
|
49
|
+
.object({
|
|
50
|
+
detail: z.string(),
|
|
51
|
+
command: z
|
|
52
|
+
.object({ executable: z.string(), args: z.array(z.string()) })
|
|
53
|
+
.strict()
|
|
54
|
+
.nullable(),
|
|
55
|
+
})
|
|
56
|
+
.strict();
|
|
57
|
+
/** `null` when the agent declares no availability probe at all. */
|
|
58
|
+
export const availabilitySchema = z
|
|
59
|
+
.discriminatedUnion(AVAILABILITY_DISCRIMINATOR, [
|
|
60
|
+
z
|
|
61
|
+
.object({ status: z.literal(AGENT_AVAILABILITY_STATUS.runnable) })
|
|
62
|
+
.strict(),
|
|
63
|
+
z
|
|
64
|
+
.object({
|
|
65
|
+
status: z.literal(AGENT_AVAILABILITY_STATUS.unavailable),
|
|
66
|
+
reason: z.enum([
|
|
67
|
+
AGENT_UNAVAILABLE_REASON.commandMissing,
|
|
68
|
+
AGENT_UNAVAILABLE_REASON.authenticationRequired,
|
|
69
|
+
]),
|
|
70
|
+
remediation: remediationSchema.nullable(),
|
|
71
|
+
})
|
|
72
|
+
.strict(),
|
|
73
|
+
z
|
|
74
|
+
.object({
|
|
75
|
+
status: z.literal(AGENT_AVAILABILITY_STATUS.indeterminate),
|
|
76
|
+
reason: z.enum([
|
|
77
|
+
AGENT_INDETERMINATE_REASON.probeTimeout,
|
|
78
|
+
AGENT_INDETERMINATE_REASON.probeFault,
|
|
79
|
+
]),
|
|
80
|
+
detail: z.string(),
|
|
81
|
+
})
|
|
82
|
+
.strict(),
|
|
83
|
+
])
|
|
84
|
+
.nullable();
|
|
85
|
+
/** The rejection every name-taking command shares (`InvalidNameResult`). */
|
|
86
|
+
const invalidNameSchema = z
|
|
87
|
+
.object({
|
|
88
|
+
kind: z.literal(INVALID_NAME_RESULT_KIND),
|
|
89
|
+
name: z.string(),
|
|
90
|
+
rule: z.string(),
|
|
91
|
+
})
|
|
92
|
+
.strict();
|
|
93
|
+
export const agentListOutputSchema = z
|
|
94
|
+
.object({
|
|
95
|
+
agentsHome: z.string(),
|
|
96
|
+
entries: z.array(z
|
|
97
|
+
.object({
|
|
98
|
+
agentId: z.string(),
|
|
99
|
+
agentConfigId: z.string(),
|
|
100
|
+
kind: z.string(),
|
|
101
|
+
source: z.enum([
|
|
102
|
+
CANDIDATE_SOURCE_KIND.profile,
|
|
103
|
+
CANDIDATE_SOURCE_KIND.ambient,
|
|
104
|
+
CANDIDATE_SOURCE_KIND.configured,
|
|
105
|
+
]),
|
|
106
|
+
profileId: z.string().nullable(),
|
|
107
|
+
availability: availabilitySchema,
|
|
108
|
+
})
|
|
109
|
+
.strict()),
|
|
110
|
+
})
|
|
111
|
+
.strict();
|
|
112
|
+
export const agentLoginOutputSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
|
|
113
|
+
z
|
|
114
|
+
.object({
|
|
115
|
+
kind: z.literal(LOGIN_MANAGED_HOME_RESULT.registered),
|
|
116
|
+
profile: profileSchema,
|
|
117
|
+
managedHome: z.string(),
|
|
118
|
+
})
|
|
119
|
+
.strict(),
|
|
120
|
+
z
|
|
121
|
+
.object({
|
|
122
|
+
kind: z.literal(LOGIN_MANAGED_HOME_RESULT.profileExists),
|
|
123
|
+
profileId: z.string(),
|
|
124
|
+
})
|
|
125
|
+
.strict(),
|
|
126
|
+
z
|
|
127
|
+
.object({
|
|
128
|
+
kind: z.literal(LOGIN_MANAGED_HOME_RESULT.unknownAgent),
|
|
129
|
+
agentId: z.string(),
|
|
130
|
+
known: z.array(z.string()),
|
|
131
|
+
})
|
|
132
|
+
.strict(),
|
|
133
|
+
z
|
|
134
|
+
.object({
|
|
135
|
+
kind: z.literal(LOGIN_MANAGED_HOME_RESULT.unsupported),
|
|
136
|
+
agentId: z.string(),
|
|
137
|
+
method: z.string(),
|
|
138
|
+
supported: z.array(z.string()),
|
|
139
|
+
})
|
|
140
|
+
.strict(),
|
|
141
|
+
z
|
|
142
|
+
.object({
|
|
143
|
+
kind: z.literal(LOGIN_MANAGED_HOME_RESULT.loginFailed),
|
|
144
|
+
detail: z.string(),
|
|
145
|
+
managedHome: z.string(),
|
|
146
|
+
})
|
|
147
|
+
.strict(),
|
|
148
|
+
invalidNameSchema,
|
|
149
|
+
]);
|
|
150
|
+
export const agentCredentialAddOutputSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
|
|
151
|
+
z
|
|
152
|
+
.object({
|
|
153
|
+
kind: z.literal(ADD_API_KEY_PROFILE_RESULT.registered),
|
|
154
|
+
profile: profileSchema,
|
|
155
|
+
})
|
|
156
|
+
.strict(),
|
|
157
|
+
z
|
|
158
|
+
.object({
|
|
159
|
+
kind: z.literal(ADD_API_KEY_PROFILE_RESULT.profileExists),
|
|
160
|
+
profileId: z.string(),
|
|
161
|
+
})
|
|
162
|
+
.strict(),
|
|
163
|
+
z
|
|
164
|
+
.object({
|
|
165
|
+
kind: z.literal(ADD_API_KEY_PROFILE_RESULT.emptyKey),
|
|
166
|
+
profileId: z.string(),
|
|
167
|
+
})
|
|
168
|
+
.strict(),
|
|
169
|
+
invalidNameSchema,
|
|
170
|
+
]);
|
|
171
|
+
export const agentAddOutputSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
|
|
172
|
+
z
|
|
173
|
+
.object({
|
|
174
|
+
kind: z.literal(ADD_AGENT_CONFIG_RESULT.added),
|
|
175
|
+
agentConfig: agentConfigSchema,
|
|
176
|
+
})
|
|
177
|
+
.strict(),
|
|
178
|
+
z
|
|
179
|
+
.object({
|
|
180
|
+
kind: z.literal(ADD_AGENT_CONFIG_RESULT.exists),
|
|
181
|
+
id: z.string(),
|
|
182
|
+
})
|
|
183
|
+
.strict(),
|
|
184
|
+
invalidNameSchema,
|
|
185
|
+
]);
|
|
186
|
+
export const agentRemoveOutputSchema = z.discriminatedUnion(RESULT_DISCRIMINATOR, [
|
|
187
|
+
z
|
|
188
|
+
.object({
|
|
189
|
+
kind: z.literal(REMOVE_AGENTS_HOME_ENTRY_RESULT.removedProfile),
|
|
190
|
+
profile: profileSchema,
|
|
191
|
+
removedManagedHome: z.string().nullable(),
|
|
192
|
+
removedSecret: z.boolean(),
|
|
193
|
+
})
|
|
194
|
+
.strict(),
|
|
195
|
+
z
|
|
196
|
+
.object({
|
|
197
|
+
kind: z.literal(REMOVE_AGENTS_HOME_ENTRY_RESULT.removedAgentConfig),
|
|
198
|
+
agentConfig: agentConfigSchema,
|
|
199
|
+
})
|
|
200
|
+
.strict(),
|
|
201
|
+
z
|
|
202
|
+
.object({
|
|
203
|
+
kind: z.literal(REMOVE_AGENTS_HOME_ENTRY_RESULT.notFound),
|
|
204
|
+
name: z.string(),
|
|
205
|
+
})
|
|
206
|
+
.strict(),
|
|
207
|
+
invalidNameSchema,
|
|
208
|
+
]);
|