/**
 * arguments/ask — the ONE typed ask per batch for the values `ask` rules need:
 * its fields, its declaration, the binding of the person's answer, the re-ask.
 *
 * Pattern: Walker, pure. Every function here is a function of what it is
 *          handed — the batch's calls, the rules of the implementation that
 *          will run (`ToolOf`), the ask's own state — and nothing reads a
 *          clock, a model or scope. The stage glue (`stages/argumentAsk.ts`)
 *          reads and writes scope and raises the pause.
 * Role:    core/ layer leaf of the inputs layer (honesty layer 2). Imports
 *          nothing from `findings/` (the folder's one-way law).
 * Emits:   N/A.
 *
 * ## One ask for the whole batch, before anything in it runs
 *
 * The layer's Resolve stage names, per call, the `ask` arguments it left out
 * (`ArgumentResolution.ask`). They become ONE typed ask (`tools/inputRequest.ts`,
 * the door `requestInput` uses): one field per distinct (tool, argument), bound
 * to every call of the batch that needs it. Two PERIOD arguments of different
 * tools share one field when their spellings convert (`lookback` ↔
 * `signed-lookback`) and their choices are the same periods — asking twice for
 * one period would ask the person what they already answered. An `iso-range`
 * never merges.
 *
 * - **Field ids are positional** (`f1`, `f2`, …) per declaration — never a
 *   joined `tool.argument` string, which two pairs could spell alike (the
 *   injective-key law). The (tool, argument, calls) behind each id rides the
 *   declaration's `context` under the library's reserved key.
 * - **A value the model READ into the person's words** (declared sources: the
 *   quote was found in the person's messages, the value is not in it) is asked
 *   too, and its field's `context` entry carries those words as `quoted` —
 *   the person's own words, never the model's value, and never while a tool
 *   in reach can hide arguments (`resolve.ts` · `quotesMayShow`).
 * - **A fixed library question.** Each author's question is its field's
 *   `description`; joined questions could break the 4096-character bound at
 *   pause time although each passed it at definition.
 * - **Nothing the model proposed rides the ask** — no `supplied`, no value, no
 *   choice the model wrote.
 * - **More than 32 fields** (the typed ask's limit) go in rounds of 32.
 *
 * ## The answer, re-checked, and a bounded re-ask
 *
 * The typed ask checks type and enum only, so an integer asked as a number can
 * come back `2.5`, and a string can break its `pattern`. Each answer is judged
 * against the PROPERTY's own schema of every argument it binds to, read off the
 * implementation that will run, through the one validator's honest subset
 * (`toolArgsValidation.ts` · `validatePropertyValue`: type, integer, enum,
 * `pattern`, `minLength`, `maxLength` — numeric `minimum` / `maximum` are NOT
 * judged, there or anywhere). One that fails is not bound: its rows say
 * `asked: 'invalid-answer'` and the field is asked again with a second fixed
 * question — at most `MAX_ASK_ROUNDS` times per field; after that, the calls
 * that needed it are refused.
 */
import { type AwaitingInput, type InputField, type InputRequestDeclaration, type InputValue } from '../../../tools/inputRequest.js';
import { type PeriodFactProblem, type PeriodFacts } from '../../../time/convert.js';
import { type InstantText } from '../../../time/instant.js';
import { type TimePolicy } from '../../../time/resolve.js';
import type { TimeAskMessages } from '../../../time/ask.js';
import { type CallWindowRow, type TimeAnswerRow, type TimeReadingRow } from '../../../time/rows.js';
import { type ZoneName } from '../../../time/zone.js';
import { convertSpelling, type PeriodSpelling } from '../../../tools/declare.js';
import { ARGUMENT_ASK_KIND, ASK_CONTEXT_KEY } from './askMarker.js';
import type { ArgumentFill, BatchCall, ToolOf } from './resolve.js';
import { type ArgumentRow } from './rows.js';
export { ARGUMENT_ASK_KIND, ASK_CONTEXT_KEY };
/** How many times one field may be put to the person before its calls are refused. */
export declare const MAX_ASK_ROUNDS = 3;
/** Fields per declaration — the typed ask's own limit (`tools/inputRequest.ts`). */
export declare const MAX_ASK_FIELDS = 32;
/** The declaration's `context` bound — the typed ask's own. */
export declare const ASK_CONTEXT_CHARS = 16384;
/** The declaration id — the author's reusable id; each round is stamped with its own `requestId`. */
export declare const ARGUMENT_ASK_ID = "agentfootprint.arguments";
/** The question of a first ask. Each field's `description` is its author's question. */
export declare const ARGUMENT_ASK_QUESTION = "Before the next step can run, a few values are needed. Each field says what it is for.";
/** The question of a re-ask, after an answer that did not fit the tool's own schema. */
export declare const ARGUMENT_REASK_QUESTION = "One answer did not fit what the tool accepts. Please answer that field again.";
/** One (tool, argument) an ask field's answer binds to, and the calls that need it. */
export interface AskMember {
    readonly toolName: string;
    readonly argument: string;
    /** Set on the argument `Tool.period` names. */
    readonly period?: true;
    /** The member's declared spelling, when its field is a shared period. */
    readonly spelling?: PeriodSpelling;
    /** Every call of the batch that needs this argument asked, in batch order. */
    readonly toolCallIds: readonly string[];
    /**
     * Under declared sources: the person's own words a READING was made of
     * (the first call's that carried one) — shown with the field, never the
     * model's value.
     */
    readonly quoted?: string;
}
/** One field of the batch's ask. */
export interface AskField {
    /** The typed ask's type — `integer` asks as `number`; the re-check judges the integer. */
    readonly type: InputField['type'];
    /** The first member's question — the field's `description`. */
    readonly question: string;
    /** The first member's choices' values — the field's `enum`. Absent: a free field. */
    readonly choices?: readonly InputValue[];
    /** The first member's spelling, when the field is a period shared across spellings. */
    readonly spelling?: PeriodSpelling;
    /** The (tool, argument) pairs the answer binds to; more than one only for a shared period. */
    readonly members: readonly AskMember[];
    /**
     * Set on the ONE field that asks which window the person's own words meant
     * (the lazy word-driven ask, time design § 5.2, § 6.3): its members are the
     * period arguments of every call that left its period out while the turn's
     * one mention was still open; the answer is a window (or, first, the zone
     * the person meant by an abbreviation), converted into each call's form.
     */
    readonly window?: WindowAskField;
}
/** One call's values from a bound window — and whether they read a WIDER window (no form held it exactly). */
export interface WindowFill {
    readonly values: Readonly<Record<string, unknown>>;
    readonly wider?: 'reads-more' | 'tool-trims';
}
/** The time half of a window field — the typed ask's `format`, its labels, and the mention asked about. */
export interface WindowAskField {
    readonly format: 'time-range' | 'zone';
    /** One label per choice (`time-range` with choices only), in the reader's locale. */
    readonly labels?: readonly string[];
    /** Per choice, the zone the candidate was read in — a wall or date form is written in it. */
    readonly zones?: readonly ZoneName[];
    /** The mention's index on its `time-reading` row. */
    readonly mention: number;
}
/** Per field (same positions as the fields): how often asked, and how it settled. */
export interface AskProgress {
    /** How many declarations this field has been put in. */
    readonly rounds: number;
    /** The bound answer, raw, in the field's own spelling. */
    readonly answer?: InputValue;
    /** The last answer did not fit the property's schema and the field is to be asked again. */
    readonly invalid?: true;
    /** Asked `MAX_ASK_ROUNDS` times without an answer that fits — its calls are refused. */
    readonly exhausted?: true;
    /** What the last answer that did not fit failed — the property schema's own expectation, never the answer. */
    readonly expected?: string;
    /**
     * A window field only: the bound window converted into each call's form, by
     * call id — the values the call runs with (raw working state, never a row).
     */
    readonly fills?: Readonly<Record<string, WindowFill>>;
    /** A window field only: the zone was answered and a follow-up question about the same words is to be asked. */
    readonly next?: true;
}
/** The ask now out, waiting for the person's answer. */
export interface AskWaiting {
    readonly requestId: string;
    /** The positions (into `fields`) of this declaration's fields, in `f1…fn` order. */
    readonly fieldIndexes: readonly number[];
    /** The stamped ask, exactly as the pause carries it — the answer is validated against it. */
    readonly awaiting: AwaitingInput;
}
/**
 * The batch ask's working state (`AgentState.argumentAsk`), written by the
 * dispatch stage only. It holds the RAW answers bound so far, because the calls
 * must run with them — the same class as `argumentResolutions`: never a row, an
 * event or a lens view.
 */
export interface ArgumentAskState {
    /** The batch this ask belongs to — the iteration its calls were emitted in. */
    readonly iteration: number;
    readonly fields: readonly AskField[];
    readonly progress: readonly AskProgress[];
    /** Present exactly while a question is out; absent once every field settled. */
    readonly waiting?: AskWaiting;
}
/** One call's `ask` arguments, as the layer's Resolve stage named them. */
export interface CallAsk {
    readonly toolCallId: string;
    readonly ask: readonly string[];
    /** Under declared sources: the person's words a reading was made of, per argument. */
    readonly quoted?: readonly {
        readonly argument: string;
        readonly quote: string;
    }[];
    /** Under `.time({ reader })`: the call left its period out while the turn's one mention was open. */
    readonly window?: true;
}
/**
 * The lazy word-driven ask's plan (time design § 5.2): the question the open
 * mention needs (`time/readingAsk.ts` · `timeAskOf`) and its mention index.
 * Handed by the stage glue only when the turn's one mention is open.
 */
export interface WindowAskPlan {
    readonly question: string;
    readonly format: 'time-range' | 'zone';
    readonly choices?: readonly string[];
    readonly labels?: readonly string[];
    readonly zones?: readonly ZoneName[];
    readonly mention: number;
    /** The turn's clock — a choice outside a member tool's declared facts is not offered (§ 6.3). */
    readonly now: InstantText;
    /** The turn's clock zone — a choice with no zone of its own is converted in it. */
    readonly zone?: ZoneName;
    /** The app's `.time({ zone })`, for a form that declares `wallZone: 'app'`. */
    readonly appZone?: ZoneName;
}
export { convertSpelling };
/**
 * Whether the period field `b` may share `a`'s field: both declare a spelling
 * the library converts, both declare choices, and the choices are the SAME
 * periods under the conversion — so every choice the person can pick is a
 * valid choice of each argument, whichever member's spelling it is read in.
 */
export declare function periodsShareField(a: AskField, b: AskField): boolean;
/**
 * The batch ask's fields: one per distinct (tool, argument) the calls left out,
 * in first-seen batch order, each bound to every call that needs it; then a
 * period field merged into an earlier one it shares (`periodsShareField`). An
 * argument whose rule cannot be read here is left out — the dispatch re-read
 * refuses its call.
 */
export declare function planAskFields(asks: readonly CallAsk[], calls: readonly BatchCall[], toolOf: ToolOf, windowPlan?: WindowAskPlan): AskField[];
/** A fresh state for a batch's fields: nothing asked yet. */
export declare function initialAskState(iteration: number, fields: readonly AskField[]): ArgumentAskState;
/**
 * The next declaration's fields: every field to ask AGAIN (an answer that did
 * not fit) first, on their own, under the re-ask question; else the next
 * never-asked fields, up to `MAX_ASK_FIELDS`. `undefined` when every field has
 * settled — bound or exhausted.
 */
export declare function nextAskRound(state: ArgumentAskState): {
    readonly fieldIndexes: readonly number[];
    readonly reask: boolean;
} | undefined;
/** A JSON object — the shape the host hook must return. */
export type AskContextObject = Readonly<Record<string, unknown>>;
/**
 * The host's own context for the ask (`AgentOptions.argumentAskContext`),
 * judged: a plain object that does not use the library's reserved key. Refused
 * — a `TypeError` naming the hook — rather than repaired or dropped.
 */
export declare function judgeAskContextHook(value: unknown): AskContextObject;
/**
 * The typed ask for one round: the fixed question, one positional field per
 * field of the round, and the reserved `context` listing the (tool, argument,
 * calls) behind each id — within 16384 characters, so a round that would not
 * fit carries fewer fields (the rest go in the next round) and a single field
 * bound to more calls than fit lists the first ones and counts the rest
 * (`moreCalls`). Passes `validateInputDeclaration`.
 */
export declare function argumentAskDeclaration(state: ArgumentAskState, round: {
    readonly fieldIndexes: readonly number[];
    readonly reask: boolean;
}, host?: AskContextObject): {
    readonly declaration: InputRequestDeclaration;
    readonly fieldIndexes: readonly number[];
};
/** `state` with the round's fields counted as asked and the question out. */
export declare function withWaiting(state: ArgumentAskState, waiting: AskWaiting): ArgumentAskState;
/** Whether a stored library ask is the one this state is waiting on (the reserved marker). */
export declare function isArgumentAsk(awaiting: AwaitingInput | undefined): boolean;
/**
 * The person's answer to the ask now out, as field values by id. Accepts what
 * `Agent.resume` hands the run (`{ status: 'input_received', requestId, values }`,
 * already checked at its door) and a raw `InputResponse` (`{ requestId, values }`)
 * from a runner that resumes the executor directly — both judged by the SAME
 * validator (`tools/inputRequest.ts` · `applyInputResponse`): the request id, the
 * declared fields, their types and choices. Throws `InputRequestError` on a
 * reply to another request or a malformed one, and on a PARTIAL reply (only
 * `Agent.resume`'s door keeps a partial answer, without running anything); a
 * cancellation throws the door's `TypeError`.
 */
export declare function readAskAnswer(waiting: AskWaiting, input: unknown): Readonly<Record<string, InputValue>>;
/** The answer in a member's own spelling — itself, unless the field is a shared period. */
export declare function memberValue(field: AskField, member: AskMember, answer: InputValue): InputValue | undefined;
/**
 * Whether `answer` fits EVERY member's property schema (in the member's own
 * spelling) — the re-check the typed ask cannot do: an integer asked as a
 * number, a `pattern`, a string length (never a numeric bound — the one
 * validator ignores `minimum` / `maximum`). The rule is re-read through the
 * same resolver.
 * `expected` names what a misfit failed — the schema's expectation, never the
 * answer.
 */
export declare function checkAnswer(field: AskField, answer: InputValue, toolOf: ToolOf, time?: AskTime): {
    readonly fits: boolean;
    readonly expected?: string;
};
/** Under `.time()`: the turn's clock and the app's zone — what a period answer is judged against. */
export interface AskTime {
    readonly now: InstantText;
    readonly appZone?: ZoneName;
    /** The turn's clock zone — a window answered with no zone of its own is written in it. */
    readonly zone?: ZoneName;
    /**
     * The turn's clock zone is UNKNOWN (`zoneSource: 'unknown'`, G15): `zone` is
     * only the UTC spelling, and a zone answer is the person's own zone — the
     * mention is re-read in it.
     */
    readonly zoneUnknown?: true;
    /**
     * Under `.time({ reader })`: the open mention's row, the policy and the
     * whole catalog — what a zone answer re-reads the mention with.
     */
    readonly reading?: {
        readonly row: TimeReadingRow;
        readonly policy: TimePolicy;
        readonly messages: TimeAskMessages;
    };
}
/**
 * What an answer for a period argument must be, in the words the refusal of
 * an exhausted ask names it (`serve.ts` · `unansweredRefusal`'s `expected`) —
 * the tool's own fact, never the person's answer.
 */
export declare function factExpectation(problem: PeriodFactProblem, facts: PeriodFacts): string;
/** What binding one answer did: the new state and the rows it files. */
export interface BoundAnswer {
    readonly state: ArgumentAskState;
    /**
     * `answered` rows for bound fields; `asked: 'invalid-answer'` rows for fields
     * asked again or exhausted; and, for a bound WINDOW field, the `time-answer`
     * row that settles its mention for the rest of the turn (`time/rows.ts`)
     * and one `call-window` row per call it filled — `filled` from the person's
     * answered window, exactly or wider (`sent`, `differs.extra`).
     */
    readonly rows: readonly (ArgumentRow | TimeAnswerRow | CallWindowRow)[];
}
/**
 * Bind the person's answer to the ask now out: each field whose value fits
 * every member's schema is bound (`answered` rows, one per (call, argument),
 * the value in the tool's own argument view, `free` for a free-text string
 * field); each that does not is marked to ask again (`invalid-answer` rows),
 * or — asked `MAX_ASK_ROUNDS` times already — exhausted. The question is no
 * longer out afterwards.
 */
export declare function bindAnswer(state: ArgumentAskState, values: Readonly<Record<string, InputValue>>, calls: readonly BatchCall[], toolOf: ToolOf, stamp: {
    readonly turn: number;
    readonly iteration: number;
}, time?: AskTime): BoundAnswer;
/** What a window answer must be when no period form of a tool holds it. */
export declare const WINDOW_FORM_EXPECTATION = "a window one of the tool's declared period forms can hold";
/** What a zone answer must be when the person's words name no time in it. */
export declare const WINDOW_ZONE_EXPECTATION = "a time zone in which the time the person wrote exists";
/** What the settled ask hands the batch, per call: the answered fills and the exhausted arguments. */
export interface SettledCall {
    readonly fills: readonly ArgumentFill[];
    /** The arguments whose answers never fit — the call is refused — with what they failed. */
    readonly exhausted: readonly {
        readonly argument: string;
        readonly expected?: string;
    }[];
}
/** Per call id, what the settled ask resolved for it (only calls the ask touched). */
export declare function settledCalls(state: ArgumentAskState): ReadonlyMap<string, SettledCall>;
