1import * as Schema from "effect/Schema";
2
3import { ThreadId, TrimmedNonEmptyString, TurnItemId } from "./baseSchemas.ts";
4
5/**
6 * The user's answer to an agent's request for a secret. A saved value is kept
7 * by the server under a one-use SecretRef; the thread learns only the status.
8 */
9export const SecretRequestAnswerInput = Schema.Struct({
10 threadId: ThreadId,
11 turnItemId: TurnItemId,
12 answer: Schema.Union([
13 Schema.Struct({ type: Schema.Literal("save"), secret: TrimmedNonEmptyString }),
14 Schema.Struct({ type: Schema.Literal("decline") }),
15 ]),
16});
17export type SecretRequestAnswerInput = typeof SecretRequestAnswerInput.Type;
18
19const SECRET_REQUEST_FAILURE_MESSAGES = {
20 load_failed: "Could not load the secret request.",
21 not_found: "This secret request no longer exists.",
22 already_answered: "This secret request was already answered.",
23 agent_stopped: "The agent that asked has stopped, so this secret can't be used.",
24 store_failed: "Could not store the secret.",
25 record_failed: "Saved the secret, but could not update the request.",
26 invalid_ref: "That secretRef is not valid.",
27 read_failed: "Could not read the secret.",
28 ref_unavailable:
29 "That secretRef was already used or does not exist. Ask the user again with request_secret.",
30 ref_expired: "That secretRef expired. Ask the user again with request_secret.",
31 consume_failed: "Could not use that secretRef. Try again.",
32} as const;
33
34export const SecretRequestFailureReason = Schema.Literals(
35 Object.keys(SECRET_REQUEST_FAILURE_MESSAGES) as Array<
36 keyof typeof SECRET_REQUEST_FAILURE_MESSAGES
37 >,
38);
39export type SecretRequestFailureReason = typeof SecretRequestFailureReason.Type;
40
41/** Answering a request or using its ref failed; the message is shown to users and agents. */
42export class SecretRequestError extends Schema.TaggedError<SecretRequestError>()(
43 "SecretRequestError",
44 {
45 reason: SecretRequestFailureReason,
46 cause: Schema.optionalKey(Schema.Defect()),
47 },
48) {
49 override get message(): string {
50 return SECRET_REQUEST_FAILURE_MESSAGES[this.reason];
51 }
52}