@myagentroam/agent 0.9.61 → 0.9.64
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/LICENSE +202 -0
- package/NOTICE +4 -0
- package/dist/cli/codex-auth-file.js +268 -3
- package/dist/cli/main.js +427 -2
- package/dist/error.js +66 -2
- package/dist/host/contracts.js +20 -2
- package/dist/host/local-agent-host.js +146 -2
- package/dist/host/local-process-executor.js +39 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +12 -2
- package/dist/model/anthropic-messages.js +474 -2
- package/dist/model/anthropic-thinking.js +33 -2
- package/dist/model/catalog-file.js +88 -2
- package/dist/model/configuration.js +137 -2
- package/dist/model/contracts.d.ts +2 -0
- package/dist/model/contracts.js +1 -2
- package/dist/model/http.js +529 -2
- package/dist/model/openai-responses.d.ts +2 -0
- package/dist/model/openai-responses.js +1602 -2
- package/dist/model/runtime-credential.js +35 -2
- package/dist/model/sse.js +199 -2
- package/dist/prompts/compact.js +25 -2
- package/dist/prompts/core.js +37 -2
- package/dist/prompts/execution-budget.js +10 -2
- package/dist/prompts/index.d.ts +3 -2
- package/dist/prompts/index.js +47 -2
- package/dist/prompts/modes.js +25 -2
- package/dist/prompts/output.js +1 -2
- package/dist/prompts/resources.d.ts +1 -1
- package/dist/prompts/resources.js +31 -2
- package/dist/prompts/subagent.d.ts +6 -0
- package/dist/prompts/subagent.js +29 -2
- package/dist/prompts/title.js +9 -2
- package/dist/prompts/workflow.js +32 -2
- package/dist/runtime/async-queue.js +62 -2
- package/dist/runtime/builtin-skills.js +19 -2
- package/dist/runtime/byted-ark-imagegen-skill.js +18 -2
- package/dist/runtime/codex-imagegen-skill.js +35 -2
- package/dist/runtime/compact.js +225 -2
- package/dist/runtime/context-gc-runtime.d.ts +35 -0
- package/dist/runtime/context-gc-runtime.js +163 -0
- package/dist/runtime/context-gc-tokens.d.ts +24 -0
- package/dist/runtime/context-gc-tokens.js +83 -0
- package/dist/runtime/context-gc.d.ts +66 -0
- package/dist/runtime/context-gc.js +909 -0
- package/dist/runtime/context-projection.d.ts +23 -0
- package/dist/runtime/context-projection.js +203 -0
- package/dist/runtime/environment-context.js +41 -2
- package/dist/runtime/execution-policy.js +13 -2
- package/dist/runtime/instructions.js +298 -2
- package/dist/runtime/normalize.js +40 -2
- package/dist/runtime/plan-output.js +95 -2
- package/dist/runtime/rollout-budget.d.ts +2 -0
- package/dist/runtime/rollout-budget.js +92 -2
- package/dist/runtime/token-budget.d.ts +2 -0
- package/dist/runtime/token-budget.js +44 -2
- package/dist/sdk/agent.js +1804 -2
- package/dist/sdk/types.d.ts +15 -5
- package/dist/sdk/types.js +1 -2
- package/dist/session/catalog.d.ts +5 -4
- package/dist/session/catalog.js +133 -2
- package/dist/session/context-gc-checkpoint.d.ts +148 -0
- package/dist/session/context-gc-checkpoint.js +665 -0
- package/dist/session/context-gc-replacements.d.ts +52 -0
- package/dist/session/context-gc-replacements.js +226 -0
- package/dist/session/context-gc-subagent.d.ts +43 -0
- package/dist/session/context-gc-subagent.js +267 -0
- package/dist/session/jsonl-store.d.ts +42 -4
- package/dist/session/jsonl-store.js +1657 -2
- package/dist/subagent/scheduler.d.ts +35 -2
- package/dist/subagent/scheduler.js +249 -2
- package/dist/subagent/session-controller.d.ts +94 -0
- package/dist/subagent/session-controller.js +675 -0
- package/dist/tools/agent-cancel.js +28 -2
- package/dist/tools/{task.d.ts → agent-message.d.ts} +2 -2
- package/dist/tools/agent-message.js +51 -0
- package/dist/tools/agent-start.js +84 -2
- package/dist/tools/agent-wait.js +53 -2
- package/dist/tools/apply-patch.js +478 -2
- package/dist/tools/code-mode.js +370 -2
- package/dist/tools/codex-image-gen.js +312 -2
- package/dist/tools/exec.js +455 -2
- package/dist/tools/execution-limits.d.ts +1 -0
- package/dist/tools/execution-limits.js +44 -2
- package/dist/tools/local-registry.js +233 -2
- package/dist/tools/local-workspace-tools.js +28 -2
- package/dist/tools/question.js +124 -2
- package/dist/tools/read-context.d.ts +16 -0
- package/dist/tools/read-context.js +85 -0
- package/dist/tools/read.d.ts +13 -0
- package/dist/tools/read.js +294 -2
- package/dist/tools/registry.js +76 -2
- package/dist/tools/runtime-context.d.ts +9 -2
- package/dist/tools/runtime-context.js +1 -2
- package/dist/tools/runtime.js +21 -2
- package/dist/tools/scheduler.js +41 -2
- package/dist/tools/shared/path-resolver.js +133 -2
- package/dist/tools/skill.js +37 -2
- package/dist/tools/todo-read.js +10 -2
- package/dist/tools/todo-write.js +65 -2
- package/dist/tools/todo.js +67 -2
- package/dist/tools/view-image.js +81 -2
- package/dist/tools/web-fetch.js +11 -2
- package/dist/tools/web-search.js +14 -2
- package/package.json +17 -15
- package/README.md +0 -3
- package/dist/runtime/prompt.d.ts +0 -9
- package/dist/runtime/prompt.js +0 -2
- package/dist/tools/shared/secret-redaction.d.ts +0 -4
- package/dist/tools/shared/secret-redaction.js +0 -2
- package/dist/tools/task-cancel.d.ts +0 -7
- package/dist/tools/task-cancel.js +0 -2
- package/dist/tools/task-output.d.ts +0 -7
- package/dist/tools/task-output.js +0 -2
- package/dist/tools/task-tools.d.ts +0 -36
- package/dist/tools/task-tools.js +0 -2
- package/dist/tools/task.js +0 -2
- package/dist/tools/todo-tools.d.ts +0 -25
- package/dist/tools/todo-tools.js +0 -2
|
@@ -1,2 +1,40 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// Normalization only shapes the model-visible request for one invocation; it
|
|
2
|
+
// never writes back to JSONL or the recoverable session history.
|
|
3
|
+
export function normalizeMessagesForModel(messages, input) {
|
|
4
|
+
const answered = new Set();
|
|
5
|
+
for (const message of messages)
|
|
6
|
+
if (message.role === 'tool' && typeof message.callId === 'string')
|
|
7
|
+
answered.add(message.callId);
|
|
8
|
+
const result = [];
|
|
9
|
+
for (const message of messages) {
|
|
10
|
+
result.push(stripUnsupportedImages(message, input));
|
|
11
|
+
const callId = pendingToolCallId(message);
|
|
12
|
+
if (!callId || answered.has(callId))
|
|
13
|
+
continue;
|
|
14
|
+
answered.add(callId);
|
|
15
|
+
result.push({
|
|
16
|
+
role: 'tool',
|
|
17
|
+
callId,
|
|
18
|
+
content: `[tool result unavailable for call ${callId}: the execution was interrupted before the result was recorded]`
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
function pendingToolCallId(message) {
|
|
24
|
+
if (message.role === 'tool_call')
|
|
25
|
+
return typeof message.callId === 'string' ? message.callId : undefined;
|
|
26
|
+
if (message.role !== 'provider' || !message.item)
|
|
27
|
+
return undefined;
|
|
28
|
+
const type = message.item['type'];
|
|
29
|
+
if (type !== 'function_call' && type !== 'custom_tool_call')
|
|
30
|
+
return undefined;
|
|
31
|
+
const callId = message.item['call_id'];
|
|
32
|
+
return typeof callId === 'string' ? callId : undefined;
|
|
33
|
+
}
|
|
34
|
+
function stripUnsupportedImages(message, input) {
|
|
35
|
+
if (input.supportsImages || !message.images?.length)
|
|
36
|
+
return message;
|
|
37
|
+
const rest = { ...message };
|
|
38
|
+
delete rest.images;
|
|
39
|
+
return rest;
|
|
40
|
+
}
|
|
@@ -1,2 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
1
|
+
const openTag = '<proposed_plan>';
|
|
2
|
+
const closeTag = '</proposed_plan>';
|
|
3
|
+
function nextFence(line, fence) {
|
|
4
|
+
const trimmed = line.trim();
|
|
5
|
+
const marker = /^(`{3,}|~{3,})/u.exec(trimmed)?.[1];
|
|
6
|
+
if (!fence)
|
|
7
|
+
return marker;
|
|
8
|
+
return marker && marker[0] === fence[0] && marker.length >= fence.length && trimmed === marker
|
|
9
|
+
? undefined
|
|
10
|
+
: fence;
|
|
11
|
+
}
|
|
12
|
+
/** Only standalone, unfenced delimiters declare a plan, never prose or examples. */
|
|
13
|
+
export function splitPlanOutput(text) {
|
|
14
|
+
const parts = [];
|
|
15
|
+
let normal = '';
|
|
16
|
+
let plan;
|
|
17
|
+
let opening = '';
|
|
18
|
+
let fence;
|
|
19
|
+
const flushNormal = () => {
|
|
20
|
+
if (normal)
|
|
21
|
+
parts.push({ kind: 'message', text: normal });
|
|
22
|
+
normal = '';
|
|
23
|
+
};
|
|
24
|
+
for (const line of text.match(/[^\n]*\n|[^\n]+$/gu) ?? []) {
|
|
25
|
+
const trimmed = line.trim();
|
|
26
|
+
const previousFence = fence;
|
|
27
|
+
fence = nextFence(line, fence);
|
|
28
|
+
if (!previousFence && !fence && trimmed === openTag && plan === undefined) {
|
|
29
|
+
opening = line;
|
|
30
|
+
plan = '';
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
else if (!previousFence && !fence && trimmed === closeTag && plan !== undefined) {
|
|
34
|
+
if (plan.trim()) {
|
|
35
|
+
flushNormal();
|
|
36
|
+
parts.push({ kind: 'plan', text: plan.trim() });
|
|
37
|
+
}
|
|
38
|
+
else
|
|
39
|
+
normal += opening + plan + line;
|
|
40
|
+
plan = undefined;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (plan === undefined)
|
|
44
|
+
normal += line;
|
|
45
|
+
else
|
|
46
|
+
plan += line;
|
|
47
|
+
}
|
|
48
|
+
if (plan !== undefined)
|
|
49
|
+
normal += opening + plan;
|
|
50
|
+
flushNormal();
|
|
51
|
+
return parts;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Stream ordinary prose immediately. Once a possible plan delimiter starts,
|
|
55
|
+
* defer the remainder until text.completed can establish the complete boundary.
|
|
56
|
+
*/
|
|
57
|
+
export class PlanOutputPrefix {
|
|
58
|
+
#line = '';
|
|
59
|
+
#pending = '';
|
|
60
|
+
#blocked = false;
|
|
61
|
+
#ordinaryLine = false;
|
|
62
|
+
#fence;
|
|
63
|
+
push(delta) {
|
|
64
|
+
if (this.#blocked)
|
|
65
|
+
return '';
|
|
66
|
+
let output = '';
|
|
67
|
+
for (const character of delta) {
|
|
68
|
+
this.#line += character;
|
|
69
|
+
if (character === '\n') {
|
|
70
|
+
if (!this.#fence && this.#line.trim() === openTag) {
|
|
71
|
+
this.#blocked = true;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
output += this.#pending + character;
|
|
75
|
+
this.#fence = nextFence(this.#line, this.#fence);
|
|
76
|
+
this.#pending = '';
|
|
77
|
+
this.#line = '';
|
|
78
|
+
this.#ordinaryLine = false;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (this.#ordinaryLine) {
|
|
82
|
+
output += character;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
this.#pending += character;
|
|
86
|
+
const candidate = this.#line.trim();
|
|
87
|
+
if (this.#fence || !openTag.startsWith(candidate)) {
|
|
88
|
+
output += this.#pending;
|
|
89
|
+
this.#pending = '';
|
|
90
|
+
this.#ordinaryLine = true;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return output;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -12,11 +12,13 @@ export declare class RolloutBudget {
|
|
|
12
12
|
#private;
|
|
13
13
|
readonly options: ResolvedRolloutBudgetOptions;
|
|
14
14
|
constructor(options: ResolvedRolloutBudgetOptions);
|
|
15
|
+
get active(): boolean;
|
|
15
16
|
get limitTokens(): number;
|
|
16
17
|
get spentTokens(): number;
|
|
17
18
|
get remainingTokens(): number;
|
|
18
19
|
get stage(): RolloutBudgetStage;
|
|
19
20
|
recordUsage(usage: ModelUsage | undefined): number;
|
|
21
|
+
discard(): void;
|
|
20
22
|
}
|
|
21
23
|
export declare function resolveRolloutBudgetOptions(options: false | RolloutBudgetOptions | undefined): ResolvedRolloutBudgetOptions | undefined;
|
|
22
24
|
export declare function createRolloutBudget(options: false | RolloutBudgetOptions | undefined): RolloutBudget | undefined;
|
|
@@ -1,2 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { MarAgentError } from '../error.js';
|
|
2
|
+
import { AGENT_EXECUTION_POLICY } from './execution-policy.js';
|
|
3
|
+
export class RolloutBudget {
|
|
4
|
+
options;
|
|
5
|
+
#spentTokens = 0;
|
|
6
|
+
#active = true;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.options = options;
|
|
9
|
+
}
|
|
10
|
+
get active() {
|
|
11
|
+
return this.#active;
|
|
12
|
+
}
|
|
13
|
+
get limitTokens() {
|
|
14
|
+
return this.options.limitTokens;
|
|
15
|
+
}
|
|
16
|
+
get spentTokens() {
|
|
17
|
+
return this.#spentTokens;
|
|
18
|
+
}
|
|
19
|
+
get remainingTokens() {
|
|
20
|
+
return Math.max(0, this.limitTokens - this.#spentTokens);
|
|
21
|
+
}
|
|
22
|
+
get stage() {
|
|
23
|
+
if (!this.#active)
|
|
24
|
+
return 'normal';
|
|
25
|
+
const remaining = this.remainingTokens;
|
|
26
|
+
if (remaining <= 0)
|
|
27
|
+
return 'exhausted';
|
|
28
|
+
if (remaining <= this.options.finalizeAtRemainingTokens)
|
|
29
|
+
return 'finalize';
|
|
30
|
+
if (remaining <= this.options.conserveAtRemainingTokens)
|
|
31
|
+
return 'conserve';
|
|
32
|
+
return 'normal';
|
|
33
|
+
}
|
|
34
|
+
recordUsage(usage) {
|
|
35
|
+
if (!this.#active || !usage)
|
|
36
|
+
return 0;
|
|
37
|
+
const providerUnits = usage.rolloutBudgetUnits;
|
|
38
|
+
if (providerUnits !== undefined && (!Number.isFinite(providerUnits) || providerUnits < 0))
|
|
39
|
+
throw new MarAgentError('MAR_AGENT_MODEL_PROTOCOL_ERROR', 'Provider rollout budget units are invalid.');
|
|
40
|
+
const charged = providerUnits ??
|
|
41
|
+
nonnegative(usage.outputTokens) * this.options.samplingTokenWeight +
|
|
42
|
+
Math.max(nonnegative(usage.contextInputTokens ?? usage.inputTokens) -
|
|
43
|
+
nonnegative(usage.cacheReadTokens), 0) *
|
|
44
|
+
this.options.prefillTokenWeight;
|
|
45
|
+
this.#spentTokens += charged;
|
|
46
|
+
return charged;
|
|
47
|
+
}
|
|
48
|
+
discard() {
|
|
49
|
+
this.#active = false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function resolveRolloutBudgetOptions(options) {
|
|
53
|
+
if (options === false)
|
|
54
|
+
return undefined;
|
|
55
|
+
const limitTokens = options?.limitTokens ?? AGENT_EXECUTION_POLICY.rolloutBudgetTokens;
|
|
56
|
+
if (!Number.isSafeInteger(limitTokens) || limitTokens < 2)
|
|
57
|
+
return invalid();
|
|
58
|
+
const conserveAtRemainingTokens = options?.conserveAtRemainingTokens ??
|
|
59
|
+
Math.min(AGENT_EXECUTION_POLICY.rolloutBudgetConserveRemainingTokens, Math.max(1, Math.floor(limitTokens * 0.28)));
|
|
60
|
+
const finalizeAtRemainingTokens = options?.finalizeAtRemainingTokens ??
|
|
61
|
+
Math.min(AGENT_EXECUTION_POLICY.rolloutBudgetFinalizeRemainingTokens, Math.max(0, Math.min(conserveAtRemainingTokens - 1, Math.floor(limitTokens * 0.16))));
|
|
62
|
+
const samplingTokenWeight = options?.samplingTokenWeight ?? AGENT_EXECUTION_POLICY.rolloutBudgetSamplingTokenWeight;
|
|
63
|
+
const prefillTokenWeight = options?.prefillTokenWeight ?? AGENT_EXECUTION_POLICY.rolloutBudgetPrefillTokenWeight;
|
|
64
|
+
if (!Number.isSafeInteger(conserveAtRemainingTokens) ||
|
|
65
|
+
conserveAtRemainingTokens < 0 ||
|
|
66
|
+
conserveAtRemainingTokens >= limitTokens ||
|
|
67
|
+
!Number.isSafeInteger(finalizeAtRemainingTokens) ||
|
|
68
|
+
finalizeAtRemainingTokens < 0 ||
|
|
69
|
+
finalizeAtRemainingTokens >= conserveAtRemainingTokens ||
|
|
70
|
+
!Number.isFinite(samplingTokenWeight) ||
|
|
71
|
+
samplingTokenWeight < 0 ||
|
|
72
|
+
!Number.isFinite(prefillTokenWeight) ||
|
|
73
|
+
prefillTokenWeight < 0)
|
|
74
|
+
return invalid();
|
|
75
|
+
return {
|
|
76
|
+
limitTokens,
|
|
77
|
+
conserveAtRemainingTokens,
|
|
78
|
+
finalizeAtRemainingTokens,
|
|
79
|
+
samplingTokenWeight,
|
|
80
|
+
prefillTokenWeight
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export function createRolloutBudget(options) {
|
|
84
|
+
const resolved = resolveRolloutBudgetOptions(options);
|
|
85
|
+
return resolved ? new RolloutBudget(resolved) : undefined;
|
|
86
|
+
}
|
|
87
|
+
function nonnegative(value) {
|
|
88
|
+
return value !== undefined && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
89
|
+
}
|
|
90
|
+
function invalid() {
|
|
91
|
+
throw new MarAgentError('MAR_AGENT_ROLLOUT_BUDGET_INVALID', 'Rollout budget configuration is invalid.');
|
|
92
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare const MODEL_TOKEN_ESTIMATOR: "UTF8_BYTES_V1";
|
|
2
|
+
/** Local budget estimate only; provider usage remains authoritative. */
|
|
1
3
|
export declare function countModelTokens(value: string): number;
|
|
2
4
|
export declare function truncateModelText(value: string, maximumTokens: number, omittedLabel?: string): {
|
|
3
5
|
content: string;
|
|
@@ -1,2 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
1
|
+
export const MODEL_TOKEN_ESTIMATOR = 'UTF8_BYTES_V1';
|
|
2
|
+
const BYTES_PER_TOKEN = 4;
|
|
3
|
+
/** Local budget estimate only; provider usage remains authoritative. */
|
|
4
|
+
export function countModelTokens(value) {
|
|
5
|
+
return Math.ceil(Buffer.byteLength(value, 'utf8') / BYTES_PER_TOKEN);
|
|
6
|
+
}
|
|
7
|
+
export function truncateModelText(value, maximumTokens, omittedLabel = 'tool output') {
|
|
8
|
+
const tokens = countModelTokens(value);
|
|
9
|
+
if (tokens <= maximumTokens)
|
|
10
|
+
return { content: value, truncated: false, omittedTokens: 0 };
|
|
11
|
+
const maximumBytes = Math.max(0, Math.floor(maximumTokens)) * BYTES_PER_TOKEN;
|
|
12
|
+
const bytes = Buffer.from(value, 'utf8');
|
|
13
|
+
let retainedBytes = Math.max(0, maximumBytes - 16 * BYTES_PER_TOKEN);
|
|
14
|
+
for (let attempt = 0; attempt < 8; attempt++) {
|
|
15
|
+
let head = Math.ceil(retainedBytes / 2);
|
|
16
|
+
let tail = bytes.length - Math.floor(retainedBytes / 2);
|
|
17
|
+
// Move cuts away from retained characters, never through a UTF-8 code point.
|
|
18
|
+
while (head > 0 && isContinuationByte(bytes[head]))
|
|
19
|
+
head--;
|
|
20
|
+
while (tail < bytes.length && isContinuationByte(bytes[tail]))
|
|
21
|
+
tail++;
|
|
22
|
+
const omittedTokens = Math.ceil((tail - head) / BYTES_PER_TOKEN);
|
|
23
|
+
const marker = `\n...[${omittedTokens} tokens of ${omittedLabel} omitted]...\n`;
|
|
24
|
+
const candidateBytes = head + Buffer.byteLength(marker, 'utf8') + bytes.length - tail;
|
|
25
|
+
if (candidateBytes <= maximumBytes)
|
|
26
|
+
return {
|
|
27
|
+
content: `${bytes.toString('utf8', 0, head)}${marker}${bytes.toString('utf8', tail)}`,
|
|
28
|
+
truncated: true,
|
|
29
|
+
omittedTokens
|
|
30
|
+
};
|
|
31
|
+
if (retainedBytes === 0)
|
|
32
|
+
break;
|
|
33
|
+
retainedBytes = Math.max(0, retainedBytes - (candidateBytes - maximumBytes));
|
|
34
|
+
}
|
|
35
|
+
const marker = `\n...[${tokens} tokens of ${omittedLabel} omitted]...\n`;
|
|
36
|
+
return {
|
|
37
|
+
content: countModelTokens(marker) <= maximumTokens ? marker : '',
|
|
38
|
+
truncated: true,
|
|
39
|
+
omittedTokens: tokens
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function isContinuationByte(byte) {
|
|
43
|
+
return byte !== undefined && (byte & 0xc0) === 0x80;
|
|
44
|
+
}
|