/** * `interview`: a conversation with the *user*, ending in a brief. * * Every other combinator here composes agents. This one puts a human in the * loop: an agent asks one question at a time through the {@link AskUser} port, * and turns the answers into the specification the rest of the pipeline works * from. * * Why one question at a time rather than a form: a good second question depends * on the first answer. A form has to guess all of them up front, and guesses * wrong the moment the first answer surprises it. */ import type { Agent } from "./../agent.ts"; import type { Answer, AskUser, Question } from "./../ask.ts"; import type { WorkflowResult } from "./../result.ts"; import type { WorkflowOptions } from "./options.ts"; /** The agent says this - alone - when it has enough to write the brief. */ export declare const READY = "READY"; /** Who asks, what about, how it reaches the user, and when it must stop. */ export type InterviewOptions = WorkflowOptions & { /** The agent conducting the interview. */ agent: Agent; /** What the user asked for, in their own words. */ input: string; /** How questions reach the user. See {@link AskUser}. */ ask: AskUser; /** * Hard cap on questions. Defaults to 6. * * The same reasoning as `loop`'s `maxIterations`, with a human on the other * end: an agent that keeps finding one more thing to clarify is the normal * failure mode, and being interrogated forever is worse than a slightly * under-specified brief. */ maxQuestions?: number; /** Overrides how a question is read. See {@link parseQuestion}. */ parse?: (output: string) => Question | undefined; }; /** * The brief, and everything that led to it. * * As a `Result`: the interviewer's last turn, whose `output` is the brief. * `usage` covers every turn, the brief included; `ok` says every turn ran, and * a short brief can still be `true`. */ export type InterviewResult = WorkflowResult & { /** The consolidated specification - `output`, under the name the rest of the pipeline reads. */ brief: string; /** Everything the user answered, in order. */ answers: Answer[]; /** True when the user submitted before the agent said it was done. */ submitted: boolean; }; /** * Interviews the user, then asks the agent to write the brief. * * The lifetime defaults to `"workflow"`, and that is not an arbitrary choice: an * interview *is* a conversation. A `"task"` interviewer would forget the answer * it just received and ask around it forever. * * The interview ends when the agent says {@link READY}, when the user submits * (`ask` returns `undefined`), or at `maxQuestions` - and in all three cases the * agent still writes a brief from what it has. Stopping early is a legitimate * outcome, not a failure: a brief written from two answers is worth more than * an interrogation nobody finished. */ export declare function interview(options: InterviewOptions): Promise; /** The opening turn: what the user wants, and how to ask about it. */ export declare function questionPrompt(input: string, maxQuestions: number): string; /** What the user answered, and how much room is left. */ export declare function answerPrompt(answer: Answer, remaining: number): string; /** The closing turn: turn the conversation into a specification. */ export declare function briefPrompt(input: string, answers: readonly Answer[]): string; /** * Reads one question out of whatever the agent actually wrote. * * Same decision as `parsePlan`, for the same reason: the input is a language * model, so this is lenient about shape - fenced, wrapped in prose, an array * with one object in it - and strict about content. No `question` string, or no * usable option, means no question: the caller moves on to the brief rather * than putting a malformed card in front of the user. */ export declare function parseQuestion(output: string): Question | undefined; //# sourceMappingURL=interview.d.ts.map