agentfootprint 7.3.1 → 7.5.0
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/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/README.md +88 -11
- package/ai-instructions/claude-code/SKILL.md +1 -1
- package/dist/core/Agent.js +26 -4
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/RunnerBase.js +12 -1
- package/dist/core/RunnerBase.js.map +1 -1
- package/dist/core/agent/AgentBuilder.js +33 -1
- package/dist/core/agent/AgentBuilder.js.map +1 -1
- package/dist/core/agent/stages/toolCalls.js +225 -16
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/checkin.js +266 -0
- package/dist/core/checkin.js.map +1 -0
- package/dist/core/pause.js +17 -1
- package/dist/core/pause.js.map +1 -1
- package/dist/core/tools.js +3 -0
- package/dist/core/tools.js.map +1 -1
- package/dist/debug.js +8 -2
- package/dist/debug.js.map +1 -1
- package/dist/embedders/index.js +2 -1
- package/dist/embedders/index.js.map +1 -1
- package/dist/esm/core/Agent.d.ts +31 -5
- package/dist/esm/core/Agent.js +26 -4
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/RunnerBase.js +12 -1
- package/dist/esm/core/RunnerBase.js.map +1 -1
- package/dist/esm/core/agent/AgentBuilder.d.ts +27 -0
- package/dist/esm/core/agent/AgentBuilder.js +33 -1
- package/dist/esm/core/agent/AgentBuilder.js.map +1 -1
- package/dist/esm/core/agent/stages/toolCalls.d.ts +9 -0
- package/dist/esm/core/agent/stages/toolCalls.js +225 -16
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/agent/types.d.ts +2 -0
- package/dist/esm/core/checkin.d.ts +263 -0
- package/dist/esm/core/checkin.js +254 -0
- package/dist/esm/core/checkin.js.map +1 -0
- package/dist/esm/core/pause.d.ts +24 -0
- package/dist/esm/core/pause.js +15 -0
- package/dist/esm/core/pause.js.map +1 -1
- package/dist/esm/core/tools.d.ts +19 -0
- package/dist/esm/core/tools.js +3 -0
- package/dist/esm/core/tools.js.map +1 -1
- package/dist/esm/debug.d.ts +2 -2
- package/dist/esm/debug.js +2 -2
- package/dist/esm/debug.js.map +1 -1
- package/dist/esm/embedders/index.js +2 -1
- package/dist/esm/embedders/index.js.map +1 -1
- package/dist/esm/events/dispatcher.d.ts +1 -1
- package/dist/esm/events/dispatcher.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +19 -0
- package/dist/esm/events/registry.d.ts +7 -1
- package/dist/esm/events/registry.js +6 -0
- package/dist/esm/events/registry.js.map +1 -1
- package/dist/esm/index.d.ts +6 -3
- package/dist/esm/index.js +9 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/context-bisect/index.d.ts +2 -1
- package/dist/esm/lib/context-bisect/index.js +4 -1
- package/dist/esm/lib/context-bisect/index.js.map +1 -1
- package/dist/esm/lib/context-bisect/localize.d.ts +6 -2
- package/dist/esm/lib/context-bisect/localize.js +19 -3
- package/dist/esm/lib/context-bisect/localize.js.map +1 -1
- package/dist/esm/lib/context-bisect/rerun.d.ts +123 -0
- package/dist/esm/lib/context-bisect/rerun.js +155 -0
- package/dist/esm/lib/context-bisect/rerun.js.map +1 -0
- package/dist/esm/lib/context-bisect/sliceToBacktrackTrace.js +12 -3
- package/dist/esm/lib/context-bisect/sliceToBacktrackTrace.js.map +1 -1
- package/dist/esm/lib/context-bisect/types.d.ts +8 -0
- package/dist/esm/lib/context-bisect/types.js.map +1 -1
- package/dist/esm/lib/context-ledger/contextLedger.js +10 -1
- package/dist/esm/lib/context-ledger/contextLedger.js.map +1 -1
- package/dist/esm/lib/context-ledger/gates.js +4 -1
- package/dist/esm/lib/context-ledger/gates.js.map +1 -1
- package/dist/esm/lib/influence-core/attribute.js +4 -1
- package/dist/esm/lib/influence-core/attribute.js.map +1 -1
- package/dist/esm/lib/influence-core/index.d.ts +2 -0
- package/dist/esm/lib/influence-core/index.js +2 -0
- package/dist/esm/lib/influence-core/index.js.map +1 -1
- package/dist/esm/lib/influence-core/lexical.d.ts +60 -0
- package/dist/esm/lib/influence-core/lexical.js +142 -0
- package/dist/esm/lib/influence-core/lexical.js.map +1 -0
- package/dist/esm/lib/influence-core/signals.d.ts +5 -0
- package/dist/esm/lib/influence-core/signals.js +6 -2
- package/dist/esm/lib/influence-core/signals.js.map +1 -1
- package/dist/esm/lib/influence-core/strategies.d.ts +51 -0
- package/dist/esm/lib/influence-core/strategies.js +29 -0
- package/dist/esm/lib/influence-core/strategies.js.map +1 -0
- package/dist/esm/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/esm/observe.d.ts +2 -2
- package/dist/esm/observe.js +2 -2
- package/dist/esm/observe.js.map +1 -1
- package/dist/esm/recorders/core/CheckInRecorder.d.ts +90 -0
- package/dist/esm/recorders/core/CheckInRecorder.js +109 -0
- package/dist/esm/recorders/core/CheckInRecorder.js.map +1 -0
- package/dist/events/dispatcher.js.map +1 -1
- package/dist/events/registry.js +6 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/context-bisect/index.js +6 -1
- package/dist/lib/context-bisect/index.js.map +1 -1
- package/dist/lib/context-bisect/localize.js +19 -3
- package/dist/lib/context-bisect/localize.js.map +1 -1
- package/dist/lib/context-bisect/rerun.js +160 -0
- package/dist/lib/context-bisect/rerun.js.map +1 -0
- package/dist/lib/context-bisect/sliceToBacktrackTrace.js +12 -3
- package/dist/lib/context-bisect/sliceToBacktrackTrace.js.map +1 -1
- package/dist/lib/context-bisect/types.js.map +1 -1
- package/dist/lib/context-ledger/contextLedger.js +10 -1
- package/dist/lib/context-ledger/contextLedger.js.map +1 -1
- package/dist/lib/context-ledger/gates.js +4 -1
- package/dist/lib/context-ledger/gates.js.map +1 -1
- package/dist/lib/influence-core/attribute.js +4 -1
- package/dist/lib/influence-core/attribute.js.map +1 -1
- package/dist/lib/influence-core/index.js +7 -1
- package/dist/lib/influence-core/index.js.map +1 -1
- package/dist/lib/influence-core/lexical.js +146 -0
- package/dist/lib/influence-core/lexical.js.map +1 -0
- package/dist/lib/influence-core/signals.js +8 -3
- package/dist/lib/influence-core/signals.js.map +1 -1
- package/dist/lib/influence-core/strategies.js +33 -0
- package/dist/lib/influence-core/strategies.js.map +1 -0
- package/dist/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/observe.js.map +1 -1
- package/dist/recorders/core/CheckInRecorder.js +114 -0
- package/dist/recorders/core/CheckInRecorder.js.map +1 -0
- package/dist/types/core/Agent.d.ts +31 -5
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/RunnerBase.d.ts.map +1 -1
- package/dist/types/core/agent/AgentBuilder.d.ts +27 -0
- package/dist/types/core/agent/AgentBuilder.d.ts.map +1 -1
- package/dist/types/core/agent/stages/toolCalls.d.ts +9 -0
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +2 -0
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/checkin.d.ts +264 -0
- package/dist/types/core/checkin.d.ts.map +1 -0
- package/dist/types/core/pause.d.ts +24 -0
- package/dist/types/core/pause.d.ts.map +1 -1
- package/dist/types/core/tools.d.ts +19 -0
- package/dist/types/core/tools.d.ts.map +1 -1
- package/dist/types/debug.d.ts +2 -2
- package/dist/types/debug.d.ts.map +1 -1
- package/dist/types/embedders/index.d.ts.map +1 -1
- package/dist/types/events/dispatcher.d.ts +1 -1
- package/dist/types/events/dispatcher.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +19 -0
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/events/registry.d.ts +7 -1
- package/dist/types/events/registry.d.ts.map +1 -1
- package/dist/types/index.d.ts +6 -3
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/context-bisect/index.d.ts +2 -1
- package/dist/types/lib/context-bisect/index.d.ts.map +1 -1
- package/dist/types/lib/context-bisect/localize.d.ts +6 -2
- package/dist/types/lib/context-bisect/localize.d.ts.map +1 -1
- package/dist/types/lib/context-bisect/rerun.d.ts +124 -0
- package/dist/types/lib/context-bisect/rerun.d.ts.map +1 -0
- package/dist/types/lib/context-bisect/sliceToBacktrackTrace.d.ts.map +1 -1
- package/dist/types/lib/context-bisect/types.d.ts +8 -0
- package/dist/types/lib/context-bisect/types.d.ts.map +1 -1
- package/dist/types/lib/context-ledger/contextLedger.d.ts.map +1 -1
- package/dist/types/lib/context-ledger/gates.d.ts.map +1 -1
- package/dist/types/lib/influence-core/attribute.d.ts.map +1 -1
- package/dist/types/lib/influence-core/index.d.ts +2 -0
- package/dist/types/lib/influence-core/index.d.ts.map +1 -1
- package/dist/types/lib/influence-core/lexical.d.ts +61 -0
- package/dist/types/lib/influence-core/lexical.d.ts.map +1 -0
- package/dist/types/lib/influence-core/signals.d.ts +5 -0
- package/dist/types/lib/influence-core/signals.d.ts.map +1 -1
- package/dist/types/lib/influence-core/strategies.d.ts +52 -0
- package/dist/types/lib/influence-core/strategies.d.ts.map +1 -0
- package/dist/types/lib/trace-toolpack/traceToolpack.d.ts.map +1 -1
- package/dist/types/observe.d.ts +2 -2
- package/dist/types/observe.d.ts.map +1 -1
- package/dist/types/recorders/core/CheckInRecorder.d.ts +91 -0
- package/dist/types/recorders/core/CheckInRecorder.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* checkin — the evidence-carrying human-consent primitive.
|
|
3
|
+
*
|
|
4
|
+
* "OpenWorker-class agents check in; agentfootprint checks in WITH THE
|
|
5
|
+
* RECEIPTS." A tool declares `checkIn` (see `Tool.checkIn` in `core/tools.ts`); when
|
|
6
|
+
* it trips, the tool-dispatch loop pauses BEFORE executing and surfaces a
|
|
7
|
+
* {@link CheckInRequest} — a typed ask that carries an EVIDENCE PACK
|
|
8
|
+
* ({@link CheckInEvidence}): what the tool will do, what context the run
|
|
9
|
+
* consumed, which context drove the choice, and a compact run-so-far trail.
|
|
10
|
+
* A human answers with {@link checkInApproved} / {@link checkInDeclined};
|
|
11
|
+
* the {@link CheckInDecision} lands as a typed record.
|
|
12
|
+
*
|
|
13
|
+
* This is the LEAF that owns every check-in TYPE + the pure assembly logic.
|
|
14
|
+
* It has zero runtime/engine imports (only type-only imports of the message
|
|
15
|
+
* shape + the influence-core attribution unit), so it stays cheap to import
|
|
16
|
+
* and trivial to unit-test. The pause plumbing lives in
|
|
17
|
+
* `core/agent/stages/toolCalls.ts`; the events in `events/`; the store in
|
|
18
|
+
* `recorders/core/CheckInRecorder.ts`.
|
|
19
|
+
*
|
|
20
|
+
* NOT a policy engine (the `PermissionChecker` in `adapters/types.ts` is
|
|
21
|
+
* untouched, and runs BEFORE this gate) and NOT UI. This asks a person to
|
|
22
|
+
* CONSENT, with the receipts attached.
|
|
23
|
+
*
|
|
24
|
+
* Pattern: Strategy (pluggable evidence assembler + driver scorer) + pure
|
|
25
|
+
* value types. Every value here survives `structuredClone` + JSON
|
|
26
|
+
* (checkpoint discipline) — no functions, no class instances.
|
|
27
|
+
*/
|
|
28
|
+
import type { LLMMessage } from '../adapters/types.js';
|
|
29
|
+
import type { AttributionUnit } from '../lib/influence-core/types.js';
|
|
30
|
+
/**
|
|
31
|
+
* The typed pause payload for one check-in. Rides the existing pause
|
|
32
|
+
* machinery: it becomes the checkpoint's `pauseData` and is surfaced on
|
|
33
|
+
* surfaced on `RunnerPauseOutcome.checkIn` (`core/pause.ts`). JSON/clone-safe.
|
|
34
|
+
*/
|
|
35
|
+
export interface CheckInRequest {
|
|
36
|
+
/** The tool the agent wants to run (its name). */
|
|
37
|
+
readonly tool: string;
|
|
38
|
+
/** The arguments the model proposed for this call. */
|
|
39
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
40
|
+
/**
|
|
41
|
+
* The model's stated reasoning for THIS call, when the assistant turn
|
|
42
|
+
* carried text alongside the tool call. Omitted when the turn was a bare
|
|
43
|
+
* tool call with no content.
|
|
44
|
+
*/
|
|
45
|
+
readonly intent?: string;
|
|
46
|
+
/** The receipts riding the ask. */
|
|
47
|
+
readonly evidence: CheckInEvidence;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The evidence pack — the "receipts". The `'minimal'` assembler fills only
|
|
51
|
+
* {@link willDo} (zero cost); the `'standard'` assembler fills all four.
|
|
52
|
+
*/
|
|
53
|
+
export interface CheckInEvidence {
|
|
54
|
+
/** Plain-words claim of what will happen: the tool description + the
|
|
55
|
+
* rendered arguments. Always present. */
|
|
56
|
+
readonly willDo: string;
|
|
57
|
+
/** What context this run consumed so far — one frame per context piece
|
|
58
|
+
* (system rules, the user task, prior tool results). Absent under the
|
|
59
|
+
* `'minimal'` assembler. */
|
|
60
|
+
readonly read?: readonly CheckInContextFrame[];
|
|
61
|
+
/** Which context drove THIS choice, ranked most-to-least. Produced by the
|
|
62
|
+
* configured {@link CheckInScorer} (default: a zero-LLM lexical scorer).
|
|
63
|
+
* Absent under the `'minimal'` assembler. */
|
|
64
|
+
readonly drivers?: readonly CheckInDriver[];
|
|
65
|
+
/** A compact grouped summary of the run so far. Absent under `'minimal'`. */
|
|
66
|
+
readonly trail?: CheckInTrail;
|
|
67
|
+
}
|
|
68
|
+
/** One piece of context the run consumed — role/channel + a compact summary. */
|
|
69
|
+
export interface CheckInContextFrame {
|
|
70
|
+
/** Origin group: `'system' | 'task' | 'result'`. */
|
|
71
|
+
readonly channel: string;
|
|
72
|
+
/** A short, truncated summary of the piece (never the full payload). */
|
|
73
|
+
readonly summary: string;
|
|
74
|
+
}
|
|
75
|
+
/** One ranked driver — a context unit and how strongly it aligns with the pick. */
|
|
76
|
+
export interface CheckInDriver {
|
|
77
|
+
/** The unit id (the citation, e.g. `'system-1'`). */
|
|
78
|
+
readonly id: string;
|
|
79
|
+
/** Origin group: `'system' | 'task' | 'result'`. */
|
|
80
|
+
readonly channel: string;
|
|
81
|
+
/** The unit text (quotable). */
|
|
82
|
+
readonly text: string;
|
|
83
|
+
/** Alignment score — higher means it drove the pick more. Scorer-defined
|
|
84
|
+
* units; compare within one request, not across scorers. */
|
|
85
|
+
readonly score: number;
|
|
86
|
+
}
|
|
87
|
+
/** A compact grouped summary of the run so far. */
|
|
88
|
+
export interface CheckInTrail {
|
|
89
|
+
/** Which ReAct iteration this check-in fired on. */
|
|
90
|
+
readonly iteration: number;
|
|
91
|
+
/** The tool calls already completed this run, oldest first. */
|
|
92
|
+
readonly toolCalls: readonly {
|
|
93
|
+
readonly name: string;
|
|
94
|
+
readonly ok: boolean;
|
|
95
|
+
}[];
|
|
96
|
+
/** One-line human summary, e.g. `"3 tools run over 2 iterations"`. */
|
|
97
|
+
readonly summary: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The human's answer to a check-in — the record that lands. Produced by
|
|
101
|
+
* {@link checkInApproved} / {@link checkInDeclined} and passed to
|
|
102
|
+
* `agent.resume(checkpoint, decision)`. JSON/clone-safe.
|
|
103
|
+
*/
|
|
104
|
+
export interface CheckInDecision {
|
|
105
|
+
/** True to run the tool, false to decline it. */
|
|
106
|
+
readonly approved: boolean;
|
|
107
|
+
/** Who decided (an operator id, an email, a queue name — your call). */
|
|
108
|
+
readonly by: string;
|
|
109
|
+
/** Optional note. On decline it is surfaced to the model so it can adapt. */
|
|
110
|
+
readonly note?: string;
|
|
111
|
+
/** When the decision was made (ms since epoch). */
|
|
112
|
+
readonly at: number;
|
|
113
|
+
}
|
|
114
|
+
/** Options for {@link checkInApproved} / {@link checkInDeclined}. */
|
|
115
|
+
export interface CheckInDecisionInput {
|
|
116
|
+
/** Who decided. */
|
|
117
|
+
readonly by: string;
|
|
118
|
+
/** Optional free-text note. */
|
|
119
|
+
readonly note?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Approve a pending check-in — the paused tool executes normally on resume.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* const decision = checkInApproved({ by: 'alice@ops', note: 'verified with customer' });
|
|
126
|
+
* const final = await agent.resume(outcome.checkpoint, decision);
|
|
127
|
+
*/
|
|
128
|
+
export declare function checkInApproved(input: CheckInDecisionInput): CheckInDecision;
|
|
129
|
+
/**
|
|
130
|
+
* Decline a pending check-in — the tool is NOT executed; the model receives
|
|
131
|
+
* a `"declined by human: <note>"` tool result and adapts in-loop.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* const decision = checkInDeclined({ by: 'alice@ops', note: 'amount too high' });
|
|
135
|
+
* const final = await agent.resume(outcome.checkpoint, decision);
|
|
136
|
+
*/
|
|
137
|
+
export declare function checkInDeclined(input: CheckInDecisionInput): CheckInDecision;
|
|
138
|
+
/**
|
|
139
|
+
* Type guard — is this resume input a {@link CheckInDecision}? Distinguishes
|
|
140
|
+
* a check-in answer from a plain `askHuman` tool-result value.
|
|
141
|
+
*/
|
|
142
|
+
export declare function isCheckInDecision(x: unknown): x is CheckInDecision;
|
|
143
|
+
/**
|
|
144
|
+
* What a tool declares to demand a check-in. `'always'` trips on every call;
|
|
145
|
+
* a predicate trips selectively (e.g. only high-value refunds). A predicate
|
|
146
|
+
* that throws trips (fail toward asking the human — consequential actions
|
|
147
|
+
* should not silently proceed on a buggy predicate).
|
|
148
|
+
*/
|
|
149
|
+
export type CheckInDemand<TArgs = Readonly<Record<string, unknown>>> = 'always' | ((args: TArgs, ctx: CheckInPredicateContext) => boolean);
|
|
150
|
+
/** Context handed to a {@link CheckInDemand} predicate. */
|
|
151
|
+
export interface CheckInPredicateContext {
|
|
152
|
+
/** The current ReAct iteration. */
|
|
153
|
+
readonly iteration: number;
|
|
154
|
+
/** This tool invocation's id. */
|
|
155
|
+
readonly toolCallId: string;
|
|
156
|
+
/** The conversation so far (system, user, prior tool results). */
|
|
157
|
+
readonly history: readonly LLMMessage[];
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Decide whether a tool's declared demand trips for this call. Returns false
|
|
161
|
+
* when the tool declared no `checkIn` (backward-compatible: byte-identical
|
|
162
|
+
* behavior for tools without the field).
|
|
163
|
+
*/
|
|
164
|
+
export declare function shouldCheckIn(demand: CheckInDemand<Readonly<Record<string, unknown>>> | undefined, args: Readonly<Record<string, unknown>>, ctx: CheckInPredicateContext): boolean;
|
|
165
|
+
/** Input to a {@link CheckInScorer}. Mirrors `influence-core`'s attribution
|
|
166
|
+
* shape so an embedding-backed scorer (wrapping `explainChoice`) drops in. */
|
|
167
|
+
export interface CheckInScoreInput {
|
|
168
|
+
/** The chosen tool. `text` is what gets scored (name + description + args). */
|
|
169
|
+
readonly tool: {
|
|
170
|
+
readonly name: string;
|
|
171
|
+
readonly text: string;
|
|
172
|
+
};
|
|
173
|
+
/** The context units to rank against the tool. */
|
|
174
|
+
readonly units: readonly AttributionUnit[];
|
|
175
|
+
/** Abort signal for network-backed scorers. */
|
|
176
|
+
readonly signal?: AbortSignal;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Ranks context units by how strongly each drove one tool choice. The
|
|
180
|
+
* DEFAULT is {@link lexicalDriverScorer} — deterministic, zero LLM, zero
|
|
181
|
+
* network. Swap in a richer one via `.checkIn({ scorer })`, e.g. wrapping
|
|
182
|
+
* `explainChoice` from `agentfootprint` with your own embedder.
|
|
183
|
+
*
|
|
184
|
+
* @example a semantic scorer
|
|
185
|
+
* const scorer: CheckInScorer = async ({ tool, units, signal }) => {
|
|
186
|
+
* const ex = await explainChoice({ tool, units, embedder, signal });
|
|
187
|
+
* return ex.units.map((u) => ({ id: u.id, channel: u.channel, text: u.text, score: u.score }));
|
|
188
|
+
* };
|
|
189
|
+
*/
|
|
190
|
+
export type CheckInScorer = (input: CheckInScoreInput) => readonly CheckInDriver[] | Promise<readonly CheckInDriver[]>;
|
|
191
|
+
/**
|
|
192
|
+
* The default drivers scorer: deterministic Jaccard token overlap between
|
|
193
|
+
* the tool text and each context unit. Zero LLM, zero network, structuredClone
|
|
194
|
+
* -safe output. Ties keep input order (stable sort).
|
|
195
|
+
*/
|
|
196
|
+
export declare const lexicalDriverScorer: CheckInScorer;
|
|
197
|
+
/** Everything the assembler needs to build one evidence pack. */
|
|
198
|
+
export interface CheckInAssemblerInput {
|
|
199
|
+
/** The chosen tool — `name` for citations, `description` for `willDo`. */
|
|
200
|
+
readonly tool: {
|
|
201
|
+
readonly name: string;
|
|
202
|
+
readonly description: string;
|
|
203
|
+
};
|
|
204
|
+
/** The proposed arguments. */
|
|
205
|
+
readonly args: Readonly<Record<string, unknown>>;
|
|
206
|
+
/** The model's stated reasoning, if any (assistant-turn text). */
|
|
207
|
+
readonly intent?: string;
|
|
208
|
+
/** The ReAct iteration this check-in fired on. */
|
|
209
|
+
readonly iteration: number;
|
|
210
|
+
/** The conversation so far — the raw material for `read`, `drivers`, `trail`. */
|
|
211
|
+
readonly history: readonly LLMMessage[];
|
|
212
|
+
/** The scorer to rank `drivers` with. */
|
|
213
|
+
readonly scorer: CheckInScorer;
|
|
214
|
+
/** Abort signal threaded to the scorer. */
|
|
215
|
+
readonly signal?: AbortSignal;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Builds the evidence pack for one check-in. Two are built in
|
|
219
|
+
* ({@link standardEvidenceAssembler}, {@link minimalEvidenceAssembler});
|
|
220
|
+
* pass your own to `.checkIn({ evidence })` for full control.
|
|
221
|
+
*/
|
|
222
|
+
export type CheckInAssembler = (input: CheckInAssemblerInput) => CheckInEvidence | Promise<CheckInEvidence>;
|
|
223
|
+
/** Which built-in assembler to use, by name. */
|
|
224
|
+
export type EvidencePreset = 'minimal' | 'standard';
|
|
225
|
+
/**
|
|
226
|
+
* Derive attribution units from the run-so-far conversation: system rules
|
|
227
|
+
* (split into sentences), the user task, and prior tool results. These feed
|
|
228
|
+
* BOTH `read` (as frames) and `drivers` (scored). Ids are unique + stable.
|
|
229
|
+
*/
|
|
230
|
+
export declare function unitsFromHistory(history: readonly LLMMessage[]): AttributionUnit[];
|
|
231
|
+
/**
|
|
232
|
+
* The `'standard'` assembler — fills all four evidence fields. The `drivers`
|
|
233
|
+
* ranking runs the configured scorer over the run-so-far context units; the
|
|
234
|
+
* default scorer is deterministic and makes zero LLM/network calls.
|
|
235
|
+
*/
|
|
236
|
+
export declare const standardEvidenceAssembler: CheckInAssembler;
|
|
237
|
+
/** The `'minimal'` assembler — only `willDo`. Zero cost; no scorer call. */
|
|
238
|
+
export declare const minimalEvidenceAssembler: CheckInAssembler;
|
|
239
|
+
/** What `.checkIn({...})` accepts on the Agent builder. */
|
|
240
|
+
export interface CheckInBuilderOptions {
|
|
241
|
+
/**
|
|
242
|
+
* How much evidence rides the ask. `'standard'` (default) fills all four
|
|
243
|
+
* fields; `'minimal'` fills only `willDo` (zero cost); or pass your own
|
|
244
|
+
* {@link CheckInAssembler}.
|
|
245
|
+
*/
|
|
246
|
+
readonly evidence?: EvidencePreset | CheckInAssembler;
|
|
247
|
+
/**
|
|
248
|
+
* The scorer that ranks `drivers`. Default {@link lexicalDriverScorer}
|
|
249
|
+
* (deterministic, zero LLM). Only consulted by the `'standard'` assembler.
|
|
250
|
+
*/
|
|
251
|
+
readonly scorer?: CheckInScorer;
|
|
252
|
+
}
|
|
253
|
+
/** The resolved config threaded into the tool-dispatch handler. */
|
|
254
|
+
export interface ResolvedCheckInConfig {
|
|
255
|
+
readonly assembler: CheckInAssembler;
|
|
256
|
+
readonly scorer: CheckInScorer;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Resolve builder options (or nothing) into a runtime config. The default —
|
|
260
|
+
* `standard` evidence + `lexicalDriverScorer` — makes a tool that declares
|
|
261
|
+
* `checkIn` work even when the builder never called `.checkIn()`.
|
|
262
|
+
*/
|
|
263
|
+
export declare function resolveCheckInConfig(opts?: CheckInBuilderOptions): ResolvedCheckInConfig;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* checkin — the evidence-carrying human-consent primitive.
|
|
3
|
+
*
|
|
4
|
+
* "OpenWorker-class agents check in; agentfootprint checks in WITH THE
|
|
5
|
+
* RECEIPTS." A tool declares `checkIn` (see `Tool.checkIn` in `core/tools.ts`); when
|
|
6
|
+
* it trips, the tool-dispatch loop pauses BEFORE executing and surfaces a
|
|
7
|
+
* {@link CheckInRequest} — a typed ask that carries an EVIDENCE PACK
|
|
8
|
+
* ({@link CheckInEvidence}): what the tool will do, what context the run
|
|
9
|
+
* consumed, which context drove the choice, and a compact run-so-far trail.
|
|
10
|
+
* A human answers with {@link checkInApproved} / {@link checkInDeclined};
|
|
11
|
+
* the {@link CheckInDecision} lands as a typed record.
|
|
12
|
+
*
|
|
13
|
+
* This is the LEAF that owns every check-in TYPE + the pure assembly logic.
|
|
14
|
+
* It has zero runtime/engine imports (only type-only imports of the message
|
|
15
|
+
* shape + the influence-core attribution unit), so it stays cheap to import
|
|
16
|
+
* and trivial to unit-test. The pause plumbing lives in
|
|
17
|
+
* `core/agent/stages/toolCalls.ts`; the events in `events/`; the store in
|
|
18
|
+
* `recorders/core/CheckInRecorder.ts`.
|
|
19
|
+
*
|
|
20
|
+
* NOT a policy engine (the `PermissionChecker` in `adapters/types.ts` is
|
|
21
|
+
* untouched, and runs BEFORE this gate) and NOT UI. This asks a person to
|
|
22
|
+
* CONSENT, with the receipts attached.
|
|
23
|
+
*
|
|
24
|
+
* Pattern: Strategy (pluggable evidence assembler + driver scorer) + pure
|
|
25
|
+
* value types. Every value here survives `structuredClone` + JSON
|
|
26
|
+
* (checkpoint discipline) — no functions, no class instances.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Approve a pending check-in — the paused tool executes normally on resume.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const decision = checkInApproved({ by: 'alice@ops', note: 'verified with customer' });
|
|
33
|
+
* const final = await agent.resume(outcome.checkpoint, decision);
|
|
34
|
+
*/
|
|
35
|
+
export function checkInApproved(input) {
|
|
36
|
+
return { approved: true, by: input.by, at: Date.now(), ...(input.note && { note: input.note }) };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Decline a pending check-in — the tool is NOT executed; the model receives
|
|
40
|
+
* a `"declined by human: <note>"` tool result and adapts in-loop.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* const decision = checkInDeclined({ by: 'alice@ops', note: 'amount too high' });
|
|
44
|
+
* const final = await agent.resume(outcome.checkpoint, decision);
|
|
45
|
+
*/
|
|
46
|
+
export function checkInDeclined(input) {
|
|
47
|
+
return { approved: false, by: input.by, at: Date.now(), ...(input.note && { note: input.note }) };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Type guard — is this resume input a {@link CheckInDecision}? Distinguishes
|
|
51
|
+
* a check-in answer from a plain `askHuman` tool-result value.
|
|
52
|
+
*/
|
|
53
|
+
export function isCheckInDecision(x) {
|
|
54
|
+
return (typeof x === 'object' &&
|
|
55
|
+
x !== null &&
|
|
56
|
+
typeof x.approved === 'boolean' &&
|
|
57
|
+
typeof x.by === 'string');
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Decide whether a tool's declared demand trips for this call. Returns false
|
|
61
|
+
* when the tool declared no `checkIn` (backward-compatible: byte-identical
|
|
62
|
+
* behavior for tools without the field).
|
|
63
|
+
*/
|
|
64
|
+
export function shouldCheckIn(demand, args, ctx) {
|
|
65
|
+
if (demand === undefined)
|
|
66
|
+
return false;
|
|
67
|
+
if (demand === 'always')
|
|
68
|
+
return true;
|
|
69
|
+
try {
|
|
70
|
+
return demand(args, ctx) === true;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// A buggy predicate must not let a consequential action slip through
|
|
74
|
+
// unreviewed — fail toward asking the human.
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const WORD_RE = /[a-z0-9]+/g;
|
|
79
|
+
const STOP = new Set([
|
|
80
|
+
'the',
|
|
81
|
+
'a',
|
|
82
|
+
'an',
|
|
83
|
+
'and',
|
|
84
|
+
'or',
|
|
85
|
+
'to',
|
|
86
|
+
'of',
|
|
87
|
+
'in',
|
|
88
|
+
'on',
|
|
89
|
+
'for',
|
|
90
|
+
'with',
|
|
91
|
+
'is',
|
|
92
|
+
'are',
|
|
93
|
+
'this',
|
|
94
|
+
'that',
|
|
95
|
+
'it',
|
|
96
|
+
'as',
|
|
97
|
+
'at',
|
|
98
|
+
'by',
|
|
99
|
+
'be',
|
|
100
|
+
'you',
|
|
101
|
+
'your',
|
|
102
|
+
'i',
|
|
103
|
+
]);
|
|
104
|
+
function tokenize(text) {
|
|
105
|
+
const out = new Set();
|
|
106
|
+
const lower = text.toLowerCase();
|
|
107
|
+
let m;
|
|
108
|
+
while ((m = WORD_RE.exec(lower))) {
|
|
109
|
+
if (m[0].length > 1 && !STOP.has(m[0]))
|
|
110
|
+
out.add(m[0]);
|
|
111
|
+
}
|
|
112
|
+
WORD_RE.lastIndex = 0;
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The default drivers scorer: deterministic Jaccard token overlap between
|
|
117
|
+
* the tool text and each context unit. Zero LLM, zero network, structuredClone
|
|
118
|
+
* -safe output. Ties keep input order (stable sort).
|
|
119
|
+
*/
|
|
120
|
+
export const lexicalDriverScorer = ({ tool, units }) => {
|
|
121
|
+
const toolTokens = tokenize(tool.text);
|
|
122
|
+
const scored = units.map((u) => {
|
|
123
|
+
const unitTokens = tokenize(u.text);
|
|
124
|
+
let shared = 0;
|
|
125
|
+
for (const t of unitTokens)
|
|
126
|
+
if (toolTokens.has(t))
|
|
127
|
+
shared++;
|
|
128
|
+
const union = toolTokens.size + unitTokens.size - shared;
|
|
129
|
+
const score = union === 0 ? 0 : shared / union;
|
|
130
|
+
return { id: u.id, channel: u.channel, text: u.text, score };
|
|
131
|
+
});
|
|
132
|
+
// Stable descending sort — Array.prototype.sort is stable in modern engines.
|
|
133
|
+
return scored.sort((a, b) => b.score - a.score);
|
|
134
|
+
};
|
|
135
|
+
const MAX_SUMMARY = 160;
|
|
136
|
+
function truncate(s, max = MAX_SUMMARY) {
|
|
137
|
+
const flat = s.replace(/\s+/g, ' ').trim();
|
|
138
|
+
return flat.length <= max ? flat : `${flat.slice(0, max - 1)}…`;
|
|
139
|
+
}
|
|
140
|
+
/** Render args as a compact `k=v, k=v` string (values truncated, clone-safe). */
|
|
141
|
+
function renderArgs(args) {
|
|
142
|
+
const parts = Object.entries(args).map(([k, v]) => {
|
|
143
|
+
const val = typeof v === 'string' ? v : v === null || v === undefined ? String(v) : JSON.stringify(v);
|
|
144
|
+
return `${k}=${truncate(val, 60)}`;
|
|
145
|
+
});
|
|
146
|
+
return parts.join(', ');
|
|
147
|
+
}
|
|
148
|
+
/** Plain-words "what will happen" claim. */
|
|
149
|
+
function buildWillDo(tool, args) {
|
|
150
|
+
const desc = tool.description.trim() || tool.name;
|
|
151
|
+
const rendered = renderArgs(args);
|
|
152
|
+
return rendered ? `${desc} — with ${rendered}` : desc;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Derive attribution units from the run-so-far conversation: system rules
|
|
156
|
+
* (split into sentences), the user task, and prior tool results. These feed
|
|
157
|
+
* BOTH `read` (as frames) and `drivers` (scored). Ids are unique + stable.
|
|
158
|
+
*/
|
|
159
|
+
export function unitsFromHistory(history) {
|
|
160
|
+
const units = [];
|
|
161
|
+
let sysN = 0;
|
|
162
|
+
let taskN = 0;
|
|
163
|
+
let resN = 0;
|
|
164
|
+
for (const m of history) {
|
|
165
|
+
const content = (m.content ?? '').trim();
|
|
166
|
+
if (!content)
|
|
167
|
+
continue;
|
|
168
|
+
if (m.role === 'system') {
|
|
169
|
+
// Split the system prompt into rule-sized units so a single rule can be
|
|
170
|
+
// cited. Sentence-ish split; keep non-empty pieces.
|
|
171
|
+
for (const piece of content.split(/(?<=[.!?])\s+|\n+/)) {
|
|
172
|
+
const t = piece.trim();
|
|
173
|
+
if (t)
|
|
174
|
+
units.push({ id: `system-${++sysN}`, channel: 'system', text: t });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else if (m.role === 'user') {
|
|
178
|
+
units.push({ id: `task-${++taskN}`, channel: 'task', text: content });
|
|
179
|
+
}
|
|
180
|
+
else if (m.role === 'tool') {
|
|
181
|
+
units.push({
|
|
182
|
+
id: `result-${++resN}`,
|
|
183
|
+
channel: 'result',
|
|
184
|
+
text: m.toolName ? `${m.toolName}: ${content}` : content,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return units;
|
|
189
|
+
}
|
|
190
|
+
function framesFromUnits(units) {
|
|
191
|
+
return units.map((u) => ({ channel: u.channel, summary: truncate(u.text) }));
|
|
192
|
+
}
|
|
193
|
+
function buildTrail(history, iteration) {
|
|
194
|
+
const toolCalls = [];
|
|
195
|
+
for (const m of history) {
|
|
196
|
+
if (m.role === 'tool' && m.toolName) {
|
|
197
|
+
// A tool result whose content advertises an error is marked not-ok. The
|
|
198
|
+
// synthetic strings the loop writes ("[permission denied…]", "declined by
|
|
199
|
+
// human…", "credential error…") all read as failures here.
|
|
200
|
+
const c = (m.content ?? '').toLowerCase();
|
|
201
|
+
const ok = !(c.startsWith('[permission denied') ||
|
|
202
|
+
c.startsWith('declined by human') ||
|
|
203
|
+
c.startsWith('credential error') ||
|
|
204
|
+
c.startsWith('authorization required'));
|
|
205
|
+
toolCalls.push({ name: m.toolName, ok });
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const summary = toolCalls.length === 0
|
|
209
|
+
? `no tools run yet (iteration ${iteration})`
|
|
210
|
+
: `${toolCalls.length} tool${toolCalls.length === 1 ? '' : 's'} run over ${iteration} iteration${iteration === 1 ? '' : 's'}`;
|
|
211
|
+
return { iteration, toolCalls, summary };
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* The `'standard'` assembler — fills all four evidence fields. The `drivers`
|
|
215
|
+
* ranking runs the configured scorer over the run-so-far context units; the
|
|
216
|
+
* default scorer is deterministic and makes zero LLM/network calls.
|
|
217
|
+
*/
|
|
218
|
+
export const standardEvidenceAssembler = async (input) => {
|
|
219
|
+
const { tool, args, iteration, history, scorer, signal } = input;
|
|
220
|
+
const units = unitsFromHistory(history);
|
|
221
|
+
const willDo = buildWillDo(tool, args);
|
|
222
|
+
const read = framesFromUnits(units);
|
|
223
|
+
const trail = buildTrail(history, iteration);
|
|
224
|
+
let drivers = [];
|
|
225
|
+
if (units.length > 0) {
|
|
226
|
+
const toolText = `${tool.name} ${tool.description} ${renderArgs(args)}`.trim();
|
|
227
|
+
drivers = await scorer({
|
|
228
|
+
tool: { name: tool.name, text: toolText },
|
|
229
|
+
units,
|
|
230
|
+
...(signal && { signal }),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
return { willDo, read, drivers, trail };
|
|
234
|
+
};
|
|
235
|
+
/** The `'minimal'` assembler — only `willDo`. Zero cost; no scorer call. */
|
|
236
|
+
export const minimalEvidenceAssembler = (input) => ({
|
|
237
|
+
willDo: buildWillDo(input.tool, input.args),
|
|
238
|
+
});
|
|
239
|
+
/**
|
|
240
|
+
* Resolve builder options (or nothing) into a runtime config. The default —
|
|
241
|
+
* `standard` evidence + `lexicalDriverScorer` — makes a tool that declares
|
|
242
|
+
* `checkIn` work even when the builder never called `.checkIn()`.
|
|
243
|
+
*/
|
|
244
|
+
export function resolveCheckInConfig(opts) {
|
|
245
|
+
const scorer = opts?.scorer ?? lexicalDriverScorer;
|
|
246
|
+
const evidence = opts?.evidence ?? 'standard';
|
|
247
|
+
const assembler = evidence === 'standard'
|
|
248
|
+
? standardEvidenceAssembler
|
|
249
|
+
: evidence === 'minimal'
|
|
250
|
+
? minimalEvidenceAssembler
|
|
251
|
+
: evidence;
|
|
252
|
+
return { assembler, scorer };
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=checkin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkin.js","sourceRoot":"","sources":["../../../src/core/checkin.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/core/pause.d.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* the tool API clean (tools are pure-ish) while still supporting pause.
|
|
17
17
|
*/
|
|
18
18
|
import type { FlowchartCheckpoint } from 'footprintjs';
|
|
19
|
+
import type { CheckInRequest } from './checkin.js';
|
|
19
20
|
/**
|
|
20
21
|
* Outcome returned by `runner.run()` / `runner.resume()` when execution
|
|
21
22
|
* has paused mid-flow. The shape mirrors footprintjs's `PausedResult` but
|
|
@@ -28,9 +29,32 @@ export interface RunnerPauseOutcome {
|
|
|
28
29
|
readonly checkpoint: FlowchartCheckpoint;
|
|
29
30
|
/** Data passed to `scope.$pause()` / `pauseHere()`. Consumer-typed. */
|
|
30
31
|
readonly pauseData: unknown;
|
|
32
|
+
/**
|
|
33
|
+
* Present ONLY when this pause is an evidence-carrying check-in (a tool
|
|
34
|
+
* declared `checkIn`). Carries the typed ask + evidence pack. Absent for
|
|
35
|
+
* plain `askHuman` / `pauseHere` pauses — that's the clean discriminant
|
|
36
|
+
* between the two pause kinds. Resume with a `CheckInDecision`
|
|
37
|
+
* (`checkInApproved` / `checkInDeclined`).
|
|
38
|
+
*/
|
|
39
|
+
readonly checkIn?: CheckInRequest;
|
|
31
40
|
}
|
|
32
41
|
/** Type guard — discriminates `RunnerPauseOutcome` from a normal `TOut`. */
|
|
33
42
|
export declare function isPaused<T>(result: T | RunnerPauseOutcome): result is RunnerPauseOutcome;
|
|
43
|
+
/**
|
|
44
|
+
* Type guard — is this a check-in pause (evidence-carrying human consent),
|
|
45
|
+
* as opposed to a plain `askHuman` pause? Narrows `checkIn` to present.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* const out = await agent.run({ message });
|
|
49
|
+
* if (isCheckInPause(out)) {
|
|
50
|
+
* showToHuman(out.checkIn.evidence); // the receipts
|
|
51
|
+
* const decision = checkInApproved({ by: 'alice' });
|
|
52
|
+
* await agent.resume(out.checkpoint, decision);
|
|
53
|
+
* }
|
|
54
|
+
*/
|
|
55
|
+
export declare function isCheckInPause(result: unknown): result is RunnerPauseOutcome & {
|
|
56
|
+
readonly checkIn: CheckInRequest;
|
|
57
|
+
};
|
|
34
58
|
/**
|
|
35
59
|
* Control-flow error raised by `pauseHere()` inside a tool's `execute()`.
|
|
36
60
|
* Caught by the Agent's tool-call stage, which forwards to `scope.$pause()`.
|
package/dist/esm/core/pause.js
CHANGED
|
@@ -19,6 +19,21 @@
|
|
|
19
19
|
export function isPaused(result) {
|
|
20
20
|
return (typeof result === 'object' && result !== null && result.paused === true);
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Type guard — is this a check-in pause (evidence-carrying human consent),
|
|
24
|
+
* as opposed to a plain `askHuman` pause? Narrows `checkIn` to present.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const out = await agent.run({ message });
|
|
28
|
+
* if (isCheckInPause(out)) {
|
|
29
|
+
* showToHuman(out.checkIn.evidence); // the receipts
|
|
30
|
+
* const decision = checkInApproved({ by: 'alice' });
|
|
31
|
+
* await agent.resume(out.checkpoint, decision);
|
|
32
|
+
* }
|
|
33
|
+
*/
|
|
34
|
+
export function isCheckInPause(result) {
|
|
35
|
+
return isPaused(result) && result.checkIn !== undefined;
|
|
36
|
+
}
|
|
22
37
|
/**
|
|
23
38
|
* Control-flow error raised by `pauseHere()` inside a tool's `execute()`.
|
|
24
39
|
* Caught by the Agent's tool-call stage, which forwards to `scope.$pause()`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pause.js","sourceRoot":"","sources":["../../../src/core/pause.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"pause.js","sourceRoot":"","sources":["../../../src/core/pause.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA2BH,4EAA4E;AAC5E,MAAM,UAAU,QAAQ,CAAI,MAA8B;IACxD,OAAO,CACL,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAK,MAA6B,CAAC,MAAM,KAAK,IAAI,CAChG,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAe;IAEf,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAK,MAA6B,CAAC,OAAO,KAAK,SAAS,CAAC;AAClF,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAU;IACvB,YAAY,IAAa;QACvB,KAAK,CAAC,cAAc,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,kEAAkE;QAClE,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,OAAO,CACL,GAAG,YAAY,YAAY;QAC3B,CAAC,GAAG,YAAY,KAAK;YACnB,GAAG,CAAC,IAAI,KAAK,cAAc;YAC3B,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CACrD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,CAAC"}
|
package/dist/esm/core/tools.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { LLMToolSchema } from '../adapters/types.js';
|
|
10
10
|
import type { Credential, CredentialNeed, CredentialProvider } from '../identity/types.js';
|
|
11
|
+
import type { CheckInDemand } from './checkin.js';
|
|
11
12
|
/**
|
|
12
13
|
* One executable tool the Agent can call.
|
|
13
14
|
*
|
|
@@ -22,6 +23,21 @@ export interface Tool<TArgs = Record<string, unknown>, TResult = unknown> {
|
|
|
22
23
|
* BEFORE invoking and injects `ctx.credential`; it is NOT in `schema`, so the
|
|
23
24
|
* LLM never sees or fills it. */
|
|
24
25
|
readonly needs?: CredentialNeed;
|
|
26
|
+
/**
|
|
27
|
+
* Declarative demand for a human check-in BEFORE this tool runs — consent
|
|
28
|
+
* for a consequential action, with an evidence pack riding the ask.
|
|
29
|
+
* `'always'` trips on every call; a `(args, ctx) => boolean` predicate trips
|
|
30
|
+
* selectively (e.g. only refunds over $1000). When it trips the tool-dispatch
|
|
31
|
+
* loop pauses BEFORE execute and surfaces a `CheckInRequest`; the human
|
|
32
|
+
* answers with `checkInApproved` / `checkInDeclined`. Omitted → byte-identical
|
|
33
|
+
* behavior (no gate, no events, no pause). See `.checkIn()` on the Agent
|
|
34
|
+
* builder to configure the evidence pack. Ordered AFTER the permission gate
|
|
35
|
+
* and arg-validation, BEFORE credential resolution.
|
|
36
|
+
*
|
|
37
|
+
* Non-generic here (a `Tool` widens into `Tool[]` registries); `defineTool`
|
|
38
|
+
* exposes a predicate typed to the tool's args at the CALL site.
|
|
39
|
+
*/
|
|
40
|
+
readonly checkIn?: CheckInDemand;
|
|
25
41
|
execute(args: TArgs, ctx: ToolExecutionContext): Promise<TResult> | TResult;
|
|
26
42
|
}
|
|
27
43
|
/** Runtime context passed to tool.execute(). */
|
|
@@ -69,6 +85,9 @@ export interface DefineToolOptions<TArgs, TResult> {
|
|
|
69
85
|
/** Declare a credential this tool needs (declare-and-push). Resolved by the
|
|
70
86
|
* framework before `execute` and injected as `ctx.credential`. */
|
|
71
87
|
readonly needs?: CredentialNeed;
|
|
88
|
+
/** Demand a human check-in before this tool runs (see {@link Tool.checkIn}).
|
|
89
|
+
* `'always'` or a `(args, ctx) => boolean` predicate. */
|
|
90
|
+
readonly checkIn?: CheckInDemand<TArgs>;
|
|
72
91
|
execute(args: TArgs, ctx: ToolExecutionContext): Promise<TResult> | TResult;
|
|
73
92
|
}
|
|
74
93
|
/**
|
package/dist/esm/core/tools.js
CHANGED
|
@@ -83,6 +83,9 @@ export function defineTool(options) {
|
|
|
83
83
|
inputSchema: options.inputSchema ?? { type: 'object', properties: {} },
|
|
84
84
|
},
|
|
85
85
|
...(options.needs && { needs: options.needs }),
|
|
86
|
+
// The call-site predicate is typed to TArgs; the stored Tool keeps the
|
|
87
|
+
// non-generic shape so it widens into `Tool[]` registries.
|
|
88
|
+
...(options.checkIn !== undefined && { checkIn: options.checkIn }),
|
|
86
89
|
execute: options.execute,
|
|
87
90
|
};
|
|
88
91
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/core/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/core/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA2FxC;;;;;;;;;;;;;;;;;;GAkBG;AACH;;;;;;;GAOG;AACH,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAC/C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,yDAAyD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAClF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,MAAM,MAAM,GACV,IAAI,CAAC,MAAM,GAAG,EAAE;YACd,CAAC,CAAC,SAAS,IAAI,CAAC,MAAM,iBAAiB;YACvC,CAAC,CAAC,mFAAmF,CAAC;QAC1F,MAAM,IAAI,KAAK,CACb,aAAa,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,MAAM,IAAI;YAC/C,sFAAsF;YACtF,wEAAwE;YACxE,0DAA0D,CAC7D,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAa;IACjD,IAAI,CAAC,SAAS,EAAE;QAAE,OAAO;IACzB,IAAI,CAAC;QACH,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,4BAA6B,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,OAA0C;IAE1C,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;SACvE;QACD,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QAC9C,uEAAuE;QACvE,2DAA2D;QAC3D,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAwB,EAAE,CAAC;QACnF,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;AACJ,CAAC"}
|