@moxxy/mode-goal 0.26.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/LICENSE +21 -0
- package/dist/completion.d.ts +20 -0
- package/dist/completion.d.ts.map +1 -0
- package/dist/completion.js +48 -0
- package/dist/completion.js.map +1 -0
- package/dist/constants.d.ts +50 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +65 -0
- package/dist/constants.js.map +1 -0
- package/dist/goal-loop.d.ts +34 -0
- package/dist/goal-loop.d.ts.map +1 -0
- package/dist/goal-loop.js +454 -0
- package/dist/goal-loop.js.map +1 -0
- package/dist/goal-tools.d.ts +14 -0
- package/dist/goal-tools.d.ts.map +1 -0
- package/dist/goal-tools.js +55 -0
- package/dist/goal-tools.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/package.json +65 -0
- package/src/completion.test.ts +68 -0
- package/src/completion.ts +55 -0
- package/src/constants.ts +75 -0
- package/src/goal-loop.ts +523 -0
- package/src/goal-tools.ts +61 -0
- package/src/index.test.ts +577 -0
- package/src/index.ts +28 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Moxxy (moxxy.ai)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CollectedToolUse, MoxxyEvent } from '@moxxy/sdk';
|
|
2
|
+
export type GoalTerminal = {
|
|
3
|
+
kind: 'complete';
|
|
4
|
+
summary: string;
|
|
5
|
+
evidence: string[];
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'abandon';
|
|
8
|
+
reason: string;
|
|
9
|
+
needsFromUser?: string;
|
|
10
|
+
} | null;
|
|
11
|
+
/**
|
|
12
|
+
* Inspect a just-executed batch of tool uses for a terminal goal signal. We
|
|
13
|
+
* confirm against the event log that the goal tool's `tool_result` actually
|
|
14
|
+
* succeeded (`ok: true`) — a hook could in principle have denied the call — so
|
|
15
|
+
* a denied goal_complete doesn't silently end the run. Returns the parsed
|
|
16
|
+
* payload (pulled from the model's tool INPUT, which is what it intended) so
|
|
17
|
+
* the caller can surface a clean summary.
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectGoalTerminal(log: ReadonlyArray<MoxxyEvent>, batch: ReadonlyArray<CollectedToolUse>): GoalTerminal;
|
|
20
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI/D,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3D,IAAI,CAAC;AAET;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC,EAC9B,KAAK,EAAE,aAAa,CAAC,gBAAgB,CAAC,GACrC,YAAY,CAkCd"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { GOAL_ABANDON_TOOL, GOAL_COMPLETE_TOOL } from './constants.js';
|
|
2
|
+
/**
|
|
3
|
+
* Inspect a just-executed batch of tool uses for a terminal goal signal. We
|
|
4
|
+
* confirm against the event log that the goal tool's `tool_result` actually
|
|
5
|
+
* succeeded (`ok: true`) — a hook could in principle have denied the call — so
|
|
6
|
+
* a denied goal_complete doesn't silently end the run. Returns the parsed
|
|
7
|
+
* payload (pulled from the model's tool INPUT, which is what it intended) so
|
|
8
|
+
* the caller can surface a clean summary.
|
|
9
|
+
*/
|
|
10
|
+
export function detectGoalTerminal(log, batch) {
|
|
11
|
+
// Map callId -> the goal tool use, so we only react to OUR tools.
|
|
12
|
+
const goalCalls = new Map();
|
|
13
|
+
for (const t of batch) {
|
|
14
|
+
if (t.name === GOAL_COMPLETE_TOOL || t.name === GOAL_ABANDON_TOOL)
|
|
15
|
+
goalCalls.set(t.id, t);
|
|
16
|
+
}
|
|
17
|
+
if (goalCalls.size === 0)
|
|
18
|
+
return null;
|
|
19
|
+
// Walk the log tail for the most recent successful result of one of those.
|
|
20
|
+
for (let i = log.length - 1; i >= 0; i--) {
|
|
21
|
+
const e = log[i];
|
|
22
|
+
if (!e || e.type !== 'tool_result' || !e.ok)
|
|
23
|
+
continue;
|
|
24
|
+
const call = goalCalls.get(String(e.callId));
|
|
25
|
+
if (!call)
|
|
26
|
+
continue;
|
|
27
|
+
const input = (call.input ?? {});
|
|
28
|
+
if (call.name === GOAL_COMPLETE_TOOL) {
|
|
29
|
+
return {
|
|
30
|
+
kind: 'complete',
|
|
31
|
+
summary: typeof input.summary === 'string' ? input.summary : 'Goal completed.',
|
|
32
|
+
// `input` is the RAW provider-emitted tool input (pre-zod), so the model
|
|
33
|
+
// can put anything in `evidence`. Keep only the string elements rather
|
|
34
|
+
// than asserting the type with an unchecked cast.
|
|
35
|
+
evidence: Array.isArray(input.evidence)
|
|
36
|
+
? input.evidence.filter((x) => typeof x === 'string')
|
|
37
|
+
: [],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
kind: 'abandon',
|
|
42
|
+
reason: typeof input.reason === 'string' ? input.reason : 'Goal abandoned.',
|
|
43
|
+
...(typeof input.needsFromUser === 'string' ? { needsFromUser: input.needsFromUser } : {}),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=completion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.js","sourceRoot":"","sources":["../src/completion.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAOvE;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,GAA8B,EAC9B,KAAsC;IAEtC,kEAAkE;IAClE,MAAM,SAAS,GAAG,IAAI,GAAG,EAA4B,CAAC;IACtD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB;YAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,2EAA2E;IAC3E,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,SAAS;QACtD,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;QAC5D,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACrC,OAAO;gBACL,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB;gBAC9E,yEAAyE;gBACzE,uEAAuE;gBACvE,kDAAkD;gBAClD,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;oBACrC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;oBAClE,CAAC,CAAC,EAAE;aACP,CAAC;QACJ,CAAC;QACD,OAAO;YACL,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB;YAC3E,GAAG,CAAC,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3F,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export declare const GOAL_MODE_NAME = "goal";
|
|
2
|
+
export declare const GOAL_PLUGIN_ID: import("@moxxy/sdk").PluginId;
|
|
3
|
+
/** Tool the model MUST call to declare the goal achieved (the terminator). */
|
|
4
|
+
export declare const GOAL_COMPLETE_TOOL = "goal_complete";
|
|
5
|
+
/** Tool the model calls to give up gracefully (blocked, needs the user). */
|
|
6
|
+
export declare const GOAL_ABANDON_TOOL = "goal_abandon";
|
|
7
|
+
/**
|
|
8
|
+
* Hard cap on autonomous iterations. Goal mode keeps re-prompting the model to
|
|
9
|
+
* continue until it calls {@link GOAL_COMPLETE_TOOL}; this is the backstop that
|
|
10
|
+
* guarantees the loop terminates even if the model never declares done. High
|
|
11
|
+
* enough for a substantial multi-step task, low enough to bound a runaway.
|
|
12
|
+
*/
|
|
13
|
+
export declare const GOAL_MAX_ITERATIONS = 150;
|
|
14
|
+
/**
|
|
15
|
+
* Consecutive iterations where the model emits NO tool calls and hasn't
|
|
16
|
+
* completed. After this many we stop (a stall) rather than spin forever
|
|
17
|
+
* nudging a model that has decided it's done without saying so.
|
|
18
|
+
*/
|
|
19
|
+
export declare const GOAL_MAX_NOOP_ITERATIONS = 3;
|
|
20
|
+
/**
|
|
21
|
+
* Cumulative token ceiling (full prompt — input + cacheRead + cacheCreation +
|
|
22
|
+
* output — across the whole goal run). A second backstop alongside the
|
|
23
|
+
* iteration cap: a few long-context iterations can burn a lot of tokens even
|
|
24
|
+
* under the iteration limit. Generous; the iteration cap is usually the binding
|
|
25
|
+
* guard.
|
|
26
|
+
*/
|
|
27
|
+
export declare const GOAL_TOKEN_BUDGET = 4000000;
|
|
28
|
+
/**
|
|
29
|
+
* Max consecutive retryable provider errors before goal mode bails with a fatal
|
|
30
|
+
* error. Goal mode runs unattended with auto-approval, so a sustained retryable
|
|
31
|
+
* condition (429 / overloaded / transient 5xx / ECONNRESET) must NOT busy-loop
|
|
32
|
+
* the provider — back off exponentially and give up after this many in a row.
|
|
33
|
+
* The counter resets on any clean provider call, so a long run can still
|
|
34
|
+
* recover from transient blips.
|
|
35
|
+
*/
|
|
36
|
+
export declare const MAX_CONSECUTIVE_RETRIES = 6;
|
|
37
|
+
/**
|
|
38
|
+
* Layered on top of any user system prompt for the whole goal run. The framing
|
|
39
|
+
* is the inverse of normal chat: stopping is NOT the signal to end — the model
|
|
40
|
+
* keeps going until it explicitly calls goal_complete. It runs unattended with
|
|
41
|
+
* tool calls auto-approved, so it must be conservative about irreversible
|
|
42
|
+
* actions and decisive about declaring done.
|
|
43
|
+
*/
|
|
44
|
+
export declare const GOAL_SYSTEM_PROMPT = "You are operating in GOAL MODE. The user has given you a goal and you will work on it AUTONOMOUSLY, across as many steps as it takes, until it is genuinely done. You are running unattended \u2014 the user is not watching each step and your tool calls are auto-approved \u2014 so act like a careful senior engineer who has been handed the keys.\n\nHow goal mode ends \u2014 this is the most important rule:\n- The loop does NOT end when you stop talking. It ends ONLY when you call the `goal_complete` tool. If you produce a message without tool calls, you will simply be prompted to continue.\n- When (and only when) the goal is FULLY achieved AND you have verified it, call `goal_complete` with a short summary and concrete evidence (commands you ran and their results, files you changed, tests that passed).\n- If you become genuinely blocked \u2014 a missing credential, a destructive action you shouldn't take unattended, or a requirement too ambiguous to proceed on \u2014 call `goal_abandon` with the reason and exactly what you need from the user. Do NOT spin on something you cannot resolve.\n\nWhile working:\n- Break the goal into steps and just do them \u2014 don't stop to ask for confirmation on routine work; you have autonomy for this run.\n- Verify your work as you go (run the project's tests / build / linter when relevant) before declaring the goal complete.\n- Be careful with irreversible or destructive operations (deleting data, force-pushing, external side effects). When something is high-stakes and reversible-only-by-the-user, prefer to `goal_abandon` and ask rather than guess.\n- Don't repeat the same failing action. If an approach isn't working, change it; if nothing works, abandon with a clear explanation.\n- Don't declare the goal complete prematurely. \"I think this should work\" is not done \u2014 verify first.";
|
|
45
|
+
/** Trailing nudge appended when the model idles (no tool calls) without
|
|
46
|
+
* completing — reminds it the loop only ends via the completion tool. */
|
|
47
|
+
export declare const CONTINUE_NUDGE: string;
|
|
48
|
+
/** Sharper nudge once the model has idled repeatedly. */
|
|
49
|
+
export declare const STALL_NUDGE: string;
|
|
50
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,SAAS,CAAC;AACrC,eAAO,MAAM,cAAc,+BAAiC,CAAC;AAE7D,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAClD,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAE3C;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,8zDAYuE,CAAC;AAEvG;0EAC0E;AAC1E,eAAO,MAAM,cAAc,QAE8D,CAAC;AAE1F,yDAAyD;AACzD,eAAO,MAAM,WAAW,QAEmG,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { asPluginId } from '@moxxy/sdk';
|
|
2
|
+
export const GOAL_MODE_NAME = 'goal';
|
|
3
|
+
export const GOAL_PLUGIN_ID = asPluginId('@moxxy/mode-goal');
|
|
4
|
+
/** Tool the model MUST call to declare the goal achieved (the terminator). */
|
|
5
|
+
export const GOAL_COMPLETE_TOOL = 'goal_complete';
|
|
6
|
+
/** Tool the model calls to give up gracefully (blocked, needs the user). */
|
|
7
|
+
export const GOAL_ABANDON_TOOL = 'goal_abandon';
|
|
8
|
+
/**
|
|
9
|
+
* Hard cap on autonomous iterations. Goal mode keeps re-prompting the model to
|
|
10
|
+
* continue until it calls {@link GOAL_COMPLETE_TOOL}; this is the backstop that
|
|
11
|
+
* guarantees the loop terminates even if the model never declares done. High
|
|
12
|
+
* enough for a substantial multi-step task, low enough to bound a runaway.
|
|
13
|
+
*/
|
|
14
|
+
export const GOAL_MAX_ITERATIONS = 150;
|
|
15
|
+
/**
|
|
16
|
+
* Consecutive iterations where the model emits NO tool calls and hasn't
|
|
17
|
+
* completed. After this many we stop (a stall) rather than spin forever
|
|
18
|
+
* nudging a model that has decided it's done without saying so.
|
|
19
|
+
*/
|
|
20
|
+
export const GOAL_MAX_NOOP_ITERATIONS = 3;
|
|
21
|
+
/**
|
|
22
|
+
* Cumulative token ceiling (full prompt — input + cacheRead + cacheCreation +
|
|
23
|
+
* output — across the whole goal run). A second backstop alongside the
|
|
24
|
+
* iteration cap: a few long-context iterations can burn a lot of tokens even
|
|
25
|
+
* under the iteration limit. Generous; the iteration cap is usually the binding
|
|
26
|
+
* guard.
|
|
27
|
+
*/
|
|
28
|
+
export const GOAL_TOKEN_BUDGET = 4_000_000;
|
|
29
|
+
/**
|
|
30
|
+
* Max consecutive retryable provider errors before goal mode bails with a fatal
|
|
31
|
+
* error. Goal mode runs unattended with auto-approval, so a sustained retryable
|
|
32
|
+
* condition (429 / overloaded / transient 5xx / ECONNRESET) must NOT busy-loop
|
|
33
|
+
* the provider — back off exponentially and give up after this many in a row.
|
|
34
|
+
* The counter resets on any clean provider call, so a long run can still
|
|
35
|
+
* recover from transient blips.
|
|
36
|
+
*/
|
|
37
|
+
export const MAX_CONSECUTIVE_RETRIES = 6;
|
|
38
|
+
/**
|
|
39
|
+
* Layered on top of any user system prompt for the whole goal run. The framing
|
|
40
|
+
* is the inverse of normal chat: stopping is NOT the signal to end — the model
|
|
41
|
+
* keeps going until it explicitly calls goal_complete. It runs unattended with
|
|
42
|
+
* tool calls auto-approved, so it must be conservative about irreversible
|
|
43
|
+
* actions and decisive about declaring done.
|
|
44
|
+
*/
|
|
45
|
+
export const GOAL_SYSTEM_PROMPT = `You are operating in GOAL MODE. The user has given you a goal and you will work on it AUTONOMOUSLY, across as many steps as it takes, until it is genuinely done. You are running unattended — the user is not watching each step and your tool calls are auto-approved — so act like a careful senior engineer who has been handed the keys.
|
|
46
|
+
|
|
47
|
+
How goal mode ends — this is the most important rule:
|
|
48
|
+
- The loop does NOT end when you stop talking. It ends ONLY when you call the \`${GOAL_COMPLETE_TOOL}\` tool. If you produce a message without tool calls, you will simply be prompted to continue.
|
|
49
|
+
- When (and only when) the goal is FULLY achieved AND you have verified it, call \`${GOAL_COMPLETE_TOOL}\` with a short summary and concrete evidence (commands you ran and their results, files you changed, tests that passed).
|
|
50
|
+
- If you become genuinely blocked — a missing credential, a destructive action you shouldn't take unattended, or a requirement too ambiguous to proceed on — call \`${GOAL_ABANDON_TOOL}\` with the reason and exactly what you need from the user. Do NOT spin on something you cannot resolve.
|
|
51
|
+
|
|
52
|
+
While working:
|
|
53
|
+
- Break the goal into steps and just do them — don't stop to ask for confirmation on routine work; you have autonomy for this run.
|
|
54
|
+
- Verify your work as you go (run the project's tests / build / linter when relevant) before declaring the goal complete.
|
|
55
|
+
- Be careful with irreversible or destructive operations (deleting data, force-pushing, external side effects). When something is high-stakes and reversible-only-by-the-user, prefer to \`${GOAL_ABANDON_TOOL}\` and ask rather than guess.
|
|
56
|
+
- Don't repeat the same failing action. If an approach isn't working, change it; if nothing works, abandon with a clear explanation.
|
|
57
|
+
- Don't declare the goal complete prematurely. "I think this should work" is not done — verify first.`;
|
|
58
|
+
/** Trailing nudge appended when the model idles (no tool calls) without
|
|
59
|
+
* completing — reminds it the loop only ends via the completion tool. */
|
|
60
|
+
export const CONTINUE_NUDGE = `You stopped without calling \`${GOAL_COMPLETE_TOOL}\`. If the goal is fully achieved AND verified, ` +
|
|
61
|
+
`call \`${GOAL_COMPLETE_TOOL}\` now. Otherwise, take the next concrete step toward it.`;
|
|
62
|
+
/** Sharper nudge once the model has idled repeatedly. */
|
|
63
|
+
export const STALL_NUDGE = `You have produced no tool calls for several turns. Either take a concrete next action toward the goal, ` +
|
|
64
|
+
`or call \`${GOAL_COMPLETE_TOOL}\` (if done) / \`${GOAL_ABANDON_TOOL}\` (if blocked). Do not reply with only text again.`;
|
|
65
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;AAE7D,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAClD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;kFAGgD,kBAAkB;qFACf,kBAAkB;sKAC+D,iBAAiB;;;;;6LAKM,iBAAiB;;sGAExG,CAAC;AAEvG;0EAC0E;AAC1E,MAAM,CAAC,MAAM,cAAc,GACzB,iCAAiC,kBAAkB,kDAAkD;IACrG,UAAU,kBAAkB,2DAA2D,CAAC;AAE1F,yDAAyD;AACzD,MAAM,CAAC,MAAM,WAAW,GACtB,yGAAyG;IACzG,aAAa,kBAAkB,oBAAoB,iBAAiB,qDAAqD,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ModeContext, type MoxxyEvent } from '@moxxy/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Override the retry back-off sleep (test seam). Returns a restore fn that
|
|
4
|
+
* callers MUST invoke (in a `finally`) — `sleepImpl` is a module-scoped
|
|
5
|
+
* singleton shared process-wide, so a leaked override bleeds the fake sleep
|
|
6
|
+
* into every other turn/test running in the same worker. Test-only.
|
|
7
|
+
*/
|
|
8
|
+
export declare function __setRetrySleepForTests(fn: (ms: number, signal: AbortSignal) => Promise<void>): () => void;
|
|
9
|
+
/**
|
|
10
|
+
* Goal mode driver.
|
|
11
|
+
*
|
|
12
|
+
* Unlike tool-use (which returns the instant the model stops emitting tools),
|
|
13
|
+
* goal mode treats "stopped emitting tools" as a cue to re-prompt: it keeps
|
|
14
|
+
* the model working autonomously across iterations until the model explicitly
|
|
15
|
+
* calls `goal_complete` (success) or `goal_abandon` (blocked). Every iteration
|
|
16
|
+
* is guarded so the loop always terminates:
|
|
17
|
+
*
|
|
18
|
+
* - hard iteration cap (`maxIterations`)
|
|
19
|
+
* - cumulative token budget
|
|
20
|
+
* - stuck-loop detector (same identical-call detection as tool-use)
|
|
21
|
+
* - no-progress detection (repeated idle iterations → stall stop)
|
|
22
|
+
* - `ctx.signal.aborted` checked every iteration and mid tool batch
|
|
23
|
+
*
|
|
24
|
+
* Tool calls are auto-approved for the whole run (the user opted into full
|
|
25
|
+
* autonomy) by swapping in a resolver that replaces only the PROMPT path:
|
|
26
|
+
* the session resolver's prompt-free `policyCheck` (user deny/allow rules
|
|
27
|
+
* from ~/.moxxy/permissions.json plus tool-declared rules) is consulted
|
|
28
|
+
* first, so a configured deny rule still denies here. Every call also still
|
|
29
|
+
* flows through `dispatchToolCall`, so tool-call HOOKS (e.g. a security
|
|
30
|
+
* plugin) still run and can deny. Auto-approve skips the prompt, not the
|
|
31
|
+
* policy.
|
|
32
|
+
*/
|
|
33
|
+
export declare function runGoalMode(ctx: ModeContext): AsyncIterable<MoxxyEvent>;
|
|
34
|
+
//# sourceMappingURL=goal-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goal-loop.d.ts","sourceRoot":"","sources":["../src/goal-loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAaL,KAAK,WAAW,EAChB,KAAK,UAAU,EAEhB,MAAM,YAAY,CAAC;AA2BpB;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GACrD,MAAM,IAAI,CAMZ;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAuB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,CAAC,UAAU,CAAC,CAkb9E"}
|