@steerable/agent-harness 0.6.2 → 0.6.4
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/dist/budget.d.ts +24 -0
- package/dist/budget.js +17 -1
- package/dist/generated/AskUserQuestionsPayload.d.ts +199 -9
- package/package.json +2 -2
package/dist/budget.d.ts
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
+
/** Default for {@link BudgetLimit.cachedTokenWeight}. */
|
|
2
|
+
export declare const DEFAULT_CACHED_TOKEN_WEIGHT = 0.1;
|
|
1
3
|
export interface BudgetLimit {
|
|
2
4
|
maxTokens: number;
|
|
3
5
|
maxSteps: number;
|
|
4
6
|
maxToolCalls: number;
|
|
7
|
+
/**
|
|
8
|
+
* Fraction of a normal token charged for prompt tokens the provider served
|
|
9
|
+
* from its cache. The token budget is a cost proxy, and a cache hit is
|
|
10
|
+
* priced well below a miss (~0.1x for Anthropic cache-read and DeepSeek
|
|
11
|
+
* cache-hit, ~0.5x for OpenAI cached input). An agentic turn re-sends a
|
|
12
|
+
* mostly identical prefix every round, so charging hits at par exhausts
|
|
13
|
+
* the budget several times sooner than the run's cost warrants. Hosts on
|
|
14
|
+
* providers with pricier caches raise it. Inert unless the caller reports
|
|
15
|
+
* `cachedTokens`; omitted → {@link DEFAULT_CACHED_TOKEN_WEIGHT}.
|
|
16
|
+
*/
|
|
17
|
+
cachedTokenWeight?: number;
|
|
5
18
|
}
|
|
6
19
|
export interface BudgetState {
|
|
7
20
|
tokensUsed: number;
|
|
@@ -9,10 +22,21 @@ export interface BudgetState {
|
|
|
9
22
|
toolCallsUsed: number;
|
|
10
23
|
}
|
|
11
24
|
export interface BudgetConsumeOptions {
|
|
25
|
+
/** The request's total usage. */
|
|
12
26
|
tokens?: number;
|
|
27
|
+
/** The subset of `tokens` served from the provider's prompt cache. */
|
|
28
|
+
cachedTokens?: number;
|
|
13
29
|
step?: boolean;
|
|
14
30
|
toolCall?: boolean;
|
|
15
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Charge one request against the budget, returning the new state.
|
|
34
|
+
*
|
|
35
|
+
* The cache discount is floored to an integer before subtraction so this
|
|
36
|
+
* stays bit-identical to the Python port (conformance case
|
|
37
|
+
* `cases/budget/cached.yaml`); a provider that reports more cached tokens
|
|
38
|
+
* than total clamps to a zero charge rather than refunding budget.
|
|
39
|
+
*/
|
|
16
40
|
export declare function consumeBudget(state: BudgetState, limits: BudgetLimit, options?: BudgetConsumeOptions): {
|
|
17
41
|
state: BudgetState;
|
|
18
42
|
exhausted: boolean;
|
package/dist/budget.js
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
|
+
/** Default for {@link BudgetLimit.cachedTokenWeight}. */
|
|
2
|
+
export const DEFAULT_CACHED_TOKEN_WEIGHT = 0.1;
|
|
3
|
+
/**
|
|
4
|
+
* Charge one request against the budget, returning the new state.
|
|
5
|
+
*
|
|
6
|
+
* The cache discount is floored to an integer before subtraction so this
|
|
7
|
+
* stays bit-identical to the Python port (conformance case
|
|
8
|
+
* `cases/budget/cached.yaml`); a provider that reports more cached tokens
|
|
9
|
+
* than total clamps to a zero charge rather than refunding budget.
|
|
10
|
+
*/
|
|
1
11
|
export function consumeBudget(state, limits, options = {}) {
|
|
12
|
+
let billedTokens = Math.max(options.tokens ?? 0, 0);
|
|
13
|
+
const cached = Math.max(options.cachedTokens ?? 0, 0);
|
|
14
|
+
if (cached) {
|
|
15
|
+
const weight = limits.cachedTokenWeight ?? DEFAULT_CACHED_TOKEN_WEIGHT;
|
|
16
|
+
billedTokens = Math.max(billedTokens - cached + Math.floor(cached * weight), 0);
|
|
17
|
+
}
|
|
2
18
|
const nextState = {
|
|
3
|
-
tokensUsed: state.tokensUsed +
|
|
19
|
+
tokensUsed: state.tokensUsed + billedTokens,
|
|
4
20
|
stepsUsed: state.stepsUsed + (options.step ? 1 : 0),
|
|
5
21
|
toolCallsUsed: state.toolCallsUsed + (options.toolCall ? 1 : 0),
|
|
6
22
|
};
|
|
@@ -7,14 +7,204 @@ export interface AskUserQuestionsPayload {
|
|
|
7
7
|
answers?: {
|
|
8
8
|
[k: string]: string | string[];
|
|
9
9
|
} | null;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @minItems 1
|
|
12
|
+
* @maxItems 4
|
|
13
|
+
*/
|
|
14
|
+
questions: [
|
|
15
|
+
{
|
|
16
|
+
id: string;
|
|
17
|
+
text: string;
|
|
18
|
+
/**
|
|
19
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
20
|
+
*/
|
|
21
|
+
header?: string;
|
|
22
|
+
type?: "select" | "text" | "password";
|
|
23
|
+
/**
|
|
24
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
25
|
+
*
|
|
26
|
+
* @minItems 2
|
|
27
|
+
* @maxItems 4
|
|
28
|
+
*/
|
|
29
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
30
|
+
placeholder?: string | null;
|
|
31
|
+
multiSelect?: boolean;
|
|
32
|
+
[k: string]: any;
|
|
33
|
+
}
|
|
34
|
+
] | [
|
|
35
|
+
{
|
|
36
|
+
id: string;
|
|
37
|
+
text: string;
|
|
38
|
+
/**
|
|
39
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
40
|
+
*/
|
|
41
|
+
header?: string;
|
|
42
|
+
type?: "select" | "text" | "password";
|
|
43
|
+
/**
|
|
44
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
45
|
+
*
|
|
46
|
+
* @minItems 2
|
|
47
|
+
* @maxItems 4
|
|
48
|
+
*/
|
|
49
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
50
|
+
placeholder?: string | null;
|
|
51
|
+
multiSelect?: boolean;
|
|
52
|
+
[k: string]: any;
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: string;
|
|
56
|
+
text: string;
|
|
57
|
+
/**
|
|
58
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
59
|
+
*/
|
|
60
|
+
header?: string;
|
|
61
|
+
type?: "select" | "text" | "password";
|
|
62
|
+
/**
|
|
63
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
64
|
+
*
|
|
65
|
+
* @minItems 2
|
|
66
|
+
* @maxItems 4
|
|
67
|
+
*/
|
|
68
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
69
|
+
placeholder?: string | null;
|
|
70
|
+
multiSelect?: boolean;
|
|
71
|
+
[k: string]: any;
|
|
72
|
+
}
|
|
73
|
+
] | [
|
|
74
|
+
{
|
|
75
|
+
id: string;
|
|
76
|
+
text: string;
|
|
77
|
+
/**
|
|
78
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
79
|
+
*/
|
|
80
|
+
header?: string;
|
|
81
|
+
type?: "select" | "text" | "password";
|
|
82
|
+
/**
|
|
83
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
84
|
+
*
|
|
85
|
+
* @minItems 2
|
|
86
|
+
* @maxItems 4
|
|
87
|
+
*/
|
|
88
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
89
|
+
placeholder?: string | null;
|
|
90
|
+
multiSelect?: boolean;
|
|
91
|
+
[k: string]: any;
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: string;
|
|
95
|
+
text: string;
|
|
96
|
+
/**
|
|
97
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
98
|
+
*/
|
|
99
|
+
header?: string;
|
|
100
|
+
type?: "select" | "text" | "password";
|
|
101
|
+
/**
|
|
102
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
103
|
+
*
|
|
104
|
+
* @minItems 2
|
|
105
|
+
* @maxItems 4
|
|
106
|
+
*/
|
|
107
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
108
|
+
placeholder?: string | null;
|
|
109
|
+
multiSelect?: boolean;
|
|
110
|
+
[k: string]: any;
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: string;
|
|
114
|
+
text: string;
|
|
115
|
+
/**
|
|
116
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
117
|
+
*/
|
|
118
|
+
header?: string;
|
|
119
|
+
type?: "select" | "text" | "password";
|
|
120
|
+
/**
|
|
121
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
122
|
+
*
|
|
123
|
+
* @minItems 2
|
|
124
|
+
* @maxItems 4
|
|
125
|
+
*/
|
|
126
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
127
|
+
placeholder?: string | null;
|
|
128
|
+
multiSelect?: boolean;
|
|
129
|
+
[k: string]: any;
|
|
130
|
+
}
|
|
131
|
+
] | [
|
|
132
|
+
{
|
|
133
|
+
id: string;
|
|
134
|
+
text: string;
|
|
135
|
+
/**
|
|
136
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
137
|
+
*/
|
|
138
|
+
header?: string;
|
|
139
|
+
type?: "select" | "text" | "password";
|
|
140
|
+
/**
|
|
141
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
142
|
+
*
|
|
143
|
+
* @minItems 2
|
|
144
|
+
* @maxItems 4
|
|
145
|
+
*/
|
|
146
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
147
|
+
placeholder?: string | null;
|
|
148
|
+
multiSelect?: boolean;
|
|
149
|
+
[k: string]: any;
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
id: string;
|
|
153
|
+
text: string;
|
|
154
|
+
/**
|
|
155
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
156
|
+
*/
|
|
157
|
+
header?: string;
|
|
158
|
+
type?: "select" | "text" | "password";
|
|
159
|
+
/**
|
|
160
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
161
|
+
*
|
|
162
|
+
* @minItems 2
|
|
163
|
+
* @maxItems 4
|
|
164
|
+
*/
|
|
165
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
166
|
+
placeholder?: string | null;
|
|
167
|
+
multiSelect?: boolean;
|
|
168
|
+
[k: string]: any;
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
id: string;
|
|
172
|
+
text: string;
|
|
173
|
+
/**
|
|
174
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
175
|
+
*/
|
|
176
|
+
header?: string;
|
|
177
|
+
type?: "select" | "text" | "password";
|
|
178
|
+
/**
|
|
179
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
180
|
+
*
|
|
181
|
+
* @minItems 2
|
|
182
|
+
* @maxItems 4
|
|
183
|
+
*/
|
|
184
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
185
|
+
placeholder?: string | null;
|
|
186
|
+
multiSelect?: boolean;
|
|
187
|
+
[k: string]: any;
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: string;
|
|
191
|
+
text: string;
|
|
192
|
+
/**
|
|
193
|
+
* Short chip label shown above the question (Claude Code AskUserQuestion parity). Optional; hosts derive one from `text` when absent.
|
|
194
|
+
*/
|
|
195
|
+
header?: string;
|
|
196
|
+
type?: "select" | "text" | "password";
|
|
197
|
+
/**
|
|
198
|
+
* Choices for a select question (2-4, CC parity). The host auto-appends an 'Other' free-text escape; the model does not list it.
|
|
199
|
+
*
|
|
200
|
+
* @minItems 2
|
|
201
|
+
* @maxItems 4
|
|
202
|
+
*/
|
|
203
|
+
options?: [string, string] | [string, string, string] | [string, string, string, string];
|
|
204
|
+
placeholder?: string | null;
|
|
205
|
+
multiSelect?: boolean;
|
|
206
|
+
[k: string]: any;
|
|
207
|
+
}
|
|
208
|
+
];
|
|
19
209
|
[k: string]: any;
|
|
20
210
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steerable/agent-harness",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.4",
|
|
4
4
|
"description": "Steerable framework Tier 2 — TypeScript facade over the Python harness (policy, budget, retry, completion, tracing) used for cross-language conformance tests. Production code should depend on the Python harness.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://steerableframework.com/",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"README.md"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@steerable/agent-protocol": "0.6.
|
|
32
|
+
"@steerable/agent-protocol": "0.6.4"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"typescript": "^5.8.3",
|