freecodego 0.1.6-alpha.2.4 → 0.1.7-alpha.2.1
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/README.i18n.yaml +2 -2
- package/README.md +17 -7
- package/README.zh.md +17 -7
- package/cordis.patch.yml +42 -6
- package/dist/agent-team.js +13 -74
- package/dist/assets/presets/augmentcode/agent.cordis.yml +3 -2
- package/dist/assets/presets/freecodego/agent.cordis.yml +3 -2
- package/dist/auto-review.js +8 -11
- package/dist/bootstrap.js +1167 -737
- package/dist/client.cjs +1244 -290
- package/dist/harness-plugin.js +5 -0
- package/dist/schedule.js +78 -26
- package/dist/tool-agent-team.js +38 -97
- package/package.json +76 -43
- package/presets/augmentcode.patch.yml +273 -0
- package/presets/freecodego.patch.yml +255 -0
package/dist/bootstrap.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
// packages/freecodego/harness-plugin/lib/index.js
|
|
2
2
|
import { createRequire as createRequire2 } from "node:module";
|
|
3
3
|
import path, { basename as basename2, dirname as dirname2, extname, isAbsolute as isAbsolute2, join as join4, matchesGlob, normalize as normalize2, relative as relative2, resolve as resolve2, sep } from "node:path";
|
|
4
|
+
import { credentialRef as credentialRef2 } from "@deepseek-ai/dsh-credentials";
|
|
4
5
|
import { constants, createCipheriv, createHash as createHash3, createHmac, createPublicKey, publicEncrypt, randomBytes, randomUUID as randomUUID3, timingSafeEqual } from "node:crypto";
|
|
5
6
|
import fs, { appendFile, copyFile as copyFile2, mkdir as mkdir4, mkdtemp, open as open2, readFile as readFile3, readdir as readdir2, readlink, realpath, rename as rename3, rm as rm2, stat as stat2, symlink, unlink, writeFile as writeFile3 } from "node:fs/promises";
|
|
6
7
|
import { availableParallelism, homedir, platform as platform2, release, tmpdir } from "node:os";
|
|
7
8
|
import { deflateRawSync, gunzipSync, inflateRawSync, inflateSync } from "node:zlib";
|
|
8
|
-
import z2 from "@deepseek-ai/schemastery";
|
|
9
9
|
import { appendFileSync, chmodSync, constants as constants$1, createWriteStream, existsSync as existsSync2, lstatSync, mkdirSync, readFileSync as readFileSync2, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { writeFileAtomic } from "@deepseek-ai/dsh-atomic-write";
|
|
11
11
|
import { expandHomePath, resolveDshHome } from "@deepseek-ai/dsh-home-paths";
|
|
12
12
|
import { execFile, spawn as spawn2 } from "node:child_process";
|
|
13
|
-
import { BlockAssembler, EMPTY_RESPONSE_CODE, LlmAdapter, LlmError, ReasoningEffortId, ToolCallId, attributionHeaders, createAssistantMessage as createAssistantMessage2,
|
|
13
|
+
import { BlockAssembler, EMPTY_RESPONSE_CODE, LlmAdapter, LlmError, ReasoningEffortId, ToolCallId, attributionHeaders, createAssistantMessage as createAssistantMessage2, createToolResultMessage as createToolResultMessage2, createUserMessage } from "@deepseek-ai/dsh-llm";
|
|
14
14
|
import { promisify } from "node:util";
|
|
15
|
+
import z2 from "@deepseek-ai/schemastery";
|
|
15
16
|
import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
16
17
|
|
|
17
18
|
// packages/freecodego/native-runtime-host/lib/index.js
|
|
@@ -1296,8 +1297,7 @@ import { createServer } from "node:http";
|
|
|
1296
1297
|
import "@deepseek-ai/dsh-token-meter/src/estimate.ts";
|
|
1297
1298
|
import { apply } from "@deepseek-ai/dsh-mcp-client";
|
|
1298
1299
|
import { apply as apply$1 } from "@deepseek-ai/dsh-skill-filesystem";
|
|
1299
|
-
import { load } from "js-yaml";
|
|
1300
|
-
import { credentialRef as credentialRef2 } from "@deepseek-ai/dsh-credentials";
|
|
1300
|
+
import yaml, { load } from "js-yaml";
|
|
1301
1301
|
import { KNOWN_SESSION_EVENT_TYPES, SessionId } from "@deepseek-ai/dsh-session";
|
|
1302
1302
|
import { SANDBOX_MODES, setSandboxMode } from "@deepseek-ai/dsh-sandbox-policy";
|
|
1303
1303
|
import { setApprovalPolicy } from "@deepseek-ai/dsh-user-approval";
|
|
@@ -1559,9 +1559,9 @@ function asAttemptResult(value) {
|
|
|
1559
1559
|
};
|
|
1560
1560
|
}
|
|
1561
1561
|
async function runGuardedRefresh(input) {
|
|
1562
|
-
const
|
|
1562
|
+
const classify2 = input.classify ?? classifyRefreshFailure;
|
|
1563
1563
|
const controller = new AbortController();
|
|
1564
|
-
const first = await attemptOnce(input.attempt, controller.signal, false,
|
|
1564
|
+
const first = await attemptOnce(input.attempt, controller.signal, false, classify2);
|
|
1565
1565
|
if (first.ok) return {
|
|
1566
1566
|
ok: true,
|
|
1567
1567
|
value: first.value,
|
|
@@ -1583,7 +1583,7 @@ async function runGuardedRefresh(input) {
|
|
|
1583
1583
|
...passthrough(first)
|
|
1584
1584
|
};
|
|
1585
1585
|
await (input.wait ?? defaultWait)(input.retryDelayMs ?? 1e3);
|
|
1586
|
-
const second = await attemptOnce(input.attempt, controller.signal, true,
|
|
1586
|
+
const second = await attemptOnce(input.attempt, controller.signal, true, classify2);
|
|
1587
1587
|
if (second.ok) return {
|
|
1588
1588
|
ok: true,
|
|
1589
1589
|
value: second.value,
|
|
@@ -1602,7 +1602,7 @@ async function runGuardedRefresh(input) {
|
|
|
1602
1602
|
function passthrough(result) {
|
|
1603
1603
|
return result.ok || result.message === void 0 ? {} : { message: result.message };
|
|
1604
1604
|
}
|
|
1605
|
-
async function attemptOnce(attempt, signal, retry,
|
|
1605
|
+
async function attemptOnce(attempt, signal, retry, classify2) {
|
|
1606
1606
|
try {
|
|
1607
1607
|
const outcome = await attempt({
|
|
1608
1608
|
signal,
|
|
@@ -1615,7 +1615,7 @@ async function attemptOnce(attempt, signal, retry, classify) {
|
|
|
1615
1615
|
};
|
|
1616
1616
|
return reported;
|
|
1617
1617
|
} catch (error) {
|
|
1618
|
-
const classified =
|
|
1618
|
+
const classified = classify2(error);
|
|
1619
1619
|
return {
|
|
1620
1620
|
ok: false,
|
|
1621
1621
|
kind: classified.kind,
|
|
@@ -3255,6 +3255,7 @@ function array(value, label) {
|
|
|
3255
3255
|
}
|
|
3256
3256
|
|
|
3257
3257
|
// packages/freecodego/harness-plugin/lib/index.js
|
|
3258
|
+
import { isVolatile } from "@deepseek-ai/cosmokit";
|
|
3258
3259
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
3259
3260
|
import { deriveTurnTokenUsage } from "@deepseek-ai/dsh-token-meter/client";
|
|
3260
3261
|
|
|
@@ -7632,20 +7633,6 @@ function walk$1(value, ancestors, onCycle) {
|
|
|
7632
7633
|
ancestors.delete(value);
|
|
7633
7634
|
}
|
|
7634
7635
|
}
|
|
7635
|
-
var FreeCodeGoGuardSettingsSchema = z2.object({
|
|
7636
|
-
envReadGuardEnabled: z2.boolean().default(true),
|
|
7637
|
-
doomLoopGuardEnabled: z2.boolean().default(true),
|
|
7638
|
-
lspEnabled: z2.boolean().default(true),
|
|
7639
|
-
commandPolicyEnabled: z2.boolean().default(true),
|
|
7640
|
-
planModeEnabled: z2.boolean().default(true),
|
|
7641
|
-
contextBudgetEnabled: z2.boolean().default(true),
|
|
7642
|
-
cacheColdClearEnabled: z2.boolean().default(true),
|
|
7643
|
-
cacheBreakAttributionEnabled: z2.boolean().default(true),
|
|
7644
|
-
assistantLoopGuardEnabled: z2.boolean().default(true),
|
|
7645
|
-
spillRecallEnabled: z2.boolean().default(true),
|
|
7646
|
-
compactionFidelityEnabled: z2.boolean().default(true),
|
|
7647
|
-
promptCompositionEnabled: z2.boolean().default(true)
|
|
7648
|
-
});
|
|
7649
7636
|
var SECRET_BASENAME = /^(?:\.env(?!\.(?:example|sample|template|dist)$)(?:\..+)?|\.credentials\.ya?ml(?!\.(?:example|sample|template|dist)$)(?:\..+)?|\.envrc|\.npmrc|\.netrc|\.pypirc|\.git-credentials|\.htpasswd|id_(?:rsa|dsa|ecdsa|ed25519)(?:_sk)?(?:\.pub)?|.+_rsa|.+_ed25519|.+\.pem|.+\.pfx|.+\.p12|.+\.keystore|secrets?\.json|secrets?\.ya?ml|credentials\.json)$/;
|
|
7650
7637
|
var SECRET_DIRECTORIES = /* @__PURE__ */ new Set([".ssh", ".gnupg"]);
|
|
7651
7638
|
var SECRET_FILE_IN_DIRECTORIES = [
|
|
@@ -10547,10 +10534,7 @@ function hookSignalOf(value) {
|
|
|
10547
10534
|
}
|
|
10548
10535
|
function hookContextMessage(text2) {
|
|
10549
10536
|
return createUserMessage({
|
|
10550
|
-
source: {
|
|
10551
|
-
kind: "plugin",
|
|
10552
|
-
plugin: "freecodego-hooks"
|
|
10553
|
-
},
|
|
10537
|
+
source: { kind: "freecodego-hooks" },
|
|
10554
10538
|
content: [{
|
|
10555
10539
|
type: "text",
|
|
10556
10540
|
text: text2
|
|
@@ -12267,6 +12251,9 @@ function isCancellationWording(message2) {
|
|
|
12267
12251
|
}
|
|
12268
12252
|
var ROUTE_TTL_MS = 1440 * 60 * 1e3;
|
|
12269
12253
|
var DEFAULT_STREAM_IDLE_MS = 12e4;
|
|
12254
|
+
function bridgeRouteIdOf(baseURL) {
|
|
12255
|
+
return /\/anthropic\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:\/v1)?\/?$/iu.exec(baseURL.trim())?.[1];
|
|
12256
|
+
}
|
|
12270
12257
|
function callId$1(value) {
|
|
12271
12258
|
return value;
|
|
12272
12259
|
}
|
|
@@ -12356,6 +12343,22 @@ var ClaudeProtocolBridge = class {
|
|
|
12356
12343
|
apiKey: this.secret
|
|
12357
12344
|
};
|
|
12358
12345
|
}
|
|
12346
|
+
/**
|
|
12347
|
+
* Whether this process still serves a route id.
|
|
12348
|
+
*
|
|
12349
|
+
* A route belongs to the listener that minted it: `dispose()` clears the map and
|
|
12350
|
+
* a new process mints new ids and a new port, so a saved endpoint whose id is
|
|
12351
|
+
* absent here answers nothing. That is the question a binding written before a
|
|
12352
|
+
* restart has to ask before it can be kept — see `web-search-binding.ts` — and
|
|
12353
|
+
* it is asked of the bridge rather than of a copy of the map, because only the
|
|
12354
|
+
* bridge knows when a route expired.
|
|
12355
|
+
* @param id - route id parsed off a saved endpoint ({@link bridgeRouteIdOf}).
|
|
12356
|
+
* @returns whether this bridge would answer for it.
|
|
12357
|
+
*/
|
|
12358
|
+
hasRoute(id) {
|
|
12359
|
+
this.pruneRoutes();
|
|
12360
|
+
return this.routes.has(id);
|
|
12361
|
+
}
|
|
12359
12362
|
/** Drop routes older than the TTL so a long-lived bridge cannot leak them. */
|
|
12360
12363
|
pruneRoutes() {
|
|
12361
12364
|
const cutoff = Date.now() - ROUTE_TTL_MS;
|
|
@@ -12917,8 +12920,7 @@ function estimateAnthropicInputTokens(body) {
|
|
|
12917
12920
|
}
|
|
12918
12921
|
function toResponsesGenerateOptions(route, body) {
|
|
12919
12922
|
const messages = [];
|
|
12920
|
-
if (typeof body.instructions === "string" && body.instructions.trim() !== "") messages.push(
|
|
12921
|
-
role: "user",
|
|
12923
|
+
if (typeof body.instructions === "string" && body.instructions.trim() !== "") messages.push(createUserMessage({
|
|
12922
12924
|
content: [{
|
|
12923
12925
|
type: "text",
|
|
12924
12926
|
text: body.instructions
|
|
@@ -12928,8 +12930,7 @@ function toResponsesGenerateOptions(route, body) {
|
|
|
12928
12930
|
if (Array.isArray(body.input)) for (const value of body.input) {
|
|
12929
12931
|
const item = value;
|
|
12930
12932
|
if (item.type === "function_call") {
|
|
12931
|
-
messages.push(
|
|
12932
|
-
role: "assistant",
|
|
12933
|
+
messages.push(createAssistantMessage2({
|
|
12933
12934
|
content: [{
|
|
12934
12935
|
type: "tool-call",
|
|
12935
12936
|
id: callId$1(String(item.call_id ?? item.id ?? "tool")),
|
|
@@ -12937,7 +12938,6 @@ function toResponsesGenerateOptions(route, body) {
|
|
|
12937
12938
|
arguments: String(item.arguments ?? "")
|
|
12938
12939
|
}],
|
|
12939
12940
|
source: {
|
|
12940
|
-
kind: "model",
|
|
12941
12941
|
provider: "bridge",
|
|
12942
12942
|
model: "bridge"
|
|
12943
12943
|
}
|
|
@@ -12946,20 +12946,13 @@ function toResponsesGenerateOptions(route, body) {
|
|
|
12946
12946
|
}
|
|
12947
12947
|
if (item.type === "function_call_output") {
|
|
12948
12948
|
const call = String(item.call_id ?? "tool");
|
|
12949
|
-
messages.push(
|
|
12950
|
-
|
|
12949
|
+
messages.push(createToolResultMessage2({
|
|
12950
|
+
callId: callId$1(call),
|
|
12951
12951
|
content: [{
|
|
12952
|
-
type: "
|
|
12953
|
-
|
|
12954
|
-
content: [{
|
|
12955
|
-
type: "text",
|
|
12956
|
-
text: typeof item.output === "string" ? item.output : JSON.stringify(item.output ?? "")
|
|
12957
|
-
}]
|
|
12952
|
+
type: "text",
|
|
12953
|
+
text: typeof item.output === "string" ? item.output : JSON.stringify(item.output ?? "")
|
|
12958
12954
|
}],
|
|
12959
|
-
|
|
12960
|
-
kind: "tool",
|
|
12961
|
-
callId: callId$1(call)
|
|
12962
|
-
}
|
|
12955
|
+
isError: item.is_error === true
|
|
12963
12956
|
}));
|
|
12964
12957
|
continue;
|
|
12965
12958
|
}
|
|
@@ -12975,14 +12968,15 @@ function toResponsesGenerateOptions(route, body) {
|
|
|
12975
12968
|
text: text2
|
|
12976
12969
|
}] : [];
|
|
12977
12970
|
});
|
|
12978
|
-
if (blocks.length > 0) messages.push(
|
|
12979
|
-
role,
|
|
12971
|
+
if (blocks.length > 0) messages.push(role === "assistant" ? createAssistantMessage2({
|
|
12980
12972
|
content: blocks,
|
|
12981
|
-
source:
|
|
12982
|
-
kind: "model",
|
|
12973
|
+
source: {
|
|
12983
12974
|
provider: "bridge",
|
|
12984
12975
|
model: "bridge"
|
|
12985
|
-
}
|
|
12976
|
+
}
|
|
12977
|
+
}) : createUserMessage({
|
|
12978
|
+
content: blocks,
|
|
12979
|
+
source: { kind: "user" }
|
|
12986
12980
|
}));
|
|
12987
12981
|
}
|
|
12988
12982
|
const tools = Array.isArray(body.tools) ? body.tools.flatMap((value) => {
|
|
@@ -13007,45 +13001,65 @@ var BRIDGE_IMAGE_PLACEHOLDER = "[image attachment: not forwarded by the FreeCode
|
|
|
13007
13001
|
function anthropicMessages(value) {
|
|
13008
13002
|
const item = value;
|
|
13009
13003
|
const role = item.role === "assistant" ? "assistant" : "user";
|
|
13010
|
-
const
|
|
13004
|
+
const content = Array.isArray(item.content) ? item.content : [{
|
|
13011
13005
|
type: "text",
|
|
13012
13006
|
text: String(item.content ?? "")
|
|
13013
|
-
}]
|
|
13007
|
+
}];
|
|
13008
|
+
const messages = [];
|
|
13009
|
+
const blocks = [];
|
|
13010
|
+
const flushTurn = () => {
|
|
13011
|
+
if (blocks.length === 0) return;
|
|
13012
|
+
messages.push(role === "assistant" ? createAssistantMessage2({
|
|
13013
|
+
content: blocks.splice(0),
|
|
13014
|
+
source: {
|
|
13015
|
+
provider: "bridge",
|
|
13016
|
+
model: "bridge"
|
|
13017
|
+
}
|
|
13018
|
+
}) : createUserMessage({
|
|
13019
|
+
content: blocks.splice(0),
|
|
13020
|
+
source: { kind: "user" }
|
|
13021
|
+
}));
|
|
13022
|
+
};
|
|
13023
|
+
for (const block of content) {
|
|
13014
13024
|
const part = block;
|
|
13015
|
-
if (part.type === "
|
|
13016
|
-
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13024
|
-
|
|
13025
|
-
|
|
13026
|
-
|
|
13027
|
-
|
|
13028
|
-
|
|
13025
|
+
if (part.type === "tool_result") {
|
|
13026
|
+
flushTurn();
|
|
13027
|
+
messages.push(createToolResultMessage2({
|
|
13028
|
+
callId: callId$1(String(part.tool_use_id ?? "tool")),
|
|
13029
|
+
content: [{
|
|
13030
|
+
type: "text",
|
|
13031
|
+
text: toolResultText(part.content)
|
|
13032
|
+
}],
|
|
13033
|
+
isError: part.is_error === true
|
|
13034
|
+
}));
|
|
13035
|
+
continue;
|
|
13036
|
+
}
|
|
13037
|
+
if (part.type === "text") {
|
|
13038
|
+
blocks.push({
|
|
13029
13039
|
type: "text",
|
|
13030
|
-
text:
|
|
13031
|
-
}
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
|
|
13048
|
-
|
|
13040
|
+
text: String(part.text ?? "")
|
|
13041
|
+
});
|
|
13042
|
+
continue;
|
|
13043
|
+
}
|
|
13044
|
+
if (part.type === "tool_use") {
|
|
13045
|
+
blocks.push({
|
|
13046
|
+
type: "tool-call",
|
|
13047
|
+
id: callId$1(String(part.id ?? randomUUID3())),
|
|
13048
|
+
name: String(part.name ?? "tool"),
|
|
13049
|
+
arguments: JSON.stringify(part.input ?? {})
|
|
13050
|
+
});
|
|
13051
|
+
continue;
|
|
13052
|
+
}
|
|
13053
|
+
if (part.type === "image") {
|
|
13054
|
+
blocks.push({
|
|
13055
|
+
type: "text",
|
|
13056
|
+
text: BRIDGE_IMAGE_PLACEHOLDER
|
|
13057
|
+
});
|
|
13058
|
+
continue;
|
|
13059
|
+
}
|
|
13060
|
+
}
|
|
13061
|
+
flushTurn();
|
|
13062
|
+
return messages;
|
|
13049
13063
|
}
|
|
13050
13064
|
function toolResultText(content) {
|
|
13051
13065
|
if (typeof content === "string") return content;
|
|
@@ -13360,40 +13374,6 @@ async function inlineImageAttachmentBlocks(content, read) {
|
|
|
13360
13374
|
function callId2(value) {
|
|
13361
13375
|
return value;
|
|
13362
13376
|
}
|
|
13363
|
-
var FreeCodeGoCapabilitySettingsSchema = z2.object({
|
|
13364
|
-
mcpEnabled: z2.boolean().default(false),
|
|
13365
|
-
skillEnabled: z2.boolean().default(false),
|
|
13366
|
-
voiceInputEnabled: z2.boolean().default(true),
|
|
13367
|
-
sessionDeleteEnabled: z2.boolean().default(true),
|
|
13368
|
-
modelCategories: z2.dict(z2.union([
|
|
13369
|
-
z2.const("text"),
|
|
13370
|
-
z2.const("image"),
|
|
13371
|
-
z2.const("video"),
|
|
13372
|
-
z2.const("audio")
|
|
13373
|
-
])).default({}),
|
|
13374
|
-
mcpServers: z2.array(z2.object({
|
|
13375
|
-
id: z2.string().min(1).max(80),
|
|
13376
|
-
enabled: z2.boolean().default(true),
|
|
13377
|
-
transport: z2.union([z2.const("stdio"), z2.const("streamable-http")]),
|
|
13378
|
-
serverName: z2.string().pattern(SERVER_NAME$1),
|
|
13379
|
-
command: z2.string().default(""),
|
|
13380
|
-
args: z2.array(z2.string().max(4096)).default([]),
|
|
13381
|
-
env: z2.dict(z2.string()).default({}),
|
|
13382
|
-
cwd: z2.string().default(""),
|
|
13383
|
-
url: z2.string().default(""),
|
|
13384
|
-
headers: z2.dict(z2.string()).default({})
|
|
13385
|
-
})).default([]),
|
|
13386
|
-
skillRoots: z2.array(z2.object({
|
|
13387
|
-
id: z2.string().min(1).max(80),
|
|
13388
|
-
enabled: z2.boolean().default(true),
|
|
13389
|
-
path: z2.string().min(1).max(4096)
|
|
13390
|
-
})).default([]),
|
|
13391
|
-
skillInvocationOverrides: z2.dict(z2.boolean()).default({}),
|
|
13392
|
-
preferredSkillPlacement: z2.union([z2.object({
|
|
13393
|
-
agent: z2.union([z2.const("harness"), z2.const("agents")]),
|
|
13394
|
-
scope: z2.union([z2.const("project"), z2.const("user")])
|
|
13395
|
-
}), z2.const(null)])
|
|
13396
|
-
});
|
|
13397
13377
|
var NO_PROJECT_ENTRIES = {
|
|
13398
13378
|
mcpServers: [],
|
|
13399
13379
|
skillRoots: []
|
|
@@ -14240,6 +14220,8 @@ function toMcpClientConfig(server) {
|
|
|
14240
14220
|
var MAX_SOURCE_BYTES = 2e6;
|
|
14241
14221
|
var MAX_SOURCE_FILES = 50;
|
|
14242
14222
|
var RESOURCE_NAME = /^[A-Za-z0-9_.:/@-]{1,256}$/;
|
|
14223
|
+
var CONFLICT_PROTECTION_KEY = "pluginConflictProtectionEnabled";
|
|
14224
|
+
var NO_SETTINGS_PORT_CONFLICT_PROTECTION = false;
|
|
14243
14225
|
var OWN_STAND_IN_MODULES = /* @__PURE__ */ new Set(["freecodego/agent-team", "freecodego/tool-agent-team"]);
|
|
14244
14226
|
var OWN_STAND_IN_ENTRY_IDS = /* @__PURE__ */ new Set(["freecodego-agent-team", "freecodego-tool-agent-team"]);
|
|
14245
14227
|
function isOfficialModuleName(moduleName) {
|
|
@@ -14250,27 +14232,6 @@ function isOwnStandIn(moduleName, entryId) {
|
|
|
14250
14232
|
const tail = entryId.slice(entryId.lastIndexOf(":") + 1);
|
|
14251
14233
|
return OWN_STAND_IN_ENTRY_IDS.has(tail);
|
|
14252
14234
|
}
|
|
14253
|
-
var FreeCodeGoPluginConflictSettingsSchema = z2.object({
|
|
14254
|
-
pluginConflictProtectionEnabled: z2.boolean().default(false),
|
|
14255
|
-
pluginConflictRecords: z2.array(z2.object({
|
|
14256
|
-
id: z2.string().min(1).max(256),
|
|
14257
|
-
detectedAt: z2.number(),
|
|
14258
|
-
resource: z2.union([
|
|
14259
|
-
z2.const("tool"),
|
|
14260
|
-
z2.const("command"),
|
|
14261
|
-
z2.const("settings"),
|
|
14262
|
-
z2.const("route"),
|
|
14263
|
-
z2.const("provider"),
|
|
14264
|
-
z2.const("slot")
|
|
14265
|
-
]),
|
|
14266
|
-
resourceName: z2.string().min(1).max(256),
|
|
14267
|
-
disabledEntryId: z2.string().min(1).max(512),
|
|
14268
|
-
disabledModuleName: z2.string().min(1).max(512),
|
|
14269
|
-
keptEntryId: z2.string().min(1).max(512),
|
|
14270
|
-
keptModuleName: z2.string().min(1).max(512),
|
|
14271
|
-
yieldedToOfficial: z2.boolean()
|
|
14272
|
-
})).default([])
|
|
14273
|
-
});
|
|
14274
14235
|
function scanPluginResourceClaims(source) {
|
|
14275
14236
|
const claims = /* @__PURE__ */ new Map();
|
|
14276
14237
|
const add = (resource, resourceName) => {
|
|
@@ -14316,7 +14277,7 @@ var FreeCodeGoPluginConflictGuard = class {
|
|
|
14316
14277
|
this.ctx = ctx;
|
|
14317
14278
|
this.settings = settings;
|
|
14318
14279
|
this.records = settings?.get()?.pluginConflictRecords ?? [];
|
|
14319
|
-
this.enabled = settings?.get()?.
|
|
14280
|
+
this.enabled = settings?.get()?.[CONFLICT_PROTECTION_KEY] ?? NO_SETTINGS_PORT_CONFLICT_PROTECTION;
|
|
14320
14281
|
}
|
|
14321
14282
|
/**
|
|
14322
14283
|
* Install plugin-owned Loader lifecycle wrappers and seed active entry claims.
|
|
@@ -14351,13 +14312,17 @@ var FreeCodeGoPluginConflictGuard = class {
|
|
|
14351
14312
|
};
|
|
14352
14313
|
}, "freecodego: plugin conflict lifecycle guard");
|
|
14353
14314
|
}
|
|
14354
|
-
/** Attach settings
|
|
14315
|
+
/** Attach the settings port this guard reads the switch and its records through.
|
|
14316
|
+
*
|
|
14317
|
+
* The guard is a per-root singleton, so a later mount that carries a port re-points the
|
|
14318
|
+
* existing instance at the live document instead of leaving it on the answer it was
|
|
14319
|
+
* constructed with.
|
|
14355
14320
|
* @param settings - the plugin settings port, when one is available.
|
|
14356
14321
|
*/
|
|
14357
14322
|
configure(settings) {
|
|
14358
14323
|
if (settings === void 0 || settings === this.settings) return;
|
|
14359
14324
|
this.settings = settings;
|
|
14360
|
-
this.enabled = settings.get()?.
|
|
14325
|
+
this.enabled = settings.get()?.[CONFLICT_PROTECTION_KEY] ?? NO_SETTINGS_PORT_CONFLICT_PROTECTION;
|
|
14361
14326
|
if (this.started) this.installInterception();
|
|
14362
14327
|
const persisted = settings.get()?.pluginConflictRecords ?? [];
|
|
14363
14328
|
const merged = [...persisted, ...this.records.filter((record3) => !persisted.some((item) => sameConflict(item, record3)))].slice(-100);
|
|
@@ -14404,13 +14369,26 @@ var FreeCodeGoPluginConflictGuard = class {
|
|
|
14404
14369
|
protectionEnabled() {
|
|
14405
14370
|
return this.settings?.get()?.pluginConflictProtectionEnabled ?? this.enabled;
|
|
14406
14371
|
}
|
|
14407
|
-
/**
|
|
14372
|
+
/**
|
|
14373
|
+
* Persist the global automatic-repair switch, and start or stop acting on it.
|
|
14374
|
+
*
|
|
14375
|
+
* Recording the value is not enough in the on direction. A guard built while the switch was
|
|
14376
|
+
* off never installed its wrappers — that is deliberate, since leaving them in place would
|
|
14377
|
+
* keep this plugin reading every entry's package while the deployment had said not to — so a
|
|
14378
|
+
* guard that only wrote the new value would report protection as on while the running Loader
|
|
14379
|
+
* went on starting every duplicate, and would silently stay inert until the next boot. The
|
|
14380
|
+
* install has to come after the write resolves, because the live document is what
|
|
14381
|
+
* {@link protectionEnabled} reads back.
|
|
14382
|
+
*
|
|
14383
|
+
* The off direction needs nothing: the wrappers ask `protectionEnabled()` per entry, so a
|
|
14384
|
+
* switch turned off stops the answering without being uninstalled.
|
|
14408
14385
|
* @param enabled - whether this capability is switched on.
|
|
14409
14386
|
* @returns the plugin Conflict Status.
|
|
14410
14387
|
*/
|
|
14411
14388
|
async setEnabled(enabled) {
|
|
14412
14389
|
this.enabled = enabled;
|
|
14413
14390
|
await this.settings?.update({ pluginConflictProtectionEnabled: enabled });
|
|
14391
|
+
if (enabled) this.installInterception();
|
|
14414
14392
|
return this.snapshot();
|
|
14415
14393
|
}
|
|
14416
14394
|
async seed() {
|
|
@@ -14654,14 +14632,6 @@ function relativeModuleSpecifiers(source) {
|
|
|
14654
14632
|
add(/\brequire\s*\(\s*(['"])(\.{1,2}\/[^'"]+)\1\s*\)/g);
|
|
14655
14633
|
return [...specifiers];
|
|
14656
14634
|
}
|
|
14657
|
-
function bootstrapConflictProtectionEnabled() {
|
|
14658
|
-
const settingsPath = join4(harnessHomeDirectory(), "settings.yaml");
|
|
14659
|
-
try {
|
|
14660
|
-
return readFileSync2(settingsPath, "utf8").match(/^freecodego-harness:\s*\r?\n(?:[ \t]+[^\r\n]*\r?\n)*?[ \t]+pluginConflictProtectionEnabled:\s*(true|false)\s*(?:#.*)?$/m)?.[1] === "true";
|
|
14661
|
-
} catch {
|
|
14662
|
-
return false;
|
|
14663
|
-
}
|
|
14664
|
-
}
|
|
14665
14635
|
function sameConflict(left, right) {
|
|
14666
14636
|
return left.resource === right.resource && left.resourceName === right.resourceName && left.disabledEntryId === right.disabledEntryId && left.disabledModuleName === right.disabledModuleName && left.keptEntryId === right.keptEntryId && left.keptModuleName === right.keptModuleName;
|
|
14667
14637
|
}
|
|
@@ -14687,7 +14657,6 @@ var MAX_UNCONFIRMED_STARTUPS = 2;
|
|
|
14687
14657
|
var DSH_INSTALL_TIMEOUT_MS = 15 * 6e4;
|
|
14688
14658
|
var NPM_PACKAGE_RE$2 = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/i;
|
|
14689
14659
|
var RELEASE_TAG_RE = /^(?:freecodego-)?v(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/u;
|
|
14690
|
-
var FreeCodeGoPluginUpdateSettingsSchema = z2.object({ pluginUpdateChecksEnabled: z2.boolean().default(true) });
|
|
14691
14660
|
var FreeCodeGoPluginUpdateService = class {
|
|
14692
14661
|
options;
|
|
14693
14662
|
packageName;
|
|
@@ -16973,10 +16942,7 @@ var FreeCodeGoAdvisorRuntime = class {
|
|
|
16973
16942
|
const evidence = new AdvisorEvidenceCache((call, signal) => executeReviewTool(this.ctx, agent, call, signal));
|
|
16974
16943
|
const findings = await Promise.all(Object.entries(COUNCIL_ROLES).map(async ([role, instruction]) => {
|
|
16975
16944
|
const messages = [createUserMessage({
|
|
16976
|
-
source: {
|
|
16977
|
-
kind: "plugin",
|
|
16978
|
-
plugin: "freecodego-advisor-council"
|
|
16979
|
-
},
|
|
16945
|
+
source: { kind: "freecodego-advisor-council" },
|
|
16980
16946
|
content: [{
|
|
16981
16947
|
type: "text",
|
|
16982
16948
|
text: `${reviewPrompt$2(delta, watchdog.instructions)}
|
|
@@ -17093,10 +17059,7 @@ Council perspective: ${role}. ${instruction}`
|
|
|
17093
17059
|
const watchdog = await discoverWatchdog(agent.session.header.cwd);
|
|
17094
17060
|
this.watchdogFilesBySession.set(String(agent.id), watchdog.files);
|
|
17095
17061
|
const messages = [createUserMessage({
|
|
17096
|
-
source: {
|
|
17097
|
-
kind: "plugin",
|
|
17098
|
-
plugin: "freecodego-advisor"
|
|
17099
|
-
},
|
|
17062
|
+
source: { kind: "freecodego-advisor" },
|
|
17100
17063
|
content: [{
|
|
17101
17064
|
type: "text",
|
|
17102
17065
|
text: reviewPrompt$2(delta, watchdog.instructions)
|
|
@@ -17235,10 +17198,7 @@ Perspective: ${perspective}`}`,
|
|
|
17235
17198
|
cooldownUntilTurn: state.cooldownUntilTurn
|
|
17236
17199
|
});
|
|
17237
17200
|
const message2 = createUserMessage({
|
|
17238
|
-
source: {
|
|
17239
|
-
kind: "plugin",
|
|
17240
|
-
plugin: "freecodego-advisor"
|
|
17241
|
-
},
|
|
17201
|
+
source: { kind: "freecodego-advisor" },
|
|
17242
17202
|
content: [{
|
|
17243
17203
|
type: "text",
|
|
17244
17204
|
text: `<advisory severity="${advice.severity}" guidance="weigh, do not blindly obey">
|
|
@@ -17351,7 +17311,6 @@ function messageText$2(message2) {
|
|
|
17351
17311
|
return message2.content.map((block) => {
|
|
17352
17312
|
if (block.type === "text" || block.type === "reasoning") return block.text;
|
|
17353
17313
|
if (block.type === "tool-call") return `${block.name}(${block.arguments})`;
|
|
17354
|
-
if (block.type === "tool-result") return block.content.map((item) => item.type === "text" ? item.text : `[${item.type}]`).join("\n");
|
|
17355
17314
|
return `[${block.type}]`;
|
|
17356
17315
|
}).join("\n");
|
|
17357
17316
|
}
|
|
@@ -20943,10 +20902,7 @@ var FreeCodeGoEngineCouncil = class {
|
|
|
20943
20902
|
try {
|
|
20944
20903
|
signal.throwIfAborted();
|
|
20945
20904
|
agent.followup(createUserMessage({
|
|
20946
|
-
source: {
|
|
20947
|
-
kind: "plugin",
|
|
20948
|
-
plugin: "freecodego-engine-council"
|
|
20949
|
-
},
|
|
20905
|
+
source: { kind: "freecodego-engine-council" },
|
|
20950
20906
|
content: [{
|
|
20951
20907
|
type: "text",
|
|
20952
20908
|
text: prompt
|
|
@@ -21264,10 +21220,7 @@ function terminalReport(task, request, runtimes, state, quorum, error) {
|
|
|
21264
21220
|
function injectCouncilHandoff(parent, report) {
|
|
21265
21221
|
try {
|
|
21266
21222
|
parent.inject(createUserMessage({
|
|
21267
|
-
source: {
|
|
21268
|
-
kind: "plugin",
|
|
21269
|
-
plugin: "freecodego-engine-council"
|
|
21270
|
-
},
|
|
21223
|
+
source: { kind: "freecodego-engine-council" },
|
|
21271
21224
|
content: [{
|
|
21272
21225
|
type: "text",
|
|
21273
21226
|
text: "Engineering council " + report.id + " finished with state " + report.state + ". Read the durable report before proceeding. " + report.finalRecommendation
|
|
@@ -21337,8 +21290,9 @@ function sameRoutes(left, right) {
|
|
|
21337
21290
|
return left.length === right.length && left.every((route, index) => route.provider === right[index]?.provider && route.model === right[index]?.model);
|
|
21338
21291
|
}
|
|
21339
21292
|
async function synchronizeSubagentModelRoutes(settings, llm) {
|
|
21340
|
-
const
|
|
21341
|
-
if (
|
|
21293
|
+
const descriptor = settings.describe().find((row) => row.ns === SUBAGENT_MODEL_SELECTION_NAMESPACE);
|
|
21294
|
+
if (descriptor === void 0) return [];
|
|
21295
|
+
const current = descriptor.value;
|
|
21342
21296
|
const previous = routesOf(current);
|
|
21343
21297
|
const previousByProvider = /* @__PURE__ */ new Map();
|
|
21344
21298
|
for (const route of previous) {
|
|
@@ -21381,7 +21335,7 @@ async function synchronizeSubagentModelRoutes(settings, llm) {
|
|
|
21381
21335
|
allowedModels: filtered
|
|
21382
21336
|
};
|
|
21383
21337
|
if (currentRecord.enabled === void 0) patch.enabled = true;
|
|
21384
|
-
if (!sameRoutes(previous, filtered) || currentRecord.enabled === void 0) await settings.update(SUBAGENT_MODEL_SELECTION_NAMESPACE, patch);
|
|
21338
|
+
if (!sameRoutes(previous, filtered) || currentRecord.enabled === void 0) await settings.update(SUBAGENT_MODEL_SELECTION_NAMESPACE, patch, descriptor.revision);
|
|
21385
21339
|
return filtered;
|
|
21386
21340
|
}
|
|
21387
21341
|
var FreeCodeGoSubagentModelRouting = class {
|
|
@@ -21416,9 +21370,17 @@ var FreeCodeGoSubagentModelRouting = class {
|
|
|
21416
21370
|
const llm = this.ctx.get("llm");
|
|
21417
21371
|
if (settings === void 0 || llm === void 0) return;
|
|
21418
21372
|
const operation = (async () => {
|
|
21373
|
+
let retries = 0;
|
|
21419
21374
|
do {
|
|
21420
21375
|
this.rerun = false;
|
|
21421
|
-
|
|
21376
|
+
try {
|
|
21377
|
+
await synchronizeSubagentModelRoutes(settings, llm);
|
|
21378
|
+
retries = 0;
|
|
21379
|
+
} catch {
|
|
21380
|
+
if (retries >= 1 || this.disposed) break;
|
|
21381
|
+
retries += 1;
|
|
21382
|
+
this.rerun = true;
|
|
21383
|
+
}
|
|
21422
21384
|
} while (this.rerun && !this.disposed);
|
|
21423
21385
|
})().catch(() => void 0).finally(() => {
|
|
21424
21386
|
if (this.pending === operation) this.pending = void 0;
|
|
@@ -26869,97 +26831,6 @@ var FreeCodeGoVerifyOnStop = class {
|
|
|
26869
26831
|
}
|
|
26870
26832
|
}
|
|
26871
26833
|
};
|
|
26872
|
-
var FreeCodeGoEngineeringSettingsSchema = z2.object({
|
|
26873
|
-
engineeringEnabled: z2.boolean().default(false),
|
|
26874
|
-
/**
|
|
26875
|
-
* The rest of the bundled engineering library is opt-in: 23 audited Skills
|
|
26876
|
-
* (the remainder of the authored set plus the vendored `mattpocock/skills`
|
|
26877
|
-
* entries that are not in the default-on starter root) stay unmounted until
|
|
26878
|
-
* the user turns this on.
|
|
26879
|
-
*/
|
|
26880
|
-
engineeringSkillsEnabled: z2.boolean().default(false),
|
|
26881
|
-
/**
|
|
26882
|
-
* The starter set is on by default: ten Skills whose value does not depend on
|
|
26883
|
-
* adopting a whole methodology. Four are disciplines the model applies on its
|
|
26884
|
-
* own (evidence before completion claims, navigation before broad reading,
|
|
26885
|
-
* planning multi-file work, root-cause debugging); the rest are `/name`
|
|
26886
|
-
* entries a user reaches for on demand and that cost nothing until typed
|
|
26887
|
-
* (a prompt-technique reference, the grilling interview and its primitive, a
|
|
26888
|
-
* re-pitch escape hatch, a handoff document, and a questionnaire for
|
|
26889
|
-
* decisions the agent cannot settle). They live in their own asset root so
|
|
26890
|
-
* "all engineering Skills" stays the union of the roots — no skill file is
|
|
26891
|
-
* duplicated, and no audit can disagree with a mount.
|
|
26892
|
-
*/
|
|
26893
|
-
engineeringStarterSkillsEnabled: z2.boolean().default(true),
|
|
26894
|
-
/**
|
|
26895
|
-
* The vendored superpowers workflow pack is a separate opt-in: it is the
|
|
26896
|
-
* auto-triggering, plan-then-dispatch methodology, so it must be a deliberate
|
|
26897
|
-
* choice rather than a side effect of enabling the engineering disciplines.
|
|
26898
|
-
*/
|
|
26899
|
-
engineeringSuperpowersSkillsEnabled: z2.boolean().default(false),
|
|
26900
|
-
/**
|
|
26901
|
-
* Injects a bounded capability map of the mounted Skills at session start.
|
|
26902
|
-
* A default-off Skill library is invisible otherwise: the model never lists
|
|
26903
|
-
* it, and a user who turned a pack on has no way to see what arrived.
|
|
26904
|
-
*/
|
|
26905
|
-
engineeringSkillMapEnabled: z2.boolean().default(true),
|
|
26906
|
-
/** Enables bounded project-declared verification after an approved council plan. */
|
|
26907
|
-
engineeringQualityEnabled: z2.boolean().default(true),
|
|
26908
|
-
engineeringMemoryEnabled: z2.boolean().default(true),
|
|
26909
|
-
engineeringCouncilEnabled: z2.boolean().default(true),
|
|
26910
|
-
engineeringCouncilDeepseekEnabled: z2.boolean().default(true),
|
|
26911
|
-
engineeringCouncilCodexEnabled: z2.boolean().default(true),
|
|
26912
|
-
engineeringCouncilClaudeEnabled: z2.boolean().default(true),
|
|
26913
|
-
engineeringMemoryContextTokenBudget: z2.number().step(1).min(0).max(4e3).default(1200),
|
|
26914
|
-
/**
|
|
26915
|
-
* Default off, deliberately: the lexical rerank is free, deterministic, and
|
|
26916
|
-
* already ranks by term coverage. Flipping this on spends one small model
|
|
26917
|
-
* request per memory search to catch the memories that share no wording with
|
|
26918
|
-
* the query — worth it for a user who searches by concept, wasted for one who
|
|
26919
|
-
* greps for identifiers.
|
|
26920
|
-
*/
|
|
26921
|
-
engineeringMemorySelectorEnabled: z2.boolean().default(false),
|
|
26922
|
-
/**
|
|
26923
|
-
* Default off, deliberately: this lets a model approve a pending action without
|
|
26924
|
-
* asking the user. Off means every approval keeps prompting. On means an action
|
|
26925
|
-
* whose arguments the reviewer can actually read may be cleared automatically —
|
|
26926
|
-
* anything it refuses, cannot read, or declines to judge still goes to the user.
|
|
26927
|
-
*/
|
|
26928
|
-
engineeringActionReviewEnabled: z2.boolean().default(false),
|
|
26929
|
-
engineeringCodeGraphEnabled: z2.boolean().default(true),
|
|
26930
|
-
engineeringCodeGraphAutoUpdate: z2.boolean().default(true),
|
|
26931
|
-
engineeringGraphEngine: z2.union([
|
|
26932
|
-
z2.const("auto"),
|
|
26933
|
-
z2.const("graphify"),
|
|
26934
|
-
z2.const("codegraph")
|
|
26935
|
-
]).default("auto"),
|
|
26936
|
-
engineeringCouncilMaxRounds: z2.number().step(1).min(1).max(3).default(2),
|
|
26937
|
-
engineeringCouncilTimeoutMs: z2.number().step(1).min(1e4).max(3e5).default(12e4),
|
|
26938
|
-
engineeringCouncilQuorum: z2.number().step(1).min(1).max(3).default(2),
|
|
26939
|
-
engineeringCouncilAutoRun: z2.boolean().default(false),
|
|
26940
|
-
/**
|
|
26941
|
-
* The three phases of the autonomous engineering loop. Each is a separate
|
|
26942
|
-
* switch because they carry different risk: creating a goal only commits the
|
|
26943
|
-
* user to finishing, while enabling the driver lets work continue with no
|
|
26944
|
-
* human turn in between.
|
|
26945
|
-
*
|
|
26946
|
-
* - `engineeringLoopCapturePlan` — when the user approves a council decision,
|
|
26947
|
-
* persist the approved plan as a durable Harness goal.
|
|
26948
|
-
* - `engineeringLoopVerifyOnComplete` — when the active goal's driver reports
|
|
26949
|
-
* it finished, run the declared verification stages and record the result.
|
|
26950
|
-
* - `engineeringLoopAutoContinue` — let the Harness goal-round driver start
|
|
26951
|
-
* the next round without a user turn. Off by default: a goal that continues
|
|
26952
|
-
* unattended is the one behaviour a user must opt into explicitly.
|
|
26953
|
-
*/
|
|
26954
|
-
engineeringLoopCapturePlan: z2.boolean().default(true),
|
|
26955
|
-
engineeringLoopVerifyOnComplete: z2.boolean().default(true),
|
|
26956
|
-
engineeringLoopAutoContinue: z2.boolean().default(false),
|
|
26957
|
-
/** Round cap for a captured plan goal; bounds unattended continuation. */
|
|
26958
|
-
engineeringLoopMaxGoalRounds: z2.number().step(1).min(1).max(256).default(24),
|
|
26959
|
-
engineeringCouncilMaxTokens: z2.number().step(100).min(1200).max(2e4).default(3600),
|
|
26960
|
-
engineeringCouncilMaxConcurrent: z2.number().step(1).min(1).max(8).default(2),
|
|
26961
|
-
engineeringCouncilDecisionTtlMs: z2.number().step(6e4).min(6e4).max(10080 * 6e4).default(30 * 6e4)
|
|
26962
|
-
});
|
|
26963
26834
|
var GOAL_OBJECTIVE_MAX_CHARS = 8e3;
|
|
26964
26835
|
var GOAL_EXCERPT_MAX_CHARS = 160;
|
|
26965
26836
|
function goalPhaseOf(value) {
|
|
@@ -28486,10 +28357,7 @@ var FreeCodeGoEngineeringRegistry = class {
|
|
|
28486
28357
|
fence.close
|
|
28487
28358
|
].join("\n");
|
|
28488
28359
|
agent.inject(createUserMessage({
|
|
28489
|
-
source: {
|
|
28490
|
-
kind: "plugin",
|
|
28491
|
-
plugin: "freecodego-engineering-memory"
|
|
28492
|
-
},
|
|
28360
|
+
source: { kind: "freecodego-engineering-memory" },
|
|
28493
28361
|
content: [{
|
|
28494
28362
|
type: "text",
|
|
28495
28363
|
text: text2
|
|
@@ -28526,10 +28394,7 @@ var FreeCodeGoEngineeringRegistry = class {
|
|
|
28526
28394
|
if (built === void 0) return;
|
|
28527
28395
|
this.skillMapBudget = built.metrics;
|
|
28528
28396
|
agent.inject(createUserMessage({
|
|
28529
|
-
source: {
|
|
28530
|
-
kind: "plugin",
|
|
28531
|
-
plugin: "freecodego-engineering-skills"
|
|
28532
|
-
},
|
|
28397
|
+
source: { kind: "freecodego-engineering-skills" },
|
|
28533
28398
|
content: [{
|
|
28534
28399
|
type: "text",
|
|
28535
28400
|
text: built.text
|
|
@@ -29899,7 +29764,7 @@ function selectGraphEngine(preference, graphifyInstalled, codeGraphInstalled) {
|
|
|
29899
29764
|
}
|
|
29900
29765
|
function normalizeSettings(value) {
|
|
29901
29766
|
return {
|
|
29902
|
-
engineeringEnabled: value?.engineeringEnabled
|
|
29767
|
+
engineeringEnabled: value?.engineeringEnabled !== false,
|
|
29903
29768
|
engineeringSkillsEnabled: value?.engineeringSkillsEnabled === true,
|
|
29904
29769
|
engineeringStarterSkillsEnabled: value?.engineeringStarterSkillsEnabled !== false,
|
|
29905
29770
|
engineeringSuperpowersSkillsEnabled: value?.engineeringSuperpowersSkillsEnabled === true,
|
|
@@ -29929,12 +29794,12 @@ function normalizeSettings(value) {
|
|
|
29929
29794
|
engineeringCouncilDecisionTtlMs: boundedInteger$1(value?.engineeringCouncilDecisionTtlMs, 30 * 6e4, 6e4, 10080 * 6e4)
|
|
29930
29795
|
};
|
|
29931
29796
|
}
|
|
29932
|
-
function pendingRecall(agent,
|
|
29797
|
+
function pendingRecall(agent, producer) {
|
|
29933
29798
|
try {
|
|
29934
29799
|
const inbox = agent.inbox;
|
|
29935
29800
|
if (inbox === void 0) return false;
|
|
29936
|
-
const
|
|
29937
|
-
return (inbox.nextStep ?? []).some(
|
|
29801
|
+
const fromProducer = (message2) => isRecord2(message2.source) && message2.source.kind === producer;
|
|
29802
|
+
return (inbox.nextStep ?? []).some(fromProducer) || (inbox.nextTurn ?? []).some(fromProducer);
|
|
29938
29803
|
} catch {
|
|
29939
29804
|
return false;
|
|
29940
29805
|
}
|
|
@@ -30955,14 +30820,6 @@ function describeCronExpression(expression) {
|
|
|
30955
30820
|
}
|
|
30956
30821
|
return `cron ${expression.source}`;
|
|
30957
30822
|
}
|
|
30958
|
-
var FreeCodeGoAutomationSettingsSchema = z2.object({
|
|
30959
|
-
/** Master switch for declarative failure recovery. */
|
|
30960
|
-
hookChainsEnabled: z2.boolean().default(true),
|
|
30961
|
-
hookChainsMaxDepth: z2.number().step(1).min(0).max(10).default(2),
|
|
30962
|
-
hookChainsCooldownMs: z2.number().step(1e3).min(0).max(1440 * 60 * 1e3).default(3e4),
|
|
30963
|
-
/** Master switch for the calendar planner. */
|
|
30964
|
-
scheduledTasksEnabled: z2.boolean().default(true)
|
|
30965
|
-
});
|
|
30966
30823
|
var HOOK_CHAINS_RELATIVE_PATH = join4(".freecodego", "hook-chains.json");
|
|
30967
30824
|
function outcomeOfTurnEnd(reason) {
|
|
30968
30825
|
switch (typeof reason === "object" && reason !== null ? reason.kind : void 0) {
|
|
@@ -31458,7 +31315,21 @@ function setEngineAvailability(agentEngines, id, availability) {
|
|
|
31458
31315
|
} catch {
|
|
31459
31316
|
}
|
|
31460
31317
|
}
|
|
31318
|
+
var MODELS_SETTINGS_ENTRY = "llm-pi-ai";
|
|
31319
|
+
function peerSettings(ctx, entryId) {
|
|
31320
|
+
const settings = ctx.get("settings");
|
|
31321
|
+
if (typeof settings?.describe !== "function") return void 0;
|
|
31322
|
+
try {
|
|
31323
|
+
const descriptor = settings.describe().find((row) => row.ns === entryId);
|
|
31324
|
+
return descriptor === void 0 ? void 0 : maybeRecord(descriptor.value);
|
|
31325
|
+
} catch {
|
|
31326
|
+
return;
|
|
31327
|
+
}
|
|
31328
|
+
}
|
|
31461
31329
|
var DONE = "[DONE]";
|
|
31330
|
+
function unsupported(what) {
|
|
31331
|
+
throw new LlmError(`${what} cannot be serialized on this wire`, "UNSUPPORTED_CONTENT");
|
|
31332
|
+
}
|
|
31462
31333
|
async function* parseSse(stream) {
|
|
31463
31334
|
const events = stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream());
|
|
31464
31335
|
for await (const event of events) {
|
|
@@ -31561,8 +31432,8 @@ function serializeRequest(options, defaults = {}) {
|
|
|
31561
31432
|
content: options.system
|
|
31562
31433
|
});
|
|
31563
31434
|
for (const message2 of options.messages) {
|
|
31564
|
-
message2.content;
|
|
31565
31435
|
if (message2.role === "system") {
|
|
31436
|
+
message2.content;
|
|
31566
31437
|
messages.push({
|
|
31567
31438
|
role: "system",
|
|
31568
31439
|
content: text(message2.content)
|
|
@@ -31573,16 +31444,19 @@ function serializeRequest(options, defaults = {}) {
|
|
|
31573
31444
|
messages.push(serializeAssistant(message2));
|
|
31574
31445
|
continue;
|
|
31575
31446
|
}
|
|
31576
|
-
|
|
31577
|
-
|
|
31578
|
-
|
|
31579
|
-
|
|
31580
|
-
|
|
31581
|
-
|
|
31582
|
-
|
|
31583
|
-
|
|
31447
|
+
if (message2.role === "tool") {
|
|
31448
|
+
messages.push({
|
|
31449
|
+
role: "tool",
|
|
31450
|
+
tool_call_id: message2.toolCallId,
|
|
31451
|
+
content: text(message2.content) || "(no output)"
|
|
31452
|
+
});
|
|
31453
|
+
continue;
|
|
31454
|
+
}
|
|
31455
|
+
if (message2.role === "developer") unsupported("developer message");
|
|
31456
|
+
message2.content;
|
|
31457
|
+
messages.push({
|
|
31584
31458
|
role: "user",
|
|
31585
|
-
content
|
|
31459
|
+
content: text(message2.content)
|
|
31586
31460
|
});
|
|
31587
31461
|
}
|
|
31588
31462
|
return requestWithMessages(options, messages, defaults);
|
|
@@ -31607,14 +31481,17 @@ async function serializeRequestWithInlineImages(options, images, defaults = {})
|
|
|
31607
31481
|
messages.push(serializeAssistant(message2));
|
|
31608
31482
|
continue;
|
|
31609
31483
|
}
|
|
31610
|
-
|
|
31611
|
-
|
|
31612
|
-
|
|
31613
|
-
|
|
31614
|
-
|
|
31615
|
-
|
|
31616
|
-
|
|
31617
|
-
|
|
31484
|
+
if (message2.role === "tool") {
|
|
31485
|
+
messages.push({
|
|
31486
|
+
role: "tool",
|
|
31487
|
+
tool_call_id: message2.toolCallId,
|
|
31488
|
+
content: text(message2.content) || "(no output)"
|
|
31489
|
+
});
|
|
31490
|
+
continue;
|
|
31491
|
+
}
|
|
31492
|
+
if (message2.role === "developer") unsupported("developer message");
|
|
31493
|
+
const content = await inlineUserContent(message2.content, images);
|
|
31494
|
+
messages.push({
|
|
31618
31495
|
role: "user",
|
|
31619
31496
|
content: inlineUserWireContent(content)
|
|
31620
31497
|
});
|
|
@@ -31870,13 +31747,6 @@ async function anthropicContent(message2, images) {
|
|
|
31870
31747
|
case "tool-call":
|
|
31871
31748
|
if (message2.role === "assistant") blocks.push(anthropicToolUse(block));
|
|
31872
31749
|
break;
|
|
31873
|
-
case "tool-result":
|
|
31874
|
-
blocks.push({
|
|
31875
|
-
type: "tool_result",
|
|
31876
|
-
tool_use_id: block.toolCallId,
|
|
31877
|
-
content: textOf$2(block.content) || "(no output)"
|
|
31878
|
-
});
|
|
31879
|
-
break;
|
|
31880
31750
|
default:
|
|
31881
31751
|
break;
|
|
31882
31752
|
}
|
|
@@ -31886,19 +31756,38 @@ async function anthropicTurns(options, images) {
|
|
|
31886
31756
|
const systems = [];
|
|
31887
31757
|
if (options.system !== void 0 && options.system !== "") systems.push(options.system);
|
|
31888
31758
|
const messages = [];
|
|
31759
|
+
const results = [];
|
|
31760
|
+
const flushResults = () => {
|
|
31761
|
+
if (results.length === 0) return;
|
|
31762
|
+
messages.push({
|
|
31763
|
+
role: "user",
|
|
31764
|
+
content: results.splice(0)
|
|
31765
|
+
});
|
|
31766
|
+
};
|
|
31889
31767
|
for (const message2 of options.messages) {
|
|
31890
31768
|
if (message2.role === "system") {
|
|
31891
31769
|
const text2 = textOf$2(message2.content);
|
|
31892
31770
|
if (text2 !== "") systems.push(text2);
|
|
31893
31771
|
continue;
|
|
31894
31772
|
}
|
|
31773
|
+
if (message2.role === "developer") unsupported("developer message");
|
|
31774
|
+
if (message2.role === "tool") {
|
|
31775
|
+
results.push({
|
|
31776
|
+
type: "tool_result",
|
|
31777
|
+
tool_use_id: message2.toolCallId,
|
|
31778
|
+
content: textOf$2(message2.content) || "(no output)"
|
|
31779
|
+
});
|
|
31780
|
+
continue;
|
|
31781
|
+
}
|
|
31895
31782
|
const content = await anthropicContent(message2, images);
|
|
31896
31783
|
if (content.length === 0) continue;
|
|
31784
|
+
flushResults();
|
|
31897
31785
|
messages.push({
|
|
31898
31786
|
role: message2.role === "assistant" ? "assistant" : "user",
|
|
31899
31787
|
content
|
|
31900
31788
|
});
|
|
31901
31789
|
}
|
|
31790
|
+
flushResults();
|
|
31902
31791
|
return {
|
|
31903
31792
|
system: systems.length === 0 ? void 0 : systems.join("\n\n"),
|
|
31904
31793
|
messages
|
|
@@ -32234,7 +32123,7 @@ var OpenAiCompatibleAdapter = class extends LlmAdapter {
|
|
|
32234
32123
|
const detail = redactProviderDetail(await response.text().catch(() => ""));
|
|
32235
32124
|
if (response.status === 400) onBadRequest?.(detail);
|
|
32236
32125
|
if (response.status === 429) this.config.onRateLimited?.(this.config.providerName, response.status);
|
|
32237
|
-
const rateHint =
|
|
32126
|
+
const rateHint = this.config.rateLimitedHint?.(this.config.providerName, response.status, detail);
|
|
32238
32127
|
throw new LlmError(`${this.config.providerName} provider request failed (HTTP ${response.status})${detail === "" ? "" : `: ${detail}`}${rateHint === void 0 ? "" : `
|
|
32239
32128
|
${rateHint}`}`, llmCodeForUpstreamStatus(response.status), { status: response.status });
|
|
32240
32129
|
}
|
|
@@ -33347,21 +33236,29 @@ function audioMimeType(file) {
|
|
|
33347
33236
|
const extension = path.extname(file).toLowerCase();
|
|
33348
33237
|
return extension === ".webm" ? "audio/webm" : extension === ".ogg" || extension === ".opus" ? "audio/ogg" : extension === ".wav" ? "audio/wav" : extension === ".m4a" || extension === ".mp4" ? "audio/mp4" : extension === ".flac" ? "audio/flac" : "audio/mpeg";
|
|
33349
33238
|
}
|
|
33350
|
-
|
|
33239
|
+
var MEDIA_GENERATION_TOOL_NAMES = {
|
|
33240
|
+
image: "freecodego_generate_image",
|
|
33241
|
+
video: "freecodego_generate_video"
|
|
33242
|
+
};
|
|
33243
|
+
var NO_MEDIA_TOOLS = {
|
|
33244
|
+
names: [],
|
|
33245
|
+
dispose: () => void 0
|
|
33246
|
+
};
|
|
33247
|
+
var GENERIC_MEDIA_OUTPUT = {
|
|
33248
|
+
schema: {
|
|
33249
|
+
type: "object",
|
|
33250
|
+
additionalProperties: true
|
|
33251
|
+
},
|
|
33252
|
+
render: (_args, value) => [{
|
|
33253
|
+
type: "text",
|
|
33254
|
+
text: JSON.stringify(value)
|
|
33255
|
+
}]
|
|
33256
|
+
};
|
|
33257
|
+
function registerGenerationTools(host) {
|
|
33351
33258
|
const tools = host.ctx.get("tools");
|
|
33352
|
-
if (tools === void 0) return;
|
|
33353
|
-
const
|
|
33354
|
-
|
|
33355
|
-
type: "object",
|
|
33356
|
-
additionalProperties: true
|
|
33357
|
-
},
|
|
33358
|
-
render: (_args, value) => [{
|
|
33359
|
-
type: "text",
|
|
33360
|
-
text: JSON.stringify(value)
|
|
33361
|
-
}]
|
|
33362
|
-
};
|
|
33363
|
-
const disposeImage = tools.register(toolDefinition({
|
|
33364
|
-
name: "freecodego_generate_image",
|
|
33259
|
+
if (tools === void 0) return NO_MEDIA_TOOLS;
|
|
33260
|
+
const imageTool = toolDefinition({
|
|
33261
|
+
name: MEDIA_GENERATION_TOOL_NAMES.image,
|
|
33365
33262
|
description: "Generate an image with the user-selected default media model. Do not pass a model id. Pass images to edit or fuse existing pictures on the providers that accept sources. If that provider is unavailable, the Host safely tries another configured image model.",
|
|
33366
33263
|
parameters: {
|
|
33367
33264
|
type: "object",
|
|
@@ -33389,7 +33286,7 @@ function registerMediaTools(host) {
|
|
|
33389
33286
|
additionalProperties: false
|
|
33390
33287
|
},
|
|
33391
33288
|
output: {
|
|
33392
|
-
schema:
|
|
33289
|
+
schema: GENERIC_MEDIA_OUTPUT.schema,
|
|
33393
33290
|
render: (_args, value) => renderGeneratedImages(value)
|
|
33394
33291
|
},
|
|
33395
33292
|
execute: async (args, exec) => {
|
|
@@ -33399,9 +33296,9 @@ function registerMediaTools(host) {
|
|
|
33399
33296
|
card: "generic",
|
|
33400
33297
|
title: `Generate image: ${args.prompt}`
|
|
33401
33298
|
})
|
|
33402
|
-
})
|
|
33403
|
-
const
|
|
33404
|
-
name:
|
|
33299
|
+
});
|
|
33300
|
+
const videoTool = toolDefinition({
|
|
33301
|
+
name: MEDIA_GENERATION_TOOL_NAMES.video,
|
|
33405
33302
|
description: "Generate a video with the user-selected default media model. Do not pass a model id. If that provider is unavailable before task creation, the Host safely tries another configured video model.",
|
|
33406
33303
|
parameters: {
|
|
33407
33304
|
type: "object",
|
|
@@ -33440,7 +33337,7 @@ function registerMediaTools(host) {
|
|
|
33440
33337
|
required: ["prompt"],
|
|
33441
33338
|
additionalProperties: false
|
|
33442
33339
|
},
|
|
33443
|
-
output:
|
|
33340
|
+
output: GENERIC_MEDIA_OUTPUT,
|
|
33444
33341
|
execute: async (args, exec) => {
|
|
33445
33342
|
return host.generateVideoWithFallback(args, exec.signal);
|
|
33446
33343
|
},
|
|
@@ -33448,8 +33345,21 @@ function registerMediaTools(host) {
|
|
|
33448
33345
|
card: "generic",
|
|
33449
33346
|
title: `Generate video: ${args.prompt}`
|
|
33450
33347
|
})
|
|
33451
|
-
})
|
|
33452
|
-
const
|
|
33348
|
+
});
|
|
33349
|
+
const disposeImage = tools.register(imageTool);
|
|
33350
|
+
const disposeVideo = tools.register(videoTool);
|
|
33351
|
+
return {
|
|
33352
|
+
names: [imageTool.name, videoTool.name],
|
|
33353
|
+
dispose: () => {
|
|
33354
|
+
disposeImage();
|
|
33355
|
+
disposeVideo();
|
|
33356
|
+
}
|
|
33357
|
+
};
|
|
33358
|
+
}
|
|
33359
|
+
function registerAudioTools(host) {
|
|
33360
|
+
const tools = host.ctx.get("tools");
|
|
33361
|
+
if (tools === void 0) return NO_MEDIA_TOOLS;
|
|
33362
|
+
const audioTool = toolDefinition({
|
|
33453
33363
|
name: "freecodego_generate_audio",
|
|
33454
33364
|
description: "Generate speech/audio with the user-selected default media model. Do not pass a model id. The Host can fall back to another configured audio model when the selected provider is unavailable.",
|
|
33455
33365
|
parameters: {
|
|
@@ -33474,7 +33384,7 @@ function registerMediaTools(host) {
|
|
|
33474
33384
|
required: ["input"],
|
|
33475
33385
|
additionalProperties: false
|
|
33476
33386
|
},
|
|
33477
|
-
output:
|
|
33387
|
+
output: GENERIC_MEDIA_OUTPUT,
|
|
33478
33388
|
execute: async (args, exec) => {
|
|
33479
33389
|
return host.generateAudioWithFallback(args, exec.agent?.session.header.cwd, exec.signal);
|
|
33480
33390
|
},
|
|
@@ -33482,8 +33392,8 @@ function registerMediaTools(host) {
|
|
|
33482
33392
|
card: "generic",
|
|
33483
33393
|
title: "Generate audio with FreeCodeGo"
|
|
33484
33394
|
})
|
|
33485
|
-
})
|
|
33486
|
-
const
|
|
33395
|
+
});
|
|
33396
|
+
const transcribeTool = toolDefinition({
|
|
33487
33397
|
name: "freecodego_transcribe_audio",
|
|
33488
33398
|
description: "Transcribe an audio file with the fixed free Groq whisper-large-v3-turbo model. The file must be inside the active workspace.",
|
|
33489
33399
|
parameters: {
|
|
@@ -33499,7 +33409,7 @@ function registerMediaTools(host) {
|
|
|
33499
33409
|
required: ["path"],
|
|
33500
33410
|
additionalProperties: false
|
|
33501
33411
|
},
|
|
33502
|
-
output:
|
|
33412
|
+
output: GENERIC_MEDIA_OUTPUT,
|
|
33503
33413
|
execute: async (args, exec) => {
|
|
33504
33414
|
const cwd = exec.agent?.session.header.cwd;
|
|
33505
33415
|
if (cwd === void 0) throw new Error("Audio transcription requires an active workspace");
|
|
@@ -33531,13 +33441,16 @@ function registerMediaTools(host) {
|
|
|
33531
33441
|
card: "generic",
|
|
33532
33442
|
title: `Transcribe audio: ${args.path}`
|
|
33533
33443
|
})
|
|
33534
|
-
})
|
|
33535
|
-
|
|
33536
|
-
|
|
33537
|
-
|
|
33538
|
-
|
|
33539
|
-
|
|
33540
|
-
|
|
33444
|
+
});
|
|
33445
|
+
const disposeAudio = tools.register(audioTool);
|
|
33446
|
+
const disposeTranscribe = tools.register(transcribeTool);
|
|
33447
|
+
return {
|
|
33448
|
+
names: [audioTool.name, transcribeTool.name],
|
|
33449
|
+
dispose: () => {
|
|
33450
|
+
disposeAudio();
|
|
33451
|
+
disposeTranscribe();
|
|
33452
|
+
}
|
|
33453
|
+
};
|
|
33541
33454
|
}
|
|
33542
33455
|
async function generateImageWithFallback(host, args, signal) {
|
|
33543
33456
|
return withMediaFallback(host, "image", signal, async (route) => {
|
|
@@ -33890,7 +33803,7 @@ function mediaRoute(host, selection) {
|
|
|
33890
33803
|
};
|
|
33891
33804
|
}
|
|
33892
33805
|
async function configuredMediaConnection(host, route) {
|
|
33893
|
-
const profile = asRecord(asRecord(asRecord(host.ctx
|
|
33806
|
+
const profile = asRecord(asRecord(asRecord(peerSettings(host.ctx, MODELS_SETTINGS_ENTRY)).providers)[route.provider]);
|
|
33894
33807
|
const baseURL = asString(profile.baseURL) ?? defaultMediaBaseURL(route.provider);
|
|
33895
33808
|
if (baseURL === void 0) throw new Error(`Media provider "${route.provider}" needs a Base URL in the Harness Models settings`);
|
|
33896
33809
|
const reference = asString(profile.apiKeyEnv) ?? defaultMediaCredentialRef(route.provider);
|
|
@@ -34464,12 +34377,19 @@ function registerAdvisorTools(deps) {
|
|
|
34464
34377
|
disposeTeamImplementation();
|
|
34465
34378
|
}, "freecodego: Advisor and engineering council tools");
|
|
34466
34379
|
}
|
|
34467
|
-
|
|
34380
|
+
var AGNES_MEDIA_TOOL_NAMES = {
|
|
34381
|
+
image: "agnes_generate_image",
|
|
34382
|
+
video: "agnes_generate_video"
|
|
34383
|
+
};
|
|
34384
|
+
function registerAgnesMediaTools(deps) {
|
|
34468
34385
|
const client = deps.agnes;
|
|
34469
34386
|
const tools = deps.ctx.get("tools");
|
|
34470
|
-
if (client === void 0 || tools === void 0) return
|
|
34387
|
+
if (client === void 0 || tools === void 0) return {
|
|
34388
|
+
names: [],
|
|
34389
|
+
dispose: () => void 0
|
|
34390
|
+
};
|
|
34471
34391
|
const disposeImage = tools.register(toolDefinition({
|
|
34472
|
-
name:
|
|
34392
|
+
name: AGNES_MEDIA_TOOL_NAMES.image,
|
|
34473
34393
|
description: "Legacy image-generation tool name. Generate an image with the FreeCodeGo Settings image default; do not assume Agnes is selected. The Host routes this request through the configured default image model and falls back safely when unavailable.",
|
|
34474
34394
|
parameters: {
|
|
34475
34395
|
type: "object",
|
|
@@ -34505,7 +34425,7 @@ function registerAgnesTools(deps) {
|
|
|
34505
34425
|
})
|
|
34506
34426
|
}));
|
|
34507
34427
|
const disposeVideo = tools.register(toolDefinition({
|
|
34508
|
-
name:
|
|
34428
|
+
name: AGNES_MEDIA_TOOL_NAMES.video,
|
|
34509
34429
|
description: "Legacy video-generation tool name. Generate a video with the FreeCodeGo Settings video default; do not assume Agnes is selected. The Host routes this request through the configured default video model and falls back safely when unavailable.",
|
|
34510
34430
|
parameters: {
|
|
34511
34431
|
type: "object",
|
|
@@ -34556,10 +34476,13 @@ function registerAgnesTools(deps) {
|
|
|
34556
34476
|
title: `Generate video: ${args.prompt}`
|
|
34557
34477
|
})
|
|
34558
34478
|
}));
|
|
34559
|
-
|
|
34560
|
-
|
|
34561
|
-
|
|
34562
|
-
|
|
34479
|
+
return {
|
|
34480
|
+
names: [AGNES_MEDIA_TOOL_NAMES.image, AGNES_MEDIA_TOOL_NAMES.video],
|
|
34481
|
+
dispose: () => {
|
|
34482
|
+
disposeImage();
|
|
34483
|
+
disposeVideo();
|
|
34484
|
+
}
|
|
34485
|
+
};
|
|
34563
34486
|
}
|
|
34564
34487
|
var COMMUNITY_ASSET_HOSTS = /* @__PURE__ */ new Set([
|
|
34565
34488
|
"raw.githubusercontent.com",
|
|
@@ -36721,6 +36644,102 @@ async function ensureFreeCodeGoAgentPreset() {
|
|
|
36721
36644
|
return false;
|
|
36722
36645
|
}
|
|
36723
36646
|
}
|
|
36647
|
+
async function loaderSettled(ctx) {
|
|
36648
|
+
const loader = ctx?.root?.loader;
|
|
36649
|
+
if (typeof loader?.await !== "function") return;
|
|
36650
|
+
try {
|
|
36651
|
+
await loader.await.call(loader);
|
|
36652
|
+
} catch {
|
|
36653
|
+
}
|
|
36654
|
+
}
|
|
36655
|
+
function findUpstreamAgentPresets(ctx) {
|
|
36656
|
+
const get = ctx?.get;
|
|
36657
|
+
if (typeof get !== "function") return void 0;
|
|
36658
|
+
let candidate;
|
|
36659
|
+
try {
|
|
36660
|
+
candidate = get.call(ctx, "agentPresets");
|
|
36661
|
+
} catch {
|
|
36662
|
+
return;
|
|
36663
|
+
}
|
|
36664
|
+
const view = candidate;
|
|
36665
|
+
return typeof view?.list === "function" && typeof view?.register === "function" ? view : void 0;
|
|
36666
|
+
}
|
|
36667
|
+
var JS_EXPRESSION_TAG = "tag:yaml.org,2002:js";
|
|
36668
|
+
var PLATFORM_EXPRESSION = /^process\.platform\s*(===|!==)\s*'([^']+)'$/;
|
|
36669
|
+
var presetSchema = yaml.DEFAULT_SCHEMA.extend([new yaml.Type(JS_EXPRESSION_TAG, {
|
|
36670
|
+
kind: "scalar",
|
|
36671
|
+
construct: (source) => {
|
|
36672
|
+
const match = PLATFORM_EXPRESSION.exec(source.trim());
|
|
36673
|
+
if (match === null) throw new Error(`unsupported !!js expression in a bundled preset: ${source.trim()}`);
|
|
36674
|
+
return match[1] === "===" ? process.platform === match[2] : process.platform !== match[2];
|
|
36675
|
+
}
|
|
36676
|
+
})]);
|
|
36677
|
+
async function readBundledAgentPreset(presetId) {
|
|
36678
|
+
const source = presetSourceDirectory(presetId);
|
|
36679
|
+
if (source === void 0) return void 0;
|
|
36680
|
+
const metadata = maybeRecord(yaml.load(await readFile3(join4(source, "preset.yml"), "utf8"), { schema: presetSchema }));
|
|
36681
|
+
const loaded2 = yaml.load(await readFile3(join4(source, "agent.cordis.yml"), "utf8"), { schema: presetSchema });
|
|
36682
|
+
if (!Array.isArray(loaded2)) return void 0;
|
|
36683
|
+
const plugins = [];
|
|
36684
|
+
for (const row of loaded2) {
|
|
36685
|
+
const record3 = maybeRecord(row);
|
|
36686
|
+
if (record3 === void 0) return void 0;
|
|
36687
|
+
plugins.push(record3);
|
|
36688
|
+
}
|
|
36689
|
+
const name2 = metadata?.name;
|
|
36690
|
+
const description = metadata?.description;
|
|
36691
|
+
const order = metadata?.order;
|
|
36692
|
+
return {
|
|
36693
|
+
id: presetId,
|
|
36694
|
+
...typeof name2 === "string" && name2 !== "" ? { name: name2 } : {},
|
|
36695
|
+
...typeof description === "string" && description !== "" ? { description } : {},
|
|
36696
|
+
...typeof order === "number" && Number.isFinite(order) ? { order } : {},
|
|
36697
|
+
plugins
|
|
36698
|
+
};
|
|
36699
|
+
}
|
|
36700
|
+
function installFreeCodeGoAgentPresets(ctx) {
|
|
36701
|
+
const disposers = [];
|
|
36702
|
+
let released = false;
|
|
36703
|
+
const keep = (unregister) => {
|
|
36704
|
+
if (released) {
|
|
36705
|
+
Promise.resolve(unregister()).catch(() => {
|
|
36706
|
+
});
|
|
36707
|
+
return;
|
|
36708
|
+
}
|
|
36709
|
+
disposers.push(unregister);
|
|
36710
|
+
};
|
|
36711
|
+
return {
|
|
36712
|
+
done: (async () => {
|
|
36713
|
+
await loaderSettled(ctx);
|
|
36714
|
+
const registry = findUpstreamAgentPresets(ctx);
|
|
36715
|
+
if (registry === void 0) {
|
|
36716
|
+
await ensureFreeCodeGoAgentPreset();
|
|
36717
|
+
return;
|
|
36718
|
+
}
|
|
36719
|
+
let declared;
|
|
36720
|
+
try {
|
|
36721
|
+
declared = new Set((await registry.list()).map((row) => row.id));
|
|
36722
|
+
} catch {
|
|
36723
|
+
declared = /* @__PURE__ */ new Set();
|
|
36724
|
+
}
|
|
36725
|
+
for (const presetId of BUNDLED_PRESET_IDS) {
|
|
36726
|
+
if (declared.has(presetId)) continue;
|
|
36727
|
+
const definition = await readBundledAgentPreset(presetId);
|
|
36728
|
+
if (definition === void 0) continue;
|
|
36729
|
+
try {
|
|
36730
|
+
keep(await registry.register(definition));
|
|
36731
|
+
} catch {
|
|
36732
|
+
}
|
|
36733
|
+
}
|
|
36734
|
+
})().catch(() => {
|
|
36735
|
+
}),
|
|
36736
|
+
release: () => {
|
|
36737
|
+
released = true;
|
|
36738
|
+
for (const unregister of disposers.splice(0)) Promise.resolve(unregister()).catch(() => {
|
|
36739
|
+
});
|
|
36740
|
+
}
|
|
36741
|
+
};
|
|
36742
|
+
}
|
|
36724
36743
|
var DEFAULT_CAPACITY = 1e3;
|
|
36725
36744
|
var DEFAULT_TTL_MS = 30 * 6e4;
|
|
36726
36745
|
function computeKey(payload) {
|
|
@@ -42612,17 +42631,6 @@ Fix these and call the tool again; no child agent was started.`;
|
|
|
42612
42631
|
var run$1 = promisify(execFile);
|
|
42613
42632
|
var GIT_TIMEOUT_MS$1 = 1e4;
|
|
42614
42633
|
var MAX_GIT_OUTPUT$1 = 4096;
|
|
42615
|
-
var FreeCodeGoTrustSettingsSchema = z2.object({
|
|
42616
|
-
/**
|
|
42617
|
-
* Master switch for the whole gate.
|
|
42618
|
-
*
|
|
42619
|
-
* Off means every project-scoped surface is treated as trusted — the
|
|
42620
|
-
* pre-gate behaviour, kept reachable so a deployment that already controls
|
|
42621
|
-
* which repositories it opens is not forced to grant each one. It is
|
|
42622
|
-
* deliberately not the default: the safe state must not be the opt-in one.
|
|
42623
|
-
*/
|
|
42624
|
-
folderTrustEnabled: z2.boolean().default(true)
|
|
42625
|
-
});
|
|
42626
42634
|
var FOLDER_TRUST_ENV = "FREECODEGO_FOLDER_TRUST";
|
|
42627
42635
|
function folderTrustEnabled(settings) {
|
|
42628
42636
|
const raw = process.env[FOLDER_TRUST_ENV]?.trim().toLowerCase();
|
|
@@ -43359,10 +43367,7 @@ var AssistantLoopGuard = class {
|
|
|
43359
43367
|
injectReminder(agent, finding) {
|
|
43360
43368
|
try {
|
|
43361
43369
|
agent.inject(createUserMessage({
|
|
43362
|
-
source: {
|
|
43363
|
-
kind: "plugin",
|
|
43364
|
-
plugin: "freecodego-assistant-loop-guard"
|
|
43365
|
-
},
|
|
43370
|
+
source: { kind: "freecodego-assistant-loop-guard" },
|
|
43366
43371
|
content: [{
|
|
43367
43372
|
type: "text",
|
|
43368
43373
|
text: renderAssistantLoopReminder(finding)
|
|
@@ -44058,10 +44063,8 @@ function isHarnessPruned(message2) {
|
|
|
44058
44063
|
return text2 !== void 0 && text2.includes("[... tool result middle pruned ...]");
|
|
44059
44064
|
}
|
|
44060
44065
|
function hasOnlyTextContent(message2) {
|
|
44061
|
-
if (message2.role !== "
|
|
44062
|
-
const
|
|
44063
|
-
if (outer?.type !== "tool-result" || !Array.isArray(outer.content)) return false;
|
|
44064
|
-
const blocks = outer.content;
|
|
44066
|
+
if (message2.role !== "tool" || !Array.isArray(message2.content)) return false;
|
|
44067
|
+
const blocks = message2.content;
|
|
44065
44068
|
if (blocks.length === 0) return false;
|
|
44066
44069
|
return blocks.every((block) => block?.type === "text");
|
|
44067
44070
|
}
|
|
@@ -44072,17 +44075,13 @@ function isClearableResult(message2, tool2, clearable, clearedMarker) {
|
|
|
44072
44075
|
return hasOnlyTextContent(message2);
|
|
44073
44076
|
}
|
|
44074
44077
|
function resultText(message2) {
|
|
44075
|
-
if (message2.role !== "
|
|
44076
|
-
const outer = message2.content[0];
|
|
44077
|
-
if (outer?.type !== "tool-result" || !Array.isArray(outer.content)) return void 0;
|
|
44078
|
+
if (message2.role !== "tool" || !Array.isArray(message2.content)) return void 0;
|
|
44078
44079
|
const texts = [];
|
|
44079
|
-
for (const block of
|
|
44080
|
+
for (const block of message2.content) if (block?.type === "text" && typeof block.text === "string") texts.push(block.text);
|
|
44080
44081
|
return texts.join("\n");
|
|
44081
44082
|
}
|
|
44082
44083
|
function resultCallId(message2) {
|
|
44083
|
-
|
|
44084
|
-
const first = message2.content[0];
|
|
44085
|
-
return first?.type === "tool-result" && typeof first.toolCallId === "string" ? first.toolCallId : void 0;
|
|
44084
|
+
return message2.role === "tool" && typeof message2.toolCallId === "string" ? message2.toolCallId : void 0;
|
|
44086
44085
|
}
|
|
44087
44086
|
function clearOldToolResults(messages, options = {}) {
|
|
44088
44087
|
const clearable = options.clearableTools ?? CLEARABLE_TOOL_KINDS;
|
|
@@ -44133,12 +44132,8 @@ function clearOldToolResults(messages, options = {}) {
|
|
|
44133
44132
|
return {
|
|
44134
44133
|
...message2,
|
|
44135
44134
|
content: [{
|
|
44136
|
-
type: "
|
|
44137
|
-
|
|
44138
|
-
content: [{
|
|
44139
|
-
type: "text",
|
|
44140
|
-
text: replacement
|
|
44141
|
-
}]
|
|
44135
|
+
type: "text",
|
|
44136
|
+
text: replacement
|
|
44142
44137
|
}]
|
|
44143
44138
|
};
|
|
44144
44139
|
}),
|
|
@@ -45093,7 +45088,7 @@ function messageText$1(content, depth = 4) {
|
|
|
45093
45088
|
}
|
|
45094
45089
|
function isSummaryEvent(data) {
|
|
45095
45090
|
const message2 = data.message;
|
|
45096
|
-
if (message2?.source?.kind === "
|
|
45091
|
+
if (message2?.source?.kind === "compact-checkpoint") return true;
|
|
45097
45092
|
const text2 = messageText$1(message2?.content);
|
|
45098
45093
|
return text2.startsWith("<summary>") || text2.includes("<compacted-conversation");
|
|
45099
45094
|
}
|
|
@@ -45416,10 +45411,7 @@ function installRehydration(ctx, deps) {
|
|
|
45416
45411
|
const agent = ctx.agents?.get?.(String(session.id));
|
|
45417
45412
|
if (agent === void 0 || typeof agent.inject !== "function") return;
|
|
45418
45413
|
agent.inject(createUserMessage({
|
|
45419
|
-
source: {
|
|
45420
|
-
kind: "plugin",
|
|
45421
|
-
plugin: "freecodego-rehydration"
|
|
45422
|
-
},
|
|
45414
|
+
source: { kind: "freecodego-rehydration" },
|
|
45423
45415
|
content: [{
|
|
45424
45416
|
type: "text",
|
|
45425
45417
|
text: body
|
|
@@ -45446,10 +45438,7 @@ function createMemorySelector(options) {
|
|
|
45446
45438
|
provider: options.route.provider,
|
|
45447
45439
|
model: options.route.model,
|
|
45448
45440
|
messages: [createUserMessage({
|
|
45449
|
-
source: {
|
|
45450
|
-
kind: "plugin",
|
|
45451
|
-
plugin: "freecodego-memory-recall"
|
|
45452
|
-
},
|
|
45441
|
+
source: { kind: "freecodego-memory-recall" },
|
|
45453
45442
|
content: [{
|
|
45454
45443
|
type: "text",
|
|
45455
45444
|
text: selectorPrompt(query2, excerpts, limit)
|
|
@@ -45823,36 +45812,40 @@ function sortEntries(entries) {
|
|
|
45823
45812
|
return [...entries].sort((left, right) => left.name.localeCompare(right.name));
|
|
45824
45813
|
}
|
|
45825
45814
|
var FreeCodeGoPolicy = class {
|
|
45826
|
-
|
|
45815
|
+
config;
|
|
45816
|
+
writer;
|
|
45827
45817
|
/**
|
|
45828
|
-
* @param
|
|
45829
|
-
* composition
|
|
45830
|
-
*
|
|
45831
|
-
*
|
|
45818
|
+
* @param config - the plugin's resolved configuration, or `undefined` when the
|
|
45819
|
+
* composition supplies none (tests, a bare context). The policy is always
|
|
45820
|
+
* constructible so consumers never branch on its presence; they branch on
|
|
45821
|
+
* {@link configured} instead.
|
|
45822
|
+
* @param writer - the persistence step, absent when no settings service is mounted.
|
|
45832
45823
|
*/
|
|
45833
|
-
constructor(
|
|
45834
|
-
this.
|
|
45824
|
+
constructor(config, writer = void 0) {
|
|
45825
|
+
this.config = config;
|
|
45826
|
+
this.writer = writer;
|
|
45835
45827
|
}
|
|
45836
|
-
/** Whether a
|
|
45828
|
+
/** Whether a configuration was available when the plugin was built. */
|
|
45837
45829
|
get configured() {
|
|
45838
|
-
return this.
|
|
45830
|
+
return this.config !== void 0;
|
|
45839
45831
|
}
|
|
45840
45832
|
/**
|
|
45841
45833
|
* The settings a behaviour read must use.
|
|
45842
45834
|
*
|
|
45843
|
-
* The only read of the
|
|
45844
|
-
*
|
|
45845
|
-
*
|
|
45846
|
-
* @returns the resolved document, or `undefined` when no settings service exists.
|
|
45835
|
+
* The only read of the Config in this package, which is what makes it the place a
|
|
45836
|
+
* second configuration layer would have to be applied — see the module doc.
|
|
45837
|
+
* @returns the resolved document, or `undefined` when no configuration exists.
|
|
45847
45838
|
*/
|
|
45848
45839
|
get() {
|
|
45849
|
-
return this.
|
|
45840
|
+
return this.config === void 0 ? void 0 : resolveSettings(this.config);
|
|
45850
45841
|
}
|
|
45851
45842
|
/**
|
|
45852
45843
|
* Apply a user-originated change.
|
|
45853
45844
|
*
|
|
45854
|
-
*
|
|
45855
|
-
*
|
|
45845
|
+
* The write goes to this plugin's own profile entry, through the settings service that
|
|
45846
|
+
* owns validation, revisions, and the document write. A composition without that
|
|
45847
|
+
* service drops the patch rather than pretending to have stored it: the caller is a
|
|
45848
|
+
* user gesture whose failure the Web client reports from the RPC that carried it.
|
|
45856
45849
|
* @param patch - the fields to merge into the settings document. Typed as the
|
|
45857
45850
|
* harness types it (`object`) rather than as a `Partial` of the document,
|
|
45858
45851
|
* because a patch is a *merge*: the caller that owns one settings domain
|
|
@@ -45860,9 +45853,17 @@ var FreeCodeGoPolicy = class {
|
|
|
45860
45853
|
* force every caller to widen a patch it knows is already valid.
|
|
45861
45854
|
*/
|
|
45862
45855
|
async update(patch) {
|
|
45863
|
-
await this.
|
|
45856
|
+
await this.writer?.update(patch);
|
|
45864
45857
|
}
|
|
45865
45858
|
};
|
|
45859
|
+
function resolveSettings(config) {
|
|
45860
|
+
const document = {};
|
|
45861
|
+
for (const [key, entry] of Object.entries(config)) {
|
|
45862
|
+
if (!isVolatile(entry)) continue;
|
|
45863
|
+
document[key] = entry.get();
|
|
45864
|
+
}
|
|
45865
|
+
return document;
|
|
45866
|
+
}
|
|
45866
45867
|
var ROLLOUT_STAGES = [
|
|
45867
45868
|
"off",
|
|
45868
45869
|
"record_only",
|
|
@@ -46446,10 +46447,7 @@ function createMemoryDreamPlanner(options) {
|
|
|
46446
46447
|
provider: options.route.provider,
|
|
46447
46448
|
model: options.route.model,
|
|
46448
46449
|
messages: [createUserMessage({
|
|
46449
|
-
source: {
|
|
46450
|
-
kind: "plugin",
|
|
46451
|
-
plugin: "freecodego-memory-dream"
|
|
46452
|
-
},
|
|
46450
|
+
source: { kind: "freecodego-memory-dream" },
|
|
46453
46451
|
content: [{
|
|
46454
46452
|
type: "text",
|
|
46455
46453
|
text: dreamPrompt(request)
|
|
@@ -46706,10 +46704,7 @@ function createActionReviewer(input) {
|
|
|
46706
46704
|
provider: input.route.provider,
|
|
46707
46705
|
model: input.route.model,
|
|
46708
46706
|
messages: [createUserMessage({
|
|
46709
|
-
source: {
|
|
46710
|
-
kind: "plugin",
|
|
46711
|
-
plugin: "freecodego-action-review"
|
|
46712
|
-
},
|
|
46707
|
+
source: { kind: "freecodego-action-review" },
|
|
46713
46708
|
content: [{
|
|
46714
46709
|
type: "text",
|
|
46715
46710
|
text: reviewPrompt(composed, action)
|
|
@@ -46802,10 +46797,6 @@ function messageText(message2) {
|
|
|
46802
46797
|
const block = item;
|
|
46803
46798
|
if (block.type === "text" || block.type === "reasoning") return block.text ?? "";
|
|
46804
46799
|
if (block.type === "tool-call") return `${block.name ?? ""}(${block.arguments ?? ""})`;
|
|
46805
|
-
if (block.type === "tool-result") return (block.content ?? []).map((part) => {
|
|
46806
|
-
const item2 = part;
|
|
46807
|
-
return item2.type === "text" ? item2.text ?? "" : `[${item2.type ?? "unknown"}]`;
|
|
46808
|
-
}).join("\n");
|
|
46809
46800
|
return block.type === void 0 ? "" : `[${block.type}]`;
|
|
46810
46801
|
}).join("\n");
|
|
46811
46802
|
}
|
|
@@ -52093,7 +52084,12 @@ function imageInputModalities(id, name2) {
|
|
|
52093
52084
|
return /(?:\bgpt[\s_.-]?(?:4o|4\.1|4\.5|5)\b|\bgemini\b|\bclaude\b|\bgrok\b|(?:[-_.]|\b)(?:vision|vl|4v)(?:[-_.]|\b))/iu.test(value) ? ["text", "image"] : ["text"];
|
|
52094
52085
|
}
|
|
52095
52086
|
var RATE_LIMIT_PROXY_HINT = "\u5F53\u524D IP \u53EF\u80FD\u88AB\u4E0A\u6E38\u9650\u6D41\uFF1A\u8BF7\u5C1D\u8BD5\u5173\u95ED\u672C\u5730/\u5168\u5C40\u4EE3\u7406\u540E\u91CD\u8BD5\u3002\nYour current IP may be rate-limited by the upstream: try disabling your local/global proxy and retry.";
|
|
52096
|
-
var KILO_RATE_LIMIT_HINT = "Kilo \u514D\u8D39\u901A\u9053\u6309\u51FA\u53E3 IP \u9650\u6D41\uFF08\u5B98\u65B9\u914D\u989D\uFF1A\u6BCF\u5C0F\u65F6 200 \u6B21\uFF0C\u767B\u5F55\u4E0E\u5426\u90FD\u4E00\u6837\uFF09\uFF0C\u5F53\u524D\u7F51\u7EDC\u53EF\u80FD\u5DF2\u7528\u5B8C\uFF1A\
|
|
52087
|
+
var KILO_RATE_LIMIT_HINT = "Kilo \u514D\u8D39\u901A\u9053\u6309\u51FA\u53E3 IP \u9650\u6D41\uFF08\u5B98\u65B9\u914D\u989D\uFF1A\u6BCF\u5C0F\u65F6 200 \u6B21\uFF0C\u767B\u5F55\u4E0E\u5426\u90FD\u4E00\u6837\uFF09\uFF0C\u5F53\u524D\u7F51\u7EDC\u53EF\u80FD\u5DF2\u7528\u5B8C\uFF1A\u8BF7\u66F4\u6362\u8282\u70B9 IP \u540E\u91CD\u8BD5\uFF0C\u6216\u5173\u95ED\u4EE3\u7406\u3001\u7528\u771F\u5B9E IP \u8BBF\u95EE\u3002\nKilo meters its free routes per egress IP (200 requests/hour, signed in or not) and this network may be out of budget: switch to a different node IP, or disable your proxy and retry from your real IP.";
|
|
52088
|
+
var OPENCODE_FREE_TIER_HINT = 'OpenCode \u514D\u8D39\u989D\u5EA6\u6309\u51FA\u53E3 IP \u5224\u5B9A\uFF1A\u5F53\u524D\u8282\u70B9 IP \u88AB\u4E0A\u6E38\u5224\u4E3A\u975E\u5B98\u65B9\u5BA2\u6237\u7AEF\uFF08\u4E0A\u6E38\u539F\u6587\uFF1Afree tier can only be used from within OpenCode\uFF09\uFF0C\u4E0D\u662F\u6A21\u578B\u6216\u5BC6\u94A5\u7684\u95EE\u9898\u3002\u8BF7\u66F4\u6362\u8282\u70B9 IP \u540E\u91CD\u8BD5\uFF0C\u6216\u5173\u95ED\u4EE3\u7406\u3001\u7528\u771F\u5B9E IP \u8BBF\u95EE\u3002\nOpenCode decides its free tier by egress IP: this node address is not accepted as its own client (upstream: "free tier can only be used from within OpenCode"), so neither the model nor the key is the problem. Switch to a different node IP, or disable your proxy and retry from your real IP.';
|
|
52089
|
+
function isOpenCodeFreeTierRefusal(status, detail) {
|
|
52090
|
+
if (status !== 403) return false;
|
|
52091
|
+
return /FreeTierError|free tier can only be used/iu.test(detail);
|
|
52092
|
+
}
|
|
52097
52093
|
var FREE_UPSTREAM_MODELS = [
|
|
52098
52094
|
{
|
|
52099
52095
|
id: "mimo-v2.5",
|
|
@@ -52497,7 +52493,10 @@ var FreeCodeGoManagedCatalogs = class {
|
|
|
52497
52493
|
normalizeReasoningEffort: (effort) => isDirectReasoningEffort(effort) ? effort : void 0,
|
|
52498
52494
|
defaultReasoningEffort: "off",
|
|
52499
52495
|
reasoningEffortsForModel: () => DIRECT_REASONING_EFFORTS,
|
|
52500
|
-
rateLimitedHint: () =>
|
|
52496
|
+
rateLimitedHint: (_provider, status, detail) => {
|
|
52497
|
+
if (isOpenCodeFreeTierRefusal(status, detail)) return OPENCODE_FREE_TIER_HINT;
|
|
52498
|
+
return status === 429 ? RATE_LIMIT_PROXY_HINT : void 0;
|
|
52499
|
+
},
|
|
52501
52500
|
omitDefaultMaxTokens: true,
|
|
52502
52501
|
omitMaxTokens: true,
|
|
52503
52502
|
defaultContextWindow: 1e6,
|
|
@@ -52523,7 +52522,7 @@ var FreeCodeGoManagedCatalogs = class {
|
|
|
52523
52522
|
headers: { "user-agent": "freecodego/kilo" }
|
|
52524
52523
|
};
|
|
52525
52524
|
},
|
|
52526
|
-
rateLimitedHint: () => KILO_RATE_LIMIT_HINT,
|
|
52525
|
+
rateLimitedHint: (_provider, status) => status === 429 ? KILO_RATE_LIMIT_HINT : void 0,
|
|
52527
52526
|
reasoningWire: "standard",
|
|
52528
52527
|
normalizeReasoningEffort: (effort) => isDirectReasoningEffort(effort) ? effort : void 0,
|
|
52529
52528
|
defaultReasoningEffort: "off",
|
|
@@ -52863,8 +52862,8 @@ var FreeCodeGoManagedCatalogs = class {
|
|
|
52863
52862
|
/** Refresh user-visible gateway monitor facts without delaying model picker paint. */
|
|
52864
52863
|
refreshGatewayHealthInBackground() {
|
|
52865
52864
|
const endpoint = this.deps.gatewayBaseUrl();
|
|
52866
|
-
const
|
|
52867
|
-
if (
|
|
52865
|
+
const unsupported2 = this.gatewayHealthUnsupported;
|
|
52866
|
+
if (unsupported2 !== void 0 && unsupported2.endpoint === endpoint && Date.now() < unsupported2.expiresAt || this.deps.api() === void 0 || this.deps.account() === void 0 || this.deps.account().snapshot().status !== "authenticated") return;
|
|
52868
52867
|
const now = Date.now();
|
|
52869
52868
|
if (this.gatewayHealthPromise !== void 0 || (this.gatewayHealthCache?.expiresAt ?? 0) > now || this.gatewayHealthRefreshAfter > now) return;
|
|
52870
52869
|
this.gatewayHealthRefreshAfter = now + GATEWAY_HEALTH_CACHE_TTL_MS;
|
|
@@ -55156,10 +55155,7 @@ function renderFile(file) {
|
|
|
55156
55155
|
lines.push("</file>");
|
|
55157
55156
|
return lines.join("\n");
|
|
55158
55157
|
}
|
|
55159
|
-
var REVIEW_MESSAGE_SOURCE = {
|
|
55160
|
-
kind: "plugin",
|
|
55161
|
-
plugin: "freecodego/review"
|
|
55162
|
-
};
|
|
55158
|
+
var REVIEW_MESSAGE_SOURCE = { kind: "freecodego/review" };
|
|
55163
55159
|
function createReviewModelPort(llm, resolveRoute2, sessionId) {
|
|
55164
55160
|
return { async generate(request) {
|
|
55165
55161
|
const route = resolveRoute2();
|
|
@@ -58048,10 +58044,7 @@ function wrapChild(handle, maxOutputChars) {
|
|
|
58048
58044
|
return {
|
|
58049
58045
|
async run(prompt) {
|
|
58050
58046
|
handle.agent.followup(createUserMessage({
|
|
58051
|
-
source: {
|
|
58052
|
-
kind: "plugin",
|
|
58053
|
-
plugin: "freecodego-review"
|
|
58054
|
-
},
|
|
58047
|
+
source: { kind: "freecodego-review" },
|
|
58055
58048
|
content: [{
|
|
58056
58049
|
type: "text",
|
|
58057
58050
|
text: prompt
|
|
@@ -58363,6 +58356,14 @@ function narrowTurnScope(turnPaths, changedPaths) {
|
|
|
58363
58356
|
const changed = new Set(changedPaths);
|
|
58364
58357
|
return turnPaths.every((path3) => changed.has(path3)) ? turnPaths : changedPaths;
|
|
58365
58358
|
}
|
|
58359
|
+
function isCallbackTarget(target) {
|
|
58360
|
+
if (target === void 0) return false;
|
|
58361
|
+
try {
|
|
58362
|
+
return new URL(target, "http://127.0.0.1").pathname === TRAE_CALLBACK_PATH;
|
|
58363
|
+
} catch {
|
|
58364
|
+
return false;
|
|
58365
|
+
}
|
|
58366
|
+
}
|
|
58366
58367
|
function completionPage(language) {
|
|
58367
58368
|
const title = language === "zh" ? "TRAE \u6388\u6743\u5DF2\u6536\u5230" : "TRAE authorization received";
|
|
58368
58369
|
return `<!doctype html><html><head><meta charset="utf-8"><title>${title}</title></head><body style="font-family:system-ui;margin:48px;color:#222"><h1 style="font-size:20px">${title}</h1><p>${language === "zh" ? "\u8BF7\u56DE\u5230\u5E94\u7528\u67E5\u770B\u767B\u5F55\u7ED3\u679C\u3002" : "Return to the app to see the result."}</p></body></html>`;
|
|
@@ -58370,7 +58371,7 @@ function completionPage(language) {
|
|
|
58370
58371
|
async function startTraeCallbackListener(onCallback, language = "zh") {
|
|
58371
58372
|
const server = createServer((request, response) => {
|
|
58372
58373
|
const url = request.url === void 0 ? "/" : request.url;
|
|
58373
|
-
if (!url
|
|
58374
|
+
if (!isCallbackTarget(url)) {
|
|
58374
58375
|
response.writeHead(404, { "content-type": "text/plain; charset=utf-8" });
|
|
58375
58376
|
response.end("not found");
|
|
58376
58377
|
return;
|
|
@@ -61248,10 +61249,7 @@ async function engineeringTeamDecision(host, sessionId, request) {
|
|
|
61248
61249
|
if (goalId !== void 0) host.engineering.armApprovedPlanGoal(agent);
|
|
61249
61250
|
}
|
|
61250
61251
|
agent.inject(createUserMessage({
|
|
61251
|
-
source: {
|
|
61252
|
-
kind: "plugin",
|
|
61253
|
-
plugin: "freecodego-engine-council"
|
|
61254
|
-
},
|
|
61252
|
+
source: { kind: "freecodego-engine-council" },
|
|
61255
61253
|
content: [{
|
|
61256
61254
|
type: "text",
|
|
61257
61255
|
text: decision.state === "approved" ? goalId === void 0 ? "The user approved engineering council " + decision.id + ". You may implement the reviewed plan, then run council verification." : "The user approved engineering council " + decision.id + '. The approved plan is now goal "' + goalId + '", which the Harness continues automatically while it stays active. Work the plan to completion, then run council verification.' : "The user rejected engineering council " + decision.id + ". Do not implement this plan; revise it or start a new council."
|
|
@@ -61283,10 +61281,7 @@ async function engineeringTeamVerify(host, sessionId, request) {
|
|
|
61283
61281
|
}
|
|
61284
61282
|
await host.engineCouncil.recordVerification(agent, input.id, result);
|
|
61285
61283
|
agent.inject(createUserMessage({
|
|
61286
|
-
source: {
|
|
61287
|
-
kind: "plugin",
|
|
61288
|
-
plugin: "freecodego-engine-council"
|
|
61289
|
-
},
|
|
61284
|
+
source: { kind: "freecodego-engine-council" },
|
|
61290
61285
|
content: [{
|
|
61291
61286
|
type: "text",
|
|
61292
61287
|
text: "Engineering council " + input.id + " verification is complete. Read the durable verification result and report failed, skipped, unavailable, or cancelled stages accurately."
|
|
@@ -61302,10 +61297,7 @@ async function engineeringTeamImplementation(host, sessionId, request) {
|
|
|
61302
61297
|
const implementation = await host.engineCouncil.recordImplementation(agent, request.id, request.summary);
|
|
61303
61298
|
engineeringTeamVerify(host, sessionId, { id: request.id }).catch(() => void 0);
|
|
61304
61299
|
agent.inject(createUserMessage({
|
|
61305
|
-
source: {
|
|
61306
|
-
kind: "plugin",
|
|
61307
|
-
plugin: "freecodego-engine-council"
|
|
61308
|
-
},
|
|
61300
|
+
source: { kind: "freecodego-engine-council" },
|
|
61309
61301
|
content: [{
|
|
61310
61302
|
type: "text",
|
|
61311
61303
|
text: `Implementation for engineering council ${request.id} was marked complete. Executed verification (build/types/lint/tests) is starting automatically; read its durable result when reporting completion.`
|
|
@@ -61535,6 +61527,73 @@ var WorkBuddyPoolService = class {
|
|
|
61535
61527
|
return results;
|
|
61536
61528
|
}
|
|
61537
61529
|
};
|
|
61530
|
+
var WEB_SEARCH_API_KEY_REF = credentialRef2("FREECODEGO_WEB_SEARCH_API_KEY");
|
|
61531
|
+
var WEB_SEARCH_SETTINGS_NAMESPACE = "web-search-deepseek";
|
|
61532
|
+
function messageOf(error) {
|
|
61533
|
+
return error instanceof Error ? error.message : String(error);
|
|
61534
|
+
}
|
|
61535
|
+
function classify(section, servesBridgeRoute) {
|
|
61536
|
+
if (section === void 0) return {
|
|
61537
|
+
state: "none",
|
|
61538
|
+
alive: true
|
|
61539
|
+
};
|
|
61540
|
+
if (asString(section.apiKeyEnv) !== WEB_SEARCH_API_KEY_REF) return {
|
|
61541
|
+
state: "other",
|
|
61542
|
+
alive: true
|
|
61543
|
+
};
|
|
61544
|
+
const saved = asString(section.baseURL);
|
|
61545
|
+
if (saved === void 0) return {
|
|
61546
|
+
state: "other",
|
|
61547
|
+
alive: true
|
|
61548
|
+
};
|
|
61549
|
+
const routeId = bridgeRouteIdOf(saved);
|
|
61550
|
+
return routeId === void 0 ? {
|
|
61551
|
+
state: "durable",
|
|
61552
|
+
alive: true
|
|
61553
|
+
} : {
|
|
61554
|
+
state: "bridge",
|
|
61555
|
+
alive: servesBridgeRoute(routeId)
|
|
61556
|
+
};
|
|
61557
|
+
}
|
|
61558
|
+
async function webSearchBindingStatus(deps) {
|
|
61559
|
+
const status = classify(await deps.readSection(), deps.servesBridgeRoute);
|
|
61560
|
+
return deps.remembered === void 0 ? status : {
|
|
61561
|
+
...status,
|
|
61562
|
+
remembered: deps.remembered
|
|
61563
|
+
};
|
|
61564
|
+
}
|
|
61565
|
+
async function repairWebSearchBinding(deps) {
|
|
61566
|
+
let section;
|
|
61567
|
+
try {
|
|
61568
|
+
section = await deps.readSection();
|
|
61569
|
+
} catch (error) {
|
|
61570
|
+
return {
|
|
61571
|
+
outcome: "failed",
|
|
61572
|
+
detail: messageOf(error)
|
|
61573
|
+
};
|
|
61574
|
+
}
|
|
61575
|
+
const status = classify(section, deps.servesBridgeRoute);
|
|
61576
|
+
if (status.state === "none") return { outcome: "unavailable" };
|
|
61577
|
+
if (status.state === "other") return { outcome: "not-applicable" };
|
|
61578
|
+
if (status.alive) return { outcome: "live" };
|
|
61579
|
+
const remembered = deps.remembered;
|
|
61580
|
+
if (remembered === void 0) return { outcome: "no-memory" };
|
|
61581
|
+
try {
|
|
61582
|
+
const binding = await deps.bind(remembered);
|
|
61583
|
+
await deps.writeCredential(binding.apiKeyEnv, binding.apiKey);
|
|
61584
|
+
await deps.writeSection({
|
|
61585
|
+
model: binding.model,
|
|
61586
|
+
baseURL: binding.baseURL,
|
|
61587
|
+
apiKeyEnv: binding.apiKeyEnv
|
|
61588
|
+
});
|
|
61589
|
+
return { outcome: "rebuilt" };
|
|
61590
|
+
} catch (error) {
|
|
61591
|
+
return {
|
|
61592
|
+
outcome: "failed",
|
|
61593
|
+
detail: messageOf(error)
|
|
61594
|
+
};
|
|
61595
|
+
}
|
|
61596
|
+
}
|
|
61538
61597
|
var FREECODEGO_CLOUD_ORIGIN = "https://freecodego.com";
|
|
61539
61598
|
async function setDefaultEngine(host, engine) {
|
|
61540
61599
|
if (engine !== "deepseek" && engine !== "codex" && engine !== "claude") throw new Error("agent engine must be deepseek, codex, or claude");
|
|
@@ -61587,9 +61646,9 @@ async function setDefaultModel(host, model) {
|
|
|
61587
61646
|
return { model: persisted };
|
|
61588
61647
|
}
|
|
61589
61648
|
function defaultAgentOptions(host) {
|
|
61590
|
-
const configuredEngine = host.policy.get()?.defaultEngine ??
|
|
61649
|
+
const configuredEngine = host.policy.get()?.defaultEngine ?? "deepseek";
|
|
61591
61650
|
const engine = configuredEngine === "codex" || configuredEngine === "claude" ? configuredEngine : "deepseek";
|
|
61592
|
-
const model = host.policy.get()?.defaultModel
|
|
61651
|
+
const model = host.policy.get()?.defaultModel;
|
|
61593
61652
|
const normalizedModel = model?.trim();
|
|
61594
61653
|
if (normalizedModel !== void 0 && AGNES_TEXT_MODEL_IDS.has(normalizedModel)) return {
|
|
61595
61654
|
engine,
|
|
@@ -61799,6 +61858,26 @@ async function sessionDelete(host, sessionId) {
|
|
|
61799
61858
|
host.ctx.emit("api-session/removed", id);
|
|
61800
61859
|
return { deleted: true };
|
|
61801
61860
|
}
|
|
61861
|
+
async function webSearchBind(host, input) {
|
|
61862
|
+
if (input === null || typeof input !== "object") throw new Error("web search binding must be an object");
|
|
61863
|
+
const provider = typeof input.provider === "string" ? input.provider.trim().toLowerCase() : "";
|
|
61864
|
+
const model = typeof input.model === "string" ? input.model.trim() : "";
|
|
61865
|
+
if (provider === "" || model === "") throw new Error("a provider and a model are required");
|
|
61866
|
+
const route = await host.catalogs.claudeGatewayForRoute({
|
|
61867
|
+
provider,
|
|
61868
|
+
modelId: model
|
|
61869
|
+
});
|
|
61870
|
+
const base = route.baseURL.replace(/\/+$/u, "");
|
|
61871
|
+
if (!/^https?:\/\//iu.test(base)) throw new Error(`Provider "${provider}" did not resolve an HTTP endpoint`);
|
|
61872
|
+
return {
|
|
61873
|
+
provider,
|
|
61874
|
+
model: route.model ?? model,
|
|
61875
|
+
baseURL: /\/v1$/u.test(base) ? base : `${base}/v1`,
|
|
61876
|
+
apiKeyEnv: WEB_SEARCH_API_KEY_REF,
|
|
61877
|
+
apiKey: route.apiKey,
|
|
61878
|
+
durable: !/^https?:\/\/(127\.0\.0\.1|localhost|\[::1\])(?::\d+)?(?:\/|$)/iu.test(base)
|
|
61879
|
+
};
|
|
61880
|
+
}
|
|
61802
61881
|
async function capabilitiesSnapshot(host) {
|
|
61803
61882
|
return host.capabilities.snapshot();
|
|
61804
61883
|
}
|
|
@@ -62157,9 +62236,7 @@ function configuredProviderRoute(ctx, model) {
|
|
|
62157
62236
|
model: model.slice(provider.length + 1)
|
|
62158
62237
|
};
|
|
62159
62238
|
}
|
|
62160
|
-
const
|
|
62161
|
-
if (typeof settings?.get !== "function") return void 0;
|
|
62162
|
-
const providers = asRecord(asRecord(settings.get("llm-pi-ai")).providers);
|
|
62239
|
+
const providers = asRecord(asRecord(peerSettings(ctx, MODELS_SETTINGS_ENTRY)).providers);
|
|
62163
62240
|
for (const [provider, profile] of Object.entries(providers)) {
|
|
62164
62241
|
const row = asRecord(profile);
|
|
62165
62242
|
if ((Array.isArray(row.models) ? row.models : []).some((entry) => asRecord(entry).id === model || String(asRecord(entry).id ?? "").toLowerCase() === model.toLowerCase())) return {
|
|
@@ -62443,7 +62520,7 @@ var MEMORY_CASES = [
|
|
|
62443
62520
|
suite: "memory",
|
|
62444
62521
|
claim: "A shared file is preferred over a shared session, because it is the actionable link.",
|
|
62445
62522
|
measure: () => {
|
|
62446
|
-
const
|
|
62523
|
+
const classify2 = (sharedFile, sameTurn, sameSession) => sharedFile !== void 0 ? "shared-file" : sameTurn ? "same-turn" : sameSession ? "same-session" : "none";
|
|
62447
62524
|
const cases = [
|
|
62448
62525
|
[
|
|
62449
62526
|
"shared-file",
|
|
@@ -62470,7 +62547,7 @@ var MEMORY_CASES = [
|
|
|
62470
62547
|
true
|
|
62471
62548
|
]
|
|
62472
62549
|
];
|
|
62473
|
-
const correct = cases.filter(([expected, file, turn, session]) =>
|
|
62550
|
+
const correct = cases.filter(([expected, file, turn, session]) => classify2(file, turn, session) === expected).length;
|
|
62474
62551
|
return {
|
|
62475
62552
|
observed: correct / cases.length,
|
|
62476
62553
|
required: 1,
|
|
@@ -62793,28 +62870,43 @@ var WIRE_CASES = [
|
|
|
62793
62870
|
{
|
|
62794
62871
|
id: "wire.tool-results-stay-adjacent",
|
|
62795
62872
|
suite: "wire",
|
|
62796
|
-
claim: "
|
|
62873
|
+
claim: "A tool result is its own tool-role message and follows the assistant frame that asked for it, with later text as a user turn.",
|
|
62797
62874
|
measure: () => {
|
|
62798
62875
|
const roles = wireMessages(serializeRequest({
|
|
62799
62876
|
provider: "logfare",
|
|
62800
62877
|
model: "gpt-5.6-sol",
|
|
62801
|
-
messages: [
|
|
62802
|
-
|
|
62803
|
-
|
|
62804
|
-
|
|
62805
|
-
|
|
62806
|
-
|
|
62807
|
-
|
|
62808
|
-
|
|
62878
|
+
messages: [
|
|
62879
|
+
createAssistantMessage2({
|
|
62880
|
+
source: {
|
|
62881
|
+
provider: "logfare",
|
|
62882
|
+
model: "gpt-5.6-sol"
|
|
62883
|
+
},
|
|
62884
|
+
content: [{
|
|
62885
|
+
type: "tool-call",
|
|
62886
|
+
id: ToolCallId("call-1"),
|
|
62887
|
+
name: "read",
|
|
62888
|
+
arguments: '{"path":"a"}'
|
|
62889
|
+
}]
|
|
62890
|
+
}),
|
|
62891
|
+
createToolResultMessage2({
|
|
62892
|
+
callId: ToolCallId("call-1"),
|
|
62809
62893
|
content: [{
|
|
62810
62894
|
type: "text",
|
|
62811
62895
|
text: "ok"
|
|
62896
|
+
}],
|
|
62897
|
+
isError: false
|
|
62898
|
+
}),
|
|
62899
|
+
createUserMessage({
|
|
62900
|
+
source: { kind: "user" },
|
|
62901
|
+
content: [{
|
|
62902
|
+
type: "text",
|
|
62903
|
+
text: "Continue the discussion."
|
|
62812
62904
|
}]
|
|
62813
|
-
}
|
|
62814
|
-
|
|
62905
|
+
})
|
|
62906
|
+
]
|
|
62815
62907
|
})).map((message2) => message2.role);
|
|
62816
62908
|
return {
|
|
62817
|
-
observed: roles.join(",") === "tool,user" ? 1 : 0,
|
|
62909
|
+
observed: roles.join(",") === "assistant,tool,user" ? 1 : 0,
|
|
62818
62910
|
required: 1,
|
|
62819
62911
|
detail: `roles=${roles.join(",")}`
|
|
62820
62912
|
};
|
|
@@ -62835,16 +62927,13 @@ var WIRE_CASES = [
|
|
|
62835
62927
|
const first = wireMessages(serializeRequest({
|
|
62836
62928
|
provider: "logfare",
|
|
62837
62929
|
model: "gpt-5.6-sol",
|
|
62838
|
-
messages: [
|
|
62839
|
-
|
|
62930
|
+
messages: [createToolResultMessage2({
|
|
62931
|
+
callId: ToolCallId("call-1"),
|
|
62840
62932
|
content: [{
|
|
62841
|
-
type: "
|
|
62842
|
-
|
|
62843
|
-
|
|
62844
|
-
|
|
62845
|
-
attachment
|
|
62846
|
-
}]
|
|
62847
|
-
}]
|
|
62933
|
+
type: "image",
|
|
62934
|
+
attachment
|
|
62935
|
+
}],
|
|
62936
|
+
isError: false
|
|
62848
62937
|
})]
|
|
62849
62938
|
}))[0];
|
|
62850
62939
|
return {
|
|
@@ -65897,23 +65986,42 @@ var ADAPTER_CASES = [
|
|
|
65897
65986
|
}
|
|
65898
65987
|
}
|
|
65899
65988
|
];
|
|
65989
|
+
function routingSettings(value, onWrite = () => void 0) {
|
|
65990
|
+
return {
|
|
65991
|
+
describe: () => [{
|
|
65992
|
+
ns: "subagent-model-selection",
|
|
65993
|
+
value,
|
|
65994
|
+
revision: 3
|
|
65995
|
+
}],
|
|
65996
|
+
update: async (_ns, patch) => {
|
|
65997
|
+
onWrite(patch);
|
|
65998
|
+
}
|
|
65999
|
+
};
|
|
66000
|
+
}
|
|
66001
|
+
var NO_ROUTING_SETTINGS = {
|
|
66002
|
+
describe: () => [],
|
|
66003
|
+
update: async () => void 0
|
|
66004
|
+
};
|
|
65900
66005
|
var ROUTING_CASES = [
|
|
65901
66006
|
{
|
|
65902
66007
|
id: "routing.sync-needs-a-settings-namespace",
|
|
65903
66008
|
suite: "routing",
|
|
65904
|
-
claim: "A composition
|
|
66009
|
+
claim: "A composition that declares no Subagent model-selection entry syncs nothing and writes nothing.",
|
|
65905
66010
|
measure: async () => {
|
|
66011
|
+
let writes = 0;
|
|
65906
66012
|
const result = await synchronizeSubagentModelRoutes({
|
|
65907
|
-
|
|
65908
|
-
update: async () =>
|
|
66013
|
+
...NO_ROUTING_SETTINGS,
|
|
66014
|
+
update: async () => {
|
|
66015
|
+
writes += 1;
|
|
66016
|
+
}
|
|
65909
66017
|
}, {
|
|
65910
66018
|
listProviders: () => [{ id: "p" }],
|
|
65911
66019
|
listModels: async () => [{ id: "m" }]
|
|
65912
66020
|
});
|
|
65913
66021
|
return {
|
|
65914
|
-
observed: result.length === 0 ? 1 : 0,
|
|
66022
|
+
observed: result.length === 0 && writes === 0 ? 1 : 0,
|
|
65915
66023
|
required: 1,
|
|
65916
|
-
detail: `routes=${result.length}`
|
|
66024
|
+
detail: `routes=${result.length} writes=${writes}`
|
|
65917
66025
|
};
|
|
65918
66026
|
}
|
|
65919
66027
|
},
|
|
@@ -65923,15 +66031,12 @@ var ROUTING_CASES = [
|
|
|
65923
66031
|
claim: "Unavailable and non-text models are excluded, and duplicates are collapsed.",
|
|
65924
66032
|
measure: async () => {
|
|
65925
66033
|
const written = [];
|
|
65926
|
-
const ids = (await synchronizeSubagentModelRoutes({
|
|
65927
|
-
|
|
65928
|
-
|
|
65929
|
-
|
|
65930
|
-
|
|
65931
|
-
|
|
65932
|
-
written.push(value);
|
|
65933
|
-
}
|
|
65934
|
-
}, {
|
|
66034
|
+
const ids = (await synchronizeSubagentModelRoutes(routingSettings({
|
|
66035
|
+
allowedModels: [],
|
|
66036
|
+
enabled: void 0
|
|
66037
|
+
}, (patch) => {
|
|
66038
|
+
written.push(patch);
|
|
66039
|
+
}), {
|
|
65935
66040
|
listProviders: () => [{ id: "p" }],
|
|
65936
66041
|
listModels: async () => [
|
|
65937
66042
|
{
|
|
@@ -65972,27 +66077,23 @@ var ROUTING_CASES = [
|
|
|
65972
66077
|
suite: "routing",
|
|
65973
66078
|
claim: "A provider that answered with nothing loses its stale routes; one that failed keeps them.",
|
|
65974
66079
|
measure: async () => {
|
|
65975
|
-
const
|
|
65976
|
-
|
|
65977
|
-
|
|
65978
|
-
|
|
65979
|
-
|
|
65980
|
-
|
|
65981
|
-
|
|
65982
|
-
|
|
65983
|
-
|
|
65984
|
-
|
|
65985
|
-
|
|
65986
|
-
|
|
65987
|
-
|
|
65988
|
-
|
|
65989
|
-
|
|
65990
|
-
|
|
65991
|
-
|
|
65992
|
-
enabled: true
|
|
65993
|
-
}),
|
|
65994
|
-
update: async () => void 0
|
|
65995
|
-
}, {
|
|
66080
|
+
const ids = (await synchronizeSubagentModelRoutes(routingSettings({
|
|
66081
|
+
allowedModels: [
|
|
66082
|
+
{
|
|
66083
|
+
provider: "answered",
|
|
66084
|
+
model: "stale"
|
|
66085
|
+
},
|
|
66086
|
+
{
|
|
66087
|
+
provider: "failed",
|
|
66088
|
+
model: "keep"
|
|
66089
|
+
},
|
|
66090
|
+
{
|
|
66091
|
+
provider: "removed",
|
|
66092
|
+
model: "drop"
|
|
66093
|
+
}
|
|
66094
|
+
],
|
|
66095
|
+
enabled: true
|
|
66096
|
+
}), {
|
|
65996
66097
|
listProviders: () => [
|
|
65997
66098
|
{ id: "answered" },
|
|
65998
66099
|
{ id: "failed" },
|
|
@@ -66022,15 +66123,12 @@ var ROUTING_CASES = [
|
|
|
66022
66123
|
measure: async () => {
|
|
66023
66124
|
const writes = [];
|
|
66024
66125
|
const run2 = async (enabled) => {
|
|
66025
|
-
await synchronizeSubagentModelRoutes({
|
|
66026
|
-
|
|
66027
|
-
|
|
66028
|
-
|
|
66029
|
-
|
|
66030
|
-
|
|
66031
|
-
writes.push(value);
|
|
66032
|
-
}
|
|
66033
|
-
}, {
|
|
66126
|
+
await synchronizeSubagentModelRoutes(routingSettings({
|
|
66127
|
+
allowedModels: [],
|
|
66128
|
+
enabled
|
|
66129
|
+
}, (patch) => {
|
|
66130
|
+
writes.push(patch);
|
|
66131
|
+
}), {
|
|
66034
66132
|
listProviders: () => [{ id: "p" }],
|
|
66035
66133
|
listModels: async () => [{
|
|
66036
66134
|
id: "m",
|
|
@@ -66056,18 +66154,15 @@ var ROUTING_CASES = [
|
|
|
66056
66154
|
claim: "An unchanged catalog does not rewrite the settings document.",
|
|
66057
66155
|
measure: async () => {
|
|
66058
66156
|
let updates = 0;
|
|
66059
|
-
await synchronizeSubagentModelRoutes({
|
|
66060
|
-
|
|
66061
|
-
|
|
66062
|
-
|
|
66063
|
-
|
|
66064
|
-
|
|
66065
|
-
|
|
66066
|
-
|
|
66067
|
-
|
|
66068
|
-
updates += 1;
|
|
66069
|
-
}
|
|
66070
|
-
}, {
|
|
66157
|
+
await synchronizeSubagentModelRoutes(routingSettings({
|
|
66158
|
+
allowedModels: [{
|
|
66159
|
+
provider: "p",
|
|
66160
|
+
model: "m"
|
|
66161
|
+
}],
|
|
66162
|
+
enabled: true
|
|
66163
|
+
}, () => {
|
|
66164
|
+
updates += 1;
|
|
66165
|
+
}), {
|
|
66071
66166
|
listProviders: () => [{ id: "p" }],
|
|
66072
66167
|
listModels: async () => [{
|
|
66073
66168
|
id: "m",
|
|
@@ -67745,10 +67840,6 @@ function reportCommandPolicyDiagnostics(ctx, policy) {
|
|
|
67745
67840
|
commandPolicyDiagnosticsReported = true;
|
|
67746
67841
|
ctx.logger?.warn?.(`freecodego: the built-in command policy compiled with ${policy.diagnostics.length} diagnostic(s); rules that failed their own examples were dropped and are no longer enforced \u2014 ${describePolicyDiagnostics(policy.diagnostics)}`);
|
|
67747
67842
|
}
|
|
67748
|
-
function bootstrapFreeCodeGoHarness(ctx) {
|
|
67749
|
-
registerFreeCodeGoSessionEventTypes();
|
|
67750
|
-
return installFreeCodeGoPluginConflictGuard(ctx);
|
|
67751
|
-
}
|
|
67752
67843
|
function memoryPipelineHome(cwd) {
|
|
67753
67844
|
const identity = path.resolve(cwd).replaceAll("\\", "/").toLowerCase();
|
|
67754
67845
|
const segment = createHash3("sha256").update(identity).digest("hex").slice(0, 24);
|
|
@@ -67837,6 +67928,8 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
67837
67928
|
let _headroomStatus_decorators;
|
|
67838
67929
|
let _deferredToolsStatus_decorators;
|
|
67839
67930
|
let _deferredToolsSetEnabled_decorators;
|
|
67931
|
+
let _mediaGenerationStatus_decorators;
|
|
67932
|
+
let _mediaGenerationSetEnabled_decorators;
|
|
67840
67933
|
let _lspMountStatus_decorators;
|
|
67841
67934
|
let _sandboxModeStatus_decorators;
|
|
67842
67935
|
let _sandboxModeSet_decorators;
|
|
@@ -67873,6 +67966,8 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
67873
67966
|
let _engineeringCodeGraphCancel_decorators;
|
|
67874
67967
|
let _engineeringCodeGraphClearProject_decorators;
|
|
67875
67968
|
let _sessionDelete_decorators;
|
|
67969
|
+
let _webSearchBind_decorators;
|
|
67970
|
+
let _webSearchBindingStatus_decorators;
|
|
67876
67971
|
let _capabilitiesSnapshot_decorators;
|
|
67877
67972
|
let _capabilitiesSetEnabled_decorators;
|
|
67878
67973
|
let _modelCategorySet_decorators;
|
|
@@ -68059,6 +68154,8 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
68059
68154
|
_headroomStatus_decorators = [Remote("headroomStatus")];
|
|
68060
68155
|
_deferredToolsStatus_decorators = [Remote("deferredToolsStatus")];
|
|
68061
68156
|
_deferredToolsSetEnabled_decorators = [Remote("deferredToolsSetEnabled")];
|
|
68157
|
+
_mediaGenerationStatus_decorators = [Remote("mediaGenerationStatus")];
|
|
68158
|
+
_mediaGenerationSetEnabled_decorators = [Remote("mediaGenerationSetEnabled")];
|
|
68062
68159
|
_lspMountStatus_decorators = [Remote("lspMountStatus")];
|
|
68063
68160
|
_sandboxModeStatus_decorators = [Remote("sandboxModeStatus")];
|
|
68064
68161
|
_sandboxModeSet_decorators = [Remote("sandboxModeSet")];
|
|
@@ -68095,6 +68192,8 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
68095
68192
|
_engineeringCodeGraphCancel_decorators = [Remote("engineeringCodeGraphCancel")];
|
|
68096
68193
|
_engineeringCodeGraphClearProject_decorators = [Remote("engineeringCodeGraphClearProject")];
|
|
68097
68194
|
_sessionDelete_decorators = [Remote("sessionDelete")];
|
|
68195
|
+
_webSearchBind_decorators = [Remote("webSearchBind")];
|
|
68196
|
+
_webSearchBindingStatus_decorators = [Remote("webSearchBindingStatus")];
|
|
68098
68197
|
_capabilitiesSnapshot_decorators = [Remote("capabilities")];
|
|
68099
68198
|
_capabilitiesSetEnabled_decorators = [Remote("capabilitiesSetEnabled")];
|
|
68100
68199
|
_modelCategorySet_decorators = [Remote("modelCategorySet")];
|
|
@@ -68788,6 +68887,28 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
68788
68887
|
},
|
|
68789
68888
|
metadata: _metadata
|
|
68790
68889
|
}, null, _instanceExtraInitializers);
|
|
68890
|
+
__esDecorate(this, null, _mediaGenerationStatus_decorators, {
|
|
68891
|
+
kind: "method",
|
|
68892
|
+
name: "mediaGenerationStatus",
|
|
68893
|
+
static: false,
|
|
68894
|
+
private: false,
|
|
68895
|
+
access: {
|
|
68896
|
+
has: (obj) => "mediaGenerationStatus" in obj,
|
|
68897
|
+
get: (obj) => obj.mediaGenerationStatus
|
|
68898
|
+
},
|
|
68899
|
+
metadata: _metadata
|
|
68900
|
+
}, null, _instanceExtraInitializers);
|
|
68901
|
+
__esDecorate(this, null, _mediaGenerationSetEnabled_decorators, {
|
|
68902
|
+
kind: "method",
|
|
68903
|
+
name: "mediaGenerationSetEnabled",
|
|
68904
|
+
static: false,
|
|
68905
|
+
private: false,
|
|
68906
|
+
access: {
|
|
68907
|
+
has: (obj) => "mediaGenerationSetEnabled" in obj,
|
|
68908
|
+
get: (obj) => obj.mediaGenerationSetEnabled
|
|
68909
|
+
},
|
|
68910
|
+
metadata: _metadata
|
|
68911
|
+
}, null, _instanceExtraInitializers);
|
|
68791
68912
|
__esDecorate(this, null, _lspMountStatus_decorators, {
|
|
68792
68913
|
kind: "method",
|
|
68793
68914
|
name: "lspMountStatus",
|
|
@@ -69184,6 +69305,28 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
69184
69305
|
},
|
|
69185
69306
|
metadata: _metadata
|
|
69186
69307
|
}, null, _instanceExtraInitializers);
|
|
69308
|
+
__esDecorate(this, null, _webSearchBind_decorators, {
|
|
69309
|
+
kind: "method",
|
|
69310
|
+
name: "webSearchBind",
|
|
69311
|
+
static: false,
|
|
69312
|
+
private: false,
|
|
69313
|
+
access: {
|
|
69314
|
+
has: (obj) => "webSearchBind" in obj,
|
|
69315
|
+
get: (obj) => obj.webSearchBind
|
|
69316
|
+
},
|
|
69317
|
+
metadata: _metadata
|
|
69318
|
+
}, null, _instanceExtraInitializers);
|
|
69319
|
+
__esDecorate(this, null, _webSearchBindingStatus_decorators, {
|
|
69320
|
+
kind: "method",
|
|
69321
|
+
name: "webSearchBindingStatus",
|
|
69322
|
+
static: false,
|
|
69323
|
+
private: false,
|
|
69324
|
+
access: {
|
|
69325
|
+
has: (obj) => "webSearchBindingStatus" in obj,
|
|
69326
|
+
get: (obj) => obj.webSearchBindingStatus
|
|
69327
|
+
},
|
|
69328
|
+
metadata: _metadata
|
|
69329
|
+
}, null, _instanceExtraInitializers);
|
|
69187
69330
|
__esDecorate(this, null, _capabilitiesSnapshot_decorators, {
|
|
69188
69331
|
kind: "method",
|
|
69189
69332
|
name: "capabilitiesSnapshot",
|
|
@@ -70654,40 +70797,336 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
70654
70797
|
"sessionPersistence"
|
|
70655
70798
|
];
|
|
70656
70799
|
/**
|
|
70657
|
-
* Runtime schema for {@link Config}
|
|
70658
|
-
*
|
|
70659
|
-
*
|
|
70660
|
-
*
|
|
70661
|
-
*
|
|
70662
|
-
*
|
|
70800
|
+
* Runtime schema for {@link Config}.
|
|
70801
|
+
*
|
|
70802
|
+
* One flat `z.object({...})` literal, and that shape is load-bearing: the generated
|
|
70803
|
+
* config catalog walks this expression *statically* — it resolves a local `const` or
|
|
70804
|
+
* a workspace-package import and refuses anything else — and the readers gate in
|
|
70805
|
+
* `scripts/freecodego-config-readers.spec.ts` parses the same literal to check that
|
|
70806
|
+
* every field it declares is read somewhere. The document therefore cannot be
|
|
70807
|
+
* assembled from the group schemas' own modules, even though those modules own the
|
|
70808
|
+
* *types*: an `intersect` of relative imports is invisible to both walks, and a
|
|
70809
|
+
* schema nothing walks is a schema nothing checks.
|
|
70810
|
+
*
|
|
70811
|
+
* Which fields are which
|
|
70812
|
+
* ----------------------
|
|
70813
|
+
* The first block is deployment input: ordinary fields, no `volatile()`, and a change
|
|
70814
|
+
* to one of them is a composition change that remounts the plugin. Every field below
|
|
70815
|
+
* it is a setting — `volatile()` is what the loader reads as "commit this into the
|
|
70816
|
+
* running references instead of remounting", and it is also what puts the field in
|
|
70817
|
+
* the settings form. {@link FreeCodeGoPolicy} is the only reader of any of them; the
|
|
70818
|
+
* section comments name the module that owns each group's type.
|
|
70663
70819
|
*/
|
|
70664
70820
|
static Config = z2.object({
|
|
70665
70821
|
gateway: z2.object({ baseUrl: z2.string().default(FREECODEGO_CLOUD_ORIGIN) }),
|
|
70666
|
-
defaultModel: z2.string(),
|
|
70667
|
-
defaultEngine: z2.union([
|
|
70668
|
-
z2.const("deepseek"),
|
|
70669
|
-
z2.const("codex"),
|
|
70670
|
-
z2.const("claude")
|
|
70671
|
-
]).default("deepseek"),
|
|
70672
70822
|
codexRuntimeDirectory: z2.string().default(""),
|
|
70673
70823
|
codexRuntimeSourceDirectory: z2.string().default(""),
|
|
70674
70824
|
claudeRuntimeDirectory: z2.string().default(""),
|
|
70675
70825
|
autoSubagentModelSelection: z2.boolean().default(true),
|
|
70676
|
-
autoAdvisorEnabled: z2.boolean().default(true),
|
|
70677
70826
|
updatePackageName: z2.string().default(""),
|
|
70678
70827
|
updateReleaseRepository: z2.string().default(""),
|
|
70679
|
-
updateReleaseTokenEnv: z2.string().default("")
|
|
70828
|
+
updateReleaseTokenEnv: z2.string().default(""),
|
|
70829
|
+
mcpEnabled: z2.boolean().default(true).volatile(),
|
|
70830
|
+
skillEnabled: z2.boolean().default(true).volatile(),
|
|
70831
|
+
voiceInputEnabled: z2.boolean().default(true).volatile(),
|
|
70832
|
+
sessionDeleteEnabled: z2.boolean().default(true).volatile(),
|
|
70833
|
+
modelCategories: z2.dict(z2.union([
|
|
70834
|
+
z2.const("text"),
|
|
70835
|
+
z2.const("image"),
|
|
70836
|
+
z2.const("video"),
|
|
70837
|
+
z2.const("audio")
|
|
70838
|
+
])).default({}).volatile(),
|
|
70839
|
+
webSearchBindingProvider: z2.string().default("").volatile(),
|
|
70840
|
+
webSearchBindingModel: z2.string().default("").volatile(),
|
|
70841
|
+
mcpServers: z2.array(z2.object({
|
|
70842
|
+
id: z2.string().min(1).max(80),
|
|
70843
|
+
enabled: z2.boolean().default(true),
|
|
70844
|
+
transport: z2.union([z2.const("stdio"), z2.const("streamable-http")]),
|
|
70845
|
+
serverName: z2.string().pattern(SERVER_NAME$1),
|
|
70846
|
+
command: z2.string().default(""),
|
|
70847
|
+
args: z2.array(z2.string().max(4096)).default([]),
|
|
70848
|
+
env: z2.dict(z2.string()).default({}),
|
|
70849
|
+
cwd: z2.string().default(""),
|
|
70850
|
+
url: z2.string().default(""),
|
|
70851
|
+
headers: z2.dict(z2.string()).default({})
|
|
70852
|
+
})).default([]).volatile(),
|
|
70853
|
+
skillRoots: z2.array(z2.object({
|
|
70854
|
+
id: z2.string().min(1).max(80),
|
|
70855
|
+
enabled: z2.boolean().default(true),
|
|
70856
|
+
path: z2.string().min(1).max(4096)
|
|
70857
|
+
})).default([]).volatile(),
|
|
70858
|
+
skillInvocationOverrides: z2.dict(z2.boolean()).default({}).volatile(),
|
|
70859
|
+
preferredSkillPlacement: z2.union([z2.object({
|
|
70860
|
+
agent: z2.union([z2.const("harness"), z2.const("agents")]),
|
|
70861
|
+
scope: z2.union([z2.const("project"), z2.const("user")])
|
|
70862
|
+
}), z2.const(null)]).volatile(),
|
|
70863
|
+
envReadGuardEnabled: z2.boolean().default(true).volatile(),
|
|
70864
|
+
doomLoopGuardEnabled: z2.boolean().default(true).volatile(),
|
|
70865
|
+
lspEnabled: z2.boolean().default(true).volatile(),
|
|
70866
|
+
commandPolicyEnabled: z2.boolean().default(true).volatile(),
|
|
70867
|
+
planModeEnabled: z2.boolean().default(true).volatile(),
|
|
70868
|
+
contextBudgetEnabled: z2.boolean().default(true).volatile(),
|
|
70869
|
+
cacheColdClearEnabled: z2.boolean().default(true).volatile(),
|
|
70870
|
+
cacheBreakAttributionEnabled: z2.boolean().default(true).volatile(),
|
|
70871
|
+
assistantLoopGuardEnabled: z2.boolean().default(true).volatile(),
|
|
70872
|
+
spillRecallEnabled: z2.boolean().default(true).volatile(),
|
|
70873
|
+
compactionFidelityEnabled: z2.boolean().default(true).volatile(),
|
|
70874
|
+
promptCompositionEnabled: z2.boolean().default(true).volatile(),
|
|
70875
|
+
/**
|
|
70876
|
+
* Master switch for the whole gate.
|
|
70877
|
+
*
|
|
70878
|
+
* Off means every project-scoped surface is treated as trusted — the
|
|
70879
|
+
* pre-gate behaviour, kept reachable so a deployment that already controls
|
|
70880
|
+
* which repositories it opens is not forced to grant each one. It is
|
|
70881
|
+
* deliberately not the default: the safe state must not be the opt-in one.
|
|
70882
|
+
*/
|
|
70883
|
+
folderTrustEnabled: z2.boolean().default(true).volatile(),
|
|
70884
|
+
pluginConflictProtectionEnabled: z2.boolean().default(true).volatile(),
|
|
70885
|
+
pluginConflictRecords: z2.array(z2.object({
|
|
70886
|
+
id: z2.string().min(1).max(256),
|
|
70887
|
+
detectedAt: z2.number(),
|
|
70888
|
+
resource: z2.union([
|
|
70889
|
+
z2.const("tool"),
|
|
70890
|
+
z2.const("command"),
|
|
70891
|
+
z2.const("settings"),
|
|
70892
|
+
z2.const("route"),
|
|
70893
|
+
z2.const("provider"),
|
|
70894
|
+
z2.const("slot")
|
|
70895
|
+
]),
|
|
70896
|
+
resourceName: z2.string().min(1).max(256),
|
|
70897
|
+
disabledEntryId: z2.string().min(1).max(512),
|
|
70898
|
+
disabledModuleName: z2.string().min(1).max(512),
|
|
70899
|
+
keptEntryId: z2.string().min(1).max(512),
|
|
70900
|
+
keptModuleName: z2.string().min(1).max(512),
|
|
70901
|
+
yieldedToOfficial: z2.boolean()
|
|
70902
|
+
})).default([]).volatile(),
|
|
70903
|
+
pluginUpdateChecksEnabled: z2.boolean().default(true).volatile(),
|
|
70904
|
+
engineeringEnabled: z2.boolean().default(true).volatile(),
|
|
70905
|
+
/**
|
|
70906
|
+
* The rest of the bundled engineering library is opt-in: 23 audited Skills
|
|
70907
|
+
* (the remainder of the authored set plus the vendored `mattpocock/skills`
|
|
70908
|
+
* entries that are not in the default-on starter root) stay unmounted until
|
|
70909
|
+
* the user turns this on.
|
|
70910
|
+
*/
|
|
70911
|
+
engineeringSkillsEnabled: z2.boolean().default(false).volatile(),
|
|
70912
|
+
/**
|
|
70913
|
+
* The starter set is on by default: ten Skills whose value does not depend on
|
|
70914
|
+
* adopting a whole methodology. Four are disciplines the model applies on its
|
|
70915
|
+
* own (evidence before completion claims, navigation before broad reading,
|
|
70916
|
+
* planning multi-file work, root-cause debugging); the rest are `/name`
|
|
70917
|
+
* entries a user reaches for on demand and that cost nothing until typed
|
|
70918
|
+
* (a prompt-technique reference, the grilling interview and its primitive, a
|
|
70919
|
+
* re-pitch escape hatch, a handoff document, and a questionnaire for
|
|
70920
|
+
* decisions the agent cannot settle). They live in their own asset root so
|
|
70921
|
+
* "all engineering Skills" stays the union of the roots — no skill file is
|
|
70922
|
+
* duplicated, and no audit can disagree with a mount.
|
|
70923
|
+
*/
|
|
70924
|
+
engineeringStarterSkillsEnabled: z2.boolean().default(true).volatile(),
|
|
70925
|
+
/**
|
|
70926
|
+
* The vendored superpowers workflow pack is a separate opt-in: it is the
|
|
70927
|
+
* auto-triggering, plan-then-dispatch methodology, so it must be a deliberate
|
|
70928
|
+
* choice rather than a side effect of enabling the engineering disciplines.
|
|
70929
|
+
*/
|
|
70930
|
+
engineeringSuperpowersSkillsEnabled: z2.boolean().default(false).volatile(),
|
|
70931
|
+
/**
|
|
70932
|
+
* Injects a bounded capability map of the mounted Skills at session start.
|
|
70933
|
+
* A default-off Skill library is invisible otherwise: the model never lists
|
|
70934
|
+
* it, and a user who turned a pack on has no way to see what arrived.
|
|
70935
|
+
*/
|
|
70936
|
+
engineeringSkillMapEnabled: z2.boolean().default(true).volatile(),
|
|
70937
|
+
/** Enables bounded project-declared verification after an approved council plan. */
|
|
70938
|
+
engineeringQualityEnabled: z2.boolean().default(true).volatile(),
|
|
70939
|
+
engineeringMemoryEnabled: z2.boolean().default(true).volatile(),
|
|
70940
|
+
engineeringCouncilEnabled: z2.boolean().default(true).volatile(),
|
|
70941
|
+
engineeringCouncilDeepseekEnabled: z2.boolean().default(true).volatile(),
|
|
70942
|
+
engineeringCouncilCodexEnabled: z2.boolean().default(true).volatile(),
|
|
70943
|
+
engineeringCouncilClaudeEnabled: z2.boolean().default(true).volatile(),
|
|
70944
|
+
engineeringMemoryContextTokenBudget: z2.number().step(1).min(0).max(4e3).default(1200).volatile(),
|
|
70945
|
+
/**
|
|
70946
|
+
* Default off, deliberately: the lexical rerank is free, deterministic, and
|
|
70947
|
+
* already ranks by term coverage. Flipping this on spends one small model
|
|
70948
|
+
* request per memory search to catch the memories that share no wording with
|
|
70949
|
+
* the query — worth it for a user who searches by concept, wasted for one who
|
|
70950
|
+
* greps for identifiers.
|
|
70951
|
+
*/
|
|
70952
|
+
engineeringMemorySelectorEnabled: z2.boolean().default(false).volatile(),
|
|
70953
|
+
/**
|
|
70954
|
+
* Default off, deliberately: this lets a model approve a pending action without
|
|
70955
|
+
* asking the user. Off means every approval keeps prompting. On means an action
|
|
70956
|
+
* whose arguments the reviewer can actually read may be cleared automatically —
|
|
70957
|
+
* anything it refuses, cannot read, or declines to judge still goes to the user.
|
|
70958
|
+
*/
|
|
70959
|
+
engineeringActionReviewEnabled: z2.boolean().default(false).volatile(),
|
|
70960
|
+
engineeringCodeGraphEnabled: z2.boolean().default(true).volatile(),
|
|
70961
|
+
engineeringCodeGraphAutoUpdate: z2.boolean().default(true).volatile(),
|
|
70962
|
+
engineeringGraphEngine: z2.union([
|
|
70963
|
+
z2.const("auto"),
|
|
70964
|
+
z2.const("graphify"),
|
|
70965
|
+
z2.const("codegraph")
|
|
70966
|
+
]).default("auto").volatile(),
|
|
70967
|
+
engineeringCouncilMaxRounds: z2.number().step(1).min(1).max(3).default(2).volatile(),
|
|
70968
|
+
engineeringCouncilTimeoutMs: z2.number().step(1).min(1e4).max(3e5).default(12e4).volatile(),
|
|
70969
|
+
engineeringCouncilQuorum: z2.number().step(1).min(1).max(3).default(2).volatile(),
|
|
70970
|
+
engineeringCouncilAutoRun: z2.boolean().default(false).volatile(),
|
|
70971
|
+
/**
|
|
70972
|
+
* The three phases of the autonomous engineering loop. Each is a separate
|
|
70973
|
+
* switch because they carry different risk: creating a goal only commits the
|
|
70974
|
+
* user to finishing, while enabling the driver lets work continue with no
|
|
70975
|
+
* human turn in between.
|
|
70976
|
+
*
|
|
70977
|
+
* - `engineeringLoopCapturePlan` — when the user approves a council decision,
|
|
70978
|
+
* persist the approved plan as a durable Harness goal.
|
|
70979
|
+
* - `engineeringLoopVerifyOnComplete` — when the active goal's driver reports
|
|
70980
|
+
* it finished, run the declared verification stages and record the result.
|
|
70981
|
+
* - `engineeringLoopAutoContinue` — let the Harness goal-round driver start
|
|
70982
|
+
* the next round without a user turn. Off by default: a goal that continues
|
|
70983
|
+
* unattended is the one behaviour a user must opt into explicitly.
|
|
70984
|
+
*/
|
|
70985
|
+
engineeringLoopCapturePlan: z2.boolean().default(true).volatile(),
|
|
70986
|
+
engineeringLoopVerifyOnComplete: z2.boolean().default(true).volatile(),
|
|
70987
|
+
engineeringLoopAutoContinue: z2.boolean().default(false).volatile(),
|
|
70988
|
+
/** Round cap for a captured plan goal; bounds unattended continuation. */
|
|
70989
|
+
engineeringLoopMaxGoalRounds: z2.number().step(1).min(1).max(256).default(24).volatile(),
|
|
70990
|
+
engineeringCouncilMaxTokens: z2.number().step(100).min(1200).max(2e4).default(3600).volatile(),
|
|
70991
|
+
engineeringCouncilMaxConcurrent: z2.number().step(1).min(1).max(8).default(2).volatile(),
|
|
70992
|
+
engineeringCouncilDecisionTtlMs: z2.number().step(6e4).min(6e4).max(10080 * 6e4).default(30 * 6e4).volatile(),
|
|
70993
|
+
/** Master switch for declarative failure recovery. */
|
|
70994
|
+
hookChainsEnabled: z2.boolean().default(true).volatile(),
|
|
70995
|
+
hookChainsMaxDepth: z2.number().step(1).min(0).max(10).default(2).volatile(),
|
|
70996
|
+
hookChainsCooldownMs: z2.number().step(1e3).min(0).max(1440 * 60 * 1e3).default(3e4).volatile(),
|
|
70997
|
+
/** Master switch for the calendar planner. */
|
|
70998
|
+
scheduledTasksEnabled: z2.boolean().default(true).volatile(),
|
|
70999
|
+
defaultModel: z2.string().default("").volatile(),
|
|
71000
|
+
defaultEngine: z2.union([
|
|
71001
|
+
z2.const("deepseek"),
|
|
71002
|
+
z2.const("codex"),
|
|
71003
|
+
z2.const("claude")
|
|
71004
|
+
]).default("deepseek").volatile(),
|
|
71005
|
+
mediaDefaults: z2.object({
|
|
71006
|
+
image: z2.string().default(""),
|
|
71007
|
+
video: z2.string().default(""),
|
|
71008
|
+
audio: z2.string().default("")
|
|
71009
|
+
}).default({
|
|
71010
|
+
image: "",
|
|
71011
|
+
video: "",
|
|
71012
|
+
audio: ""
|
|
71013
|
+
}).volatile(),
|
|
71014
|
+
/**
|
|
71015
|
+
* Master switch for the image and video generation tools.
|
|
71016
|
+
*
|
|
71017
|
+
* On by default: the tools spend nothing until a route is called, and they are the
|
|
71018
|
+
* only way the capability is reachable — a feature that has to be found before it
|
|
71019
|
+
* does anything is why the media surface looked absent. It governs the generic
|
|
71020
|
+
* `freecodego_generate_image` / `_video` pair and the legacy `agnes_*` aliases with
|
|
71021
|
+
* them; `freecodego_generate_audio` and `freecodego_transcribe_audio` are
|
|
71022
|
+
* deliberately outside it, because one writes into the active workspace and the
|
|
71023
|
+
* other reads out of it.
|
|
71024
|
+
*/
|
|
71025
|
+
mediaGenerationEnabled: z2.boolean().default(true).volatile(),
|
|
71026
|
+
/**
|
|
71027
|
+
* Sandbox profile deny globs, enforced in the plugin policy layer.
|
|
71028
|
+
*
|
|
71029
|
+
* Empty by default: a deny list is containment the user asked for, and
|
|
71030
|
+
* inventing one would refuse paths nobody named.
|
|
71031
|
+
*/
|
|
71032
|
+
sandboxDenyPatterns: z2.array(z2.string()).default([]).volatile(),
|
|
71033
|
+
rehydrationEnabled: z2.boolean().default(true).volatile(),
|
|
71034
|
+
/**
|
|
71035
|
+
* Conversation-arc rehydration (goals + decisions folded from the
|
|
71036
|
+
* session's own goal events, promoted memories, and announced
|
|
71037
|
+
* choices). Off by default: it changes what the post-compaction
|
|
71038
|
+
* message contains, and a user must opt into new prompt surface —
|
|
71039
|
+
* the mechanical fold is bounded, but its wording is still model-
|
|
71040
|
+
* visible behavior.
|
|
71041
|
+
*/
|
|
71042
|
+
rehydrationArcEnabled: z2.boolean().default(false).volatile(),
|
|
71043
|
+
advisorEnabled: z2.boolean().default(true).volatile(),
|
|
71044
|
+
advisorMode: z2.union([
|
|
71045
|
+
z2.const("async"),
|
|
71046
|
+
z2.const("catchup"),
|
|
71047
|
+
z2.const("blocker-only")
|
|
71048
|
+
]).default("async").volatile(),
|
|
71049
|
+
advisorProvider: z2.string().default("opencode").volatile(),
|
|
71050
|
+
advisorModel: z2.string().default("auto").volatile(),
|
|
71051
|
+
advisorAllowAgentControl: z2.boolean().default(true).volatile(),
|
|
71052
|
+
advisorInterruptCooldownTurns: z2.number().step(1).min(0).max(20).default(3).volatile(),
|
|
71053
|
+
advisorMemoryDraftsEnabled: z2.boolean().default(true).volatile(),
|
|
71054
|
+
reviewMode: z2.union([
|
|
71055
|
+
z2.const("off"),
|
|
71056
|
+
z2.const("record"),
|
|
71057
|
+
z2.const("gate")
|
|
71058
|
+
]).default("off").volatile(),
|
|
71059
|
+
reviewThreshold: z2.union([
|
|
71060
|
+
z2.const("critical"),
|
|
71061
|
+
z2.const("high"),
|
|
71062
|
+
z2.const("medium"),
|
|
71063
|
+
z2.const("low")
|
|
71064
|
+
]).default("high").volatile(),
|
|
71065
|
+
reviewCooldownTurns: z2.number().step(1).min(0).max(20).default(3).volatile(),
|
|
71066
|
+
reviewDeep: z2.boolean().default(false).volatile(),
|
|
71067
|
+
reviewEscalation: z2.boolean().default(false).volatile(),
|
|
71068
|
+
headroomEnabled: z2.boolean().default(true).volatile(),
|
|
71069
|
+
headroomThresholdChars: z2.number().step(1).min(256).max(1e6).default(1200).volatile(),
|
|
71070
|
+
headroomMinSavingsRatio: z2.number().min(0.05).max(0.95).default(0.85).volatile(),
|
|
71071
|
+
headroomDedupEnabled: z2.boolean().default(true).volatile(),
|
|
71072
|
+
/**
|
|
71073
|
+
* Tools to protect *in addition* to the built-in list.
|
|
71074
|
+
*
|
|
71075
|
+
* Additional, not instead of: the built-in set
|
|
71076
|
+
* (`DEFAULT_EXCLUDE_TOOLS`) is a safety guarantee — those outputs are
|
|
71077
|
+
* what the model byte-patches against — and this field defaults to an
|
|
71078
|
+
* empty array, so a reading where it replaced the built-ins would make
|
|
71079
|
+
* the default install protect nothing.
|
|
71080
|
+
*/
|
|
71081
|
+
headroomExcludeTools: z2.array(z2.string()).default([]).volatile(),
|
|
71082
|
+
headroomFoldReads: z2.boolean().default(false).volatile(),
|
|
71083
|
+
/**
|
|
71084
|
+
* Skeletonize large source-file reads: retained lines stay byte-exact
|
|
71085
|
+
* while whole body runs collapse to a marker. On by default because
|
|
71086
|
+
* `read` is the largest single source of re-sent context; the original
|
|
71087
|
+
* is always retrievable through `headroom_retrieve`.
|
|
71088
|
+
*/
|
|
71089
|
+
headroomCodeSkeletonEnabled: z2.boolean().default(true).volatile(),
|
|
71090
|
+
/**
|
|
71091
|
+
* Reversible-render competition policy. `reversible` (default) delivers a
|
|
71092
|
+
* render that clears `FOLD_DECISIVE_RATIO` on sight — a Stage 2 fold, or a
|
|
71093
|
+
* mixed-content splice; `max` demotes every one of them to a candidate so
|
|
71094
|
+
* the compressor written for the payload's shape is always asked first.
|
|
71095
|
+
* The two settings are two products, not a fine-tuning — see
|
|
71096
|
+
* `HeadroomRuntime.foldPolicy` for the measured difference on the shapes
|
|
71097
|
+
* where they disagree.
|
|
71098
|
+
*/
|
|
71099
|
+
headroomFoldPolicy: z2.union([z2.const("reversible"), z2.const("max")]).default("reversible").volatile(),
|
|
71100
|
+
/**
|
|
71101
|
+
* Keep task-specific tool schemas out of the request until the model
|
|
71102
|
+
* asks for them with `tool_search`. Measured saving is ~3.2k tokens per
|
|
71103
|
+
* request on this plugin's own 37 tools alone.
|
|
71104
|
+
*/
|
|
71105
|
+
deferredToolSchemasEnabled: z2.boolean().default(true).volatile(),
|
|
71106
|
+
/** Explicit deferral list; when empty the plugin-owned prefix rule applies. */
|
|
71107
|
+
deferredToolNames: z2.array(z2.string()).default([]).volatile(),
|
|
71108
|
+
headroomOutputShaper: z2.boolean().default(false).volatile(),
|
|
71109
|
+
headroomVerbosityLevel: z2.number().step(1).min(0).max(4).default(0).volatile(),
|
|
71110
|
+
/**
|
|
71111
|
+
* Memory consolidation rollout (`memory/rollout.ts`).
|
|
71112
|
+
*
|
|
71113
|
+
* A stage rather than a switch because consolidating runs a model over
|
|
71114
|
+
* the session's successful turns: `record_only` captures without
|
|
71115
|
+
* consolidating, `shadow` consolidates without committing, and only
|
|
71116
|
+
* `active` writes. Off by default, and off is where an unrecognised
|
|
71117
|
+
* value lands too — see `resolveMemoryRollout`, which fails closed
|
|
71118
|
+
* rather than falling back to the legacy search path.
|
|
71119
|
+
*/
|
|
71120
|
+
memoryRollout: z2.union([
|
|
71121
|
+
z2.const("off"),
|
|
71122
|
+
z2.const("record_only"),
|
|
71123
|
+
z2.const("shadow"),
|
|
71124
|
+
z2.const("active")
|
|
71125
|
+
]).default("off").volatile()
|
|
70680
71126
|
});
|
|
70681
71127
|
account;
|
|
70682
71128
|
api;
|
|
70683
71129
|
credentials;
|
|
70684
|
-
/**
|
|
70685
|
-
* The registered settings namespace. Nothing outside this class reads it.
|
|
70686
|
-
*
|
|
70687
|
-
* Every behaviour read goes through {@link policy}, so exactly one place
|
|
70688
|
-
* answers "what is configured".
|
|
70689
|
-
*/
|
|
70690
|
-
engineSettings;
|
|
70691
71130
|
/** The one accessor behaviour reads go through (see `policy.ts`). */
|
|
70692
71131
|
policy;
|
|
70693
71132
|
capabilities;
|
|
@@ -70935,7 +71374,11 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
70935
71374
|
this.config = config;
|
|
70936
71375
|
reportCommandPolicyDiagnostics(ctx, this.commandPolicy);
|
|
70937
71376
|
ensureDesktopDshShim();
|
|
70938
|
-
|
|
71377
|
+
ctx.effect(() => {
|
|
71378
|
+
const presets = installFreeCodeGoAgentPresets(ctx);
|
|
71379
|
+
this.pendingWrites.run(() => presets.done);
|
|
71380
|
+
return presets.release;
|
|
71381
|
+
}, "freecodego: agent presets");
|
|
70939
71382
|
ctx.effect(() => {
|
|
70940
71383
|
const known = KNOWN_SESSION_EVENT_TYPES;
|
|
70941
71384
|
const added = freeCodeGoSessionEventTypes.filter((type) => !known.has(type));
|
|
@@ -70992,138 +71435,15 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
70992
71435
|
const claudeStatus = this.claudeRuntime.status();
|
|
70993
71436
|
setEngineAvailability(this.agentEngines, "claude", claudeStatus.installed ? "available" : "unavailable");
|
|
70994
71437
|
const settings = ctx.get("settings");
|
|
70995
|
-
|
|
70996
|
-
|
|
70997
|
-
|
|
70998
|
-
|
|
70999
|
-
|
|
71000
|
-
|
|
71001
|
-
|
|
71002
|
-
|
|
71003
|
-
|
|
71004
|
-
image: "",
|
|
71005
|
-
video: "",
|
|
71006
|
-
audio: ""
|
|
71007
|
-
})
|
|
71008
|
-
}),
|
|
71009
|
-
FreeCodeGoCapabilitySettingsSchema,
|
|
71010
|
-
FreeCodeGoPluginConflictSettingsSchema,
|
|
71011
|
-
FreeCodeGoPluginUpdateSettingsSchema,
|
|
71012
|
-
FreeCodeGoEngineeringSettingsSchema,
|
|
71013
|
-
FreeCodeGoAutomationSettingsSchema,
|
|
71014
|
-
FreeCodeGoGuardSettingsSchema,
|
|
71015
|
-
FreeCodeGoTrustSettingsSchema,
|
|
71016
|
-
z2.object({
|
|
71017
|
-
/**
|
|
71018
|
-
* Sandbox profile deny globs, enforced in the plugin policy layer.
|
|
71019
|
-
*
|
|
71020
|
-
* Empty by default: a deny list is containment the user asked for, and
|
|
71021
|
-
* inventing one would refuse paths nobody named.
|
|
71022
|
-
*/
|
|
71023
|
-
sandboxDenyPatterns: z2.array(z2.string()).default([])
|
|
71024
|
-
}),
|
|
71025
|
-
z2.object({
|
|
71026
|
-
rehydrationEnabled: z2.boolean().default(true),
|
|
71027
|
-
/**
|
|
71028
|
-
* Conversation-arc rehydration (goals + decisions folded from the
|
|
71029
|
-
* session's own goal events, promoted memories, and announced
|
|
71030
|
-
* choices). Off by default: it changes what the post-compaction
|
|
71031
|
-
* message contains, and a user must opt into new prompt surface —
|
|
71032
|
-
* the mechanical fold is bounded, but its wording is still model-
|
|
71033
|
-
* visible behavior.
|
|
71034
|
-
*/
|
|
71035
|
-
rehydrationArcEnabled: z2.boolean().default(false)
|
|
71036
|
-
}),
|
|
71037
|
-
z2.object({
|
|
71038
|
-
advisorEnabled: z2.boolean().default(config.autoAdvisorEnabled !== false),
|
|
71039
|
-
advisorMode: z2.union([
|
|
71040
|
-
z2.const("async"),
|
|
71041
|
-
z2.const("catchup"),
|
|
71042
|
-
z2.const("blocker-only")
|
|
71043
|
-
]).default("async"),
|
|
71044
|
-
advisorProvider: z2.string().default("opencode"),
|
|
71045
|
-
advisorModel: z2.string().default("auto"),
|
|
71046
|
-
advisorAllowAgentControl: z2.boolean().default(true),
|
|
71047
|
-
advisorInterruptCooldownTurns: z2.number().step(1).min(0).max(20).default(3),
|
|
71048
|
-
advisorMemoryDraftsEnabled: z2.boolean().default(true),
|
|
71049
|
-
reviewMode: z2.union([
|
|
71050
|
-
z2.const("off"),
|
|
71051
|
-
z2.const("record"),
|
|
71052
|
-
z2.const("gate")
|
|
71053
|
-
]).default("off"),
|
|
71054
|
-
reviewThreshold: z2.union([
|
|
71055
|
-
z2.const("critical"),
|
|
71056
|
-
z2.const("high"),
|
|
71057
|
-
z2.const("medium"),
|
|
71058
|
-
z2.const("low")
|
|
71059
|
-
]).default("high"),
|
|
71060
|
-
reviewCooldownTurns: z2.number().step(1).min(0).max(20).default(3),
|
|
71061
|
-
reviewDeep: z2.boolean().default(false),
|
|
71062
|
-
reviewEscalation: z2.boolean().default(false),
|
|
71063
|
-
headroomEnabled: z2.boolean().default(true),
|
|
71064
|
-
headroomThresholdChars: z2.number().step(1).min(256).max(1e6).default(1200),
|
|
71065
|
-
headroomMinSavingsRatio: z2.number().min(0.05).max(0.95).default(0.85),
|
|
71066
|
-
headroomDedupEnabled: z2.boolean().default(true),
|
|
71067
|
-
/**
|
|
71068
|
-
* Tools to protect *in addition* to the built-in list.
|
|
71069
|
-
*
|
|
71070
|
-
* Additional, not instead of: the built-in set
|
|
71071
|
-
* (`DEFAULT_EXCLUDE_TOOLS`) is a safety guarantee — those outputs are
|
|
71072
|
-
* what the model byte-patches against — and this field defaults to an
|
|
71073
|
-
* empty array, so a reading where it replaced the built-ins would make
|
|
71074
|
-
* the default install protect nothing.
|
|
71075
|
-
*/
|
|
71076
|
-
headroomExcludeTools: z2.array(z2.string()).default([]),
|
|
71077
|
-
headroomFoldReads: z2.boolean().default(false),
|
|
71078
|
-
/**
|
|
71079
|
-
* Skeletonize large source-file reads: retained lines stay byte-exact
|
|
71080
|
-
* while whole body runs collapse to a marker. On by default because
|
|
71081
|
-
* `read` is the largest single source of re-sent context; the original
|
|
71082
|
-
* is always retrievable through `headroom_retrieve`.
|
|
71083
|
-
*/
|
|
71084
|
-
headroomCodeSkeletonEnabled: z2.boolean().default(true),
|
|
71085
|
-
/**
|
|
71086
|
-
* Reversible-render competition policy. `reversible` (default) delivers a
|
|
71087
|
-
* render that clears `FOLD_DECISIVE_RATIO` on sight — a Stage 2 fold, or a
|
|
71088
|
-
* mixed-content splice; `max` demotes every one of them to a candidate so
|
|
71089
|
-
* the compressor written for the payload's shape is always asked first.
|
|
71090
|
-
* The two settings are two products, not a fine-tuning — see
|
|
71091
|
-
* `HeadroomRuntime.foldPolicy` for the measured difference on the shapes
|
|
71092
|
-
* where they disagree.
|
|
71093
|
-
*/
|
|
71094
|
-
headroomFoldPolicy: z2.union([z2.const("reversible"), z2.const("max")]).default("reversible"),
|
|
71095
|
-
/**
|
|
71096
|
-
* Keep task-specific tool schemas out of the request until the model
|
|
71097
|
-
* asks for them with `tool_search`. Measured saving is ~3.2k tokens per
|
|
71098
|
-
* request on this plugin's own 37 tools alone.
|
|
71099
|
-
*/
|
|
71100
|
-
deferredToolSchemasEnabled: z2.boolean().default(true),
|
|
71101
|
-
/** Explicit deferral list; when empty the plugin-owned prefix rule applies. */
|
|
71102
|
-
deferredToolNames: z2.array(z2.string()).default([]),
|
|
71103
|
-
headroomOutputShaper: z2.boolean().default(false),
|
|
71104
|
-
headroomVerbosityLevel: z2.number().step(1).min(0).max(4).default(0)
|
|
71105
|
-
}),
|
|
71106
|
-
z2.object({
|
|
71107
|
-
/**
|
|
71108
|
-
* Memory consolidation rollout (`memory/rollout.ts`).
|
|
71109
|
-
*
|
|
71110
|
-
* A stage rather than a switch because consolidating runs a model over
|
|
71111
|
-
* the session's successful turns: `record_only` captures without
|
|
71112
|
-
* consolidating, `shadow` consolidates without committing, and only
|
|
71113
|
-
* `active` writes. Off by default, and off is where an unrecognised
|
|
71114
|
-
* value lands too — see `resolveMemoryRollout`, which fails closed
|
|
71115
|
-
* rather than falling back to the legacy search path.
|
|
71116
|
-
*/
|
|
71117
|
-
memoryRollout: z2.union([
|
|
71118
|
-
z2.const("off"),
|
|
71119
|
-
z2.const("record_only"),
|
|
71120
|
-
z2.const("shadow"),
|
|
71121
|
-
z2.const("active")
|
|
71122
|
-
]).default("off")
|
|
71123
|
-
})
|
|
71124
|
-
]), { applies: "live" });
|
|
71125
|
-
else this.engineSettings = void 0;
|
|
71126
|
-
this.policy = new FreeCodeGoPolicy(this.engineSettings);
|
|
71438
|
+
const settingsWriter = settings === void 0 ? void 0 : { update: async (patch) => {
|
|
71439
|
+
const entry = this.ctx.fiber.entry;
|
|
71440
|
+
if (entry === void 0) return;
|
|
71441
|
+
await settings.update(entry.options.id, patch);
|
|
71442
|
+
} };
|
|
71443
|
+
this.ctx.inject(["settings"], (child) => {
|
|
71444
|
+
child.effect(() => child.settings.configure({ auto: false }, this.ctx.fiber));
|
|
71445
|
+
});
|
|
71446
|
+
this.policy = new FreeCodeGoPolicy(this.config, settingsWriter);
|
|
71127
71447
|
this.capabilities = new FreeCodeGoCapabilityRegistry(ctx, this.policy, (directory) => this.projectScopeTrust(directory), async () => {
|
|
71128
71448
|
const tier = await this.projectTierFor(process.cwd()).catch(() => void 0);
|
|
71129
71449
|
return {
|
|
@@ -71435,10 +71755,7 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
71435
71755
|
const failed = result.stages.filter((stage) => stage.state === "fail" || stage.state === "unavailable");
|
|
71436
71756
|
if (failed.length === 0) return;
|
|
71437
71757
|
agent.inject(createUserMessage({
|
|
71438
|
-
source: {
|
|
71439
|
-
kind: "plugin",
|
|
71440
|
-
plugin: "freecodego-engineering-loop"
|
|
71441
|
-
},
|
|
71758
|
+
source: { kind: "freecodego-engineering-loop" },
|
|
71442
71759
|
content: [{
|
|
71443
71760
|
type: "text",
|
|
71444
71761
|
text: `Engineering goal "${goalId}" ended in phase "${phase}", but verification did not pass: ${failed.map((stage) => `${stage.id}=${stage.state}`).join(", ")}. Resolve these before treating the plan as done.`
|
|
@@ -71450,10 +71767,7 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
71450
71767
|
if (loop.phase === "blocked") {
|
|
71451
71768
|
const budget = loop.roundsStarted === void 0 || loop.maxGoalRounds === void 0 ? "" : ` after ${loop.roundsStarted}/${loop.maxGoalRounds} goal rounds`;
|
|
71452
71769
|
agent.inject(createUserMessage({
|
|
71453
|
-
source: {
|
|
71454
|
-
kind: "plugin",
|
|
71455
|
-
plugin: "freecodego-engineering-loop"
|
|
71456
|
-
},
|
|
71770
|
+
source: { kind: "freecodego-engineering-loop" },
|
|
71457
71771
|
content: [{
|
|
71458
71772
|
type: "text",
|
|
71459
71773
|
text: `Engineering goal "${goalId}" stopped unattended${budget}: ${loop.blockedMessage ?? loop.blockedCode ?? "the round driver blocked it"}. Nothing continues until that is resolved; use \u5DE5\u7A0B\u589E\u5F3A \u2192 \u65E0\u4EBA\u503C\u5B88\u5DE5\u7A0B\u56DE\u8DEF \u2192 \u7EE7\u7EED to resume it.`
|
|
@@ -71565,9 +71879,13 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
71565
71879
|
this.catalogs.registerNvidiaAdapter();
|
|
71566
71880
|
this.catalogs.registerKiloAdapter();
|
|
71567
71881
|
this.catalogs.prewarmProviderCatalogs();
|
|
71882
|
+
this.repairWebSearchBinding();
|
|
71568
71883
|
this.catalogs.refreshLogfareHealthInBackground();
|
|
71569
|
-
this.
|
|
71570
|
-
this.
|
|
71884
|
+
this.syncMediaGenerationTools();
|
|
71885
|
+
ctx.effect(() => this.registerAudioTools(), "freecodego: media audio tools");
|
|
71886
|
+
ctx.effect(() => () => {
|
|
71887
|
+
this.disposeMediaGenerationTools();
|
|
71888
|
+
}, "freecodego: media generation tools");
|
|
71571
71889
|
ctx.effect(() => async () => {
|
|
71572
71890
|
await Promise.all([this.pendingWrites.drain(), this.catalogs.pendingWrites.drain()]);
|
|
71573
71891
|
}, "freecodego: background preset and catalog writes");
|
|
@@ -71612,10 +71930,7 @@ var FreeCodeGoHarnessPlugin = (() => {
|
|
|
71612
71930
|
const agent = agents.get(agentId);
|
|
71613
71931
|
if (typeof agent?.inject !== "function") return;
|
|
71614
71932
|
agent.inject(createUserMessage({
|
|
71615
|
-
source: {
|
|
71616
|
-
kind: "plugin",
|
|
71617
|
-
plugin: "freecodego-verify-on-stop"
|
|
71618
|
-
},
|
|
71933
|
+
source: { kind: "freecodego-verify-on-stop" },
|
|
71619
71934
|
content: [{
|
|
71620
71935
|
type: "text",
|
|
71621
71936
|
text: `<verify-on-stop>
|
|
@@ -71701,10 +72016,7 @@ ${text2}
|
|
|
71701
72016
|
const agent = agents.get(agentId);
|
|
71702
72017
|
if (typeof agent?.inject !== "function") return false;
|
|
71703
72018
|
agent.inject(createUserMessage({
|
|
71704
|
-
source: {
|
|
71705
|
-
kind: "plugin",
|
|
71706
|
-
plugin: "freecodego-review"
|
|
71707
|
-
},
|
|
72019
|
+
source: { kind: "freecodego-review" },
|
|
71708
72020
|
content: [{
|
|
71709
72021
|
type: "text",
|
|
71710
72022
|
text: `<stop-time-review>
|
|
@@ -72225,6 +72537,32 @@ ${text2}
|
|
|
72225
72537
|
await settings.update({ deferredToolSchemasEnabled: enabled });
|
|
72226
72538
|
return this.deferredTools.status();
|
|
72227
72539
|
}
|
|
72540
|
+
/**
|
|
72541
|
+
* Read the image/video generation switch and the tool names it governs.
|
|
72542
|
+
*
|
|
72543
|
+
* Two name lists, because "what this switch owns" and "what is mounted right now"
|
|
72544
|
+
* are different facts: the first comes from the registration modules' single
|
|
72545
|
+
* declarations, the second from the registrations themselves. Reported together so a
|
|
72546
|
+
* panel can say which tools a profile actually has without restating either list.
|
|
72547
|
+
* @returns the media Generation Status.
|
|
72548
|
+
*/
|
|
72549
|
+
mediaGenerationStatus() {
|
|
72550
|
+
return {
|
|
72551
|
+
enabled: this.policy.get()?.mediaGenerationEnabled !== false,
|
|
72552
|
+
gated: [...Object.values(MEDIA_GENERATION_TOOL_NAMES), ...Object.values(AGNES_MEDIA_TOOL_NAMES)],
|
|
72553
|
+
registered: this.mediaGenerationTools?.names ?? []
|
|
72554
|
+
};
|
|
72555
|
+
}
|
|
72556
|
+
/**
|
|
72557
|
+
* Mount or unmount the image and video generation tools.
|
|
72558
|
+
* @param enabled - whether the capability is switched on.
|
|
72559
|
+
* @returns the media Generation Status.
|
|
72560
|
+
*/
|
|
72561
|
+
async mediaGenerationSetEnabled(enabled) {
|
|
72562
|
+
await this.policy.update({ mediaGenerationEnabled: enabled });
|
|
72563
|
+
this.syncMediaGenerationTools();
|
|
72564
|
+
return this.mediaGenerationStatus();
|
|
72565
|
+
}
|
|
72228
72566
|
/** Probe-and-mount status for the optional LSP stack (fail-soft).
|
|
72229
72567
|
* @returns the probe-and-mount state of the optional LSP stack.
|
|
72230
72568
|
*/
|
|
@@ -73496,10 +73834,7 @@ ${detail.body}`
|
|
|
73496
73834
|
const outcome = this.personaRuns.complete(childId, produced);
|
|
73497
73835
|
if (outcome?.message === void 0) return;
|
|
73498
73836
|
outcome.parent?.inject?.(createUserMessage({
|
|
73499
|
-
source: {
|
|
73500
|
-
kind: "plugin",
|
|
73501
|
-
plugin: "freecodego-persona"
|
|
73502
|
-
},
|
|
73837
|
+
source: { kind: "freecodego-persona" },
|
|
73503
73838
|
content: [{
|
|
73504
73839
|
type: "text",
|
|
73505
73840
|
text: `[freecodego] ${outcome.message}`
|
|
@@ -73746,10 +74081,7 @@ ${detail.body}`
|
|
|
73746
74081
|
})).agent;
|
|
73747
74082
|
if (child?.followup === void 0) throw new Error("the child agent was created but cannot be sent its brief; it was not given one");
|
|
73748
74083
|
child.followup(createUserMessage({
|
|
73749
|
-
source: {
|
|
73750
|
-
kind: "plugin",
|
|
73751
|
-
plugin: "freecodego-persona"
|
|
73752
|
-
},
|
|
74084
|
+
source: { kind: "freecodego-persona" },
|
|
73753
74085
|
content: [{
|
|
73754
74086
|
type: "text",
|
|
73755
74087
|
text: input.session.brief
|
|
@@ -74333,10 +74665,7 @@ ${detail.body}`
|
|
|
74333
74665
|
if (!plan.changed) return;
|
|
74334
74666
|
if (typeof agent?.inject !== "function") return;
|
|
74335
74667
|
agent.inject(createUserMessage({
|
|
74336
|
-
source: {
|
|
74337
|
-
kind: "plugin",
|
|
74338
|
-
plugin: "freecodego-context-budget"
|
|
74339
|
-
},
|
|
74668
|
+
source: { kind: "freecodego-context-budget" },
|
|
74340
74669
|
content: [{
|
|
74341
74670
|
type: "text",
|
|
74342
74671
|
text: `<context-budget>
|
|
@@ -74373,10 +74702,7 @@ ${plan.text}
|
|
|
74373
74702
|
if (fragments.length === 0) return;
|
|
74374
74703
|
if (typeof agent.inject !== "function") return;
|
|
74375
74704
|
agent.inject(createUserMessage({
|
|
74376
|
-
source: {
|
|
74377
|
-
kind: "plugin",
|
|
74378
|
-
plugin: "freecodego-plan-mode"
|
|
74379
|
-
},
|
|
74705
|
+
source: { kind: "freecodego-plan-mode" },
|
|
74380
74706
|
content: [{
|
|
74381
74707
|
type: "text",
|
|
74382
74708
|
text: renderFragments(fragments)
|
|
@@ -74682,6 +75008,19 @@ ${plan.text}
|
|
|
74682
75008
|
async sessionDelete(sessionId) {
|
|
74683
75009
|
return sessionDelete(this.engineRemotesHost, sessionId);
|
|
74684
75010
|
}
|
|
75011
|
+
/** Resolve one of this plugin's models as the DeepSeek web-search provider.
|
|
75012
|
+
* @param input - the provider and the model the user picked.
|
|
75013
|
+
* @returns the endpoint, model, and credential the search page must use.
|
|
75014
|
+
*/
|
|
75015
|
+
async webSearchBind(input) {
|
|
75016
|
+
return webSearchBind(this.engineRemotesHost, input);
|
|
75017
|
+
}
|
|
75018
|
+
/** Report whether the saved web-search binding is this plugin's, and whether it still answers.
|
|
75019
|
+
* @returns the state the search page renders from.
|
|
75020
|
+
*/
|
|
75021
|
+
async webSearchBindingStatus() {
|
|
75022
|
+
return webSearchBindingStatus(this.webSearchBindingReads());
|
|
75023
|
+
}
|
|
74685
75024
|
/** Return the current cross-engine MCP and Skill capability inventory.
|
|
74686
75025
|
* @returns the capability snapshot the Host reports.
|
|
74687
75026
|
*/
|
|
@@ -75905,10 +76244,6 @@ ${plan.text}
|
|
|
75905
76244
|
});
|
|
75906
76245
|
if (dispose !== void 0) this.ctx.effect(() => dispose, "freecodego: edit_and_run composite tool");
|
|
75907
76246
|
}
|
|
75908
|
-
/** Model-facing media tools keep Agnes API keys and requests in the Host. */
|
|
75909
|
-
registerAgnesTools() {
|
|
75910
|
-
registerAgnesTools(this.agentToolsDeps());
|
|
75911
|
-
}
|
|
75912
76247
|
agentToolsDeps() {
|
|
75913
76248
|
return {
|
|
75914
76249
|
...this.coreDeps,
|
|
@@ -75921,9 +76256,105 @@ ${plan.text}
|
|
|
75921
76256
|
probeCommandPolicy: (agent) => this.projectPolicyForAgent(agent)
|
|
75922
76257
|
};
|
|
75923
76258
|
}
|
|
75924
|
-
/**
|
|
75925
|
-
|
|
75926
|
-
|
|
76259
|
+
/** The mounted image/video registrations, absent while the switch is off. */
|
|
76260
|
+
mediaGenerationTools;
|
|
76261
|
+
/**
|
|
76262
|
+
* Register the audio generation and transcription tools, which no switch governs.
|
|
76263
|
+
* @returns the disposer that releases both registrations.
|
|
76264
|
+
*/
|
|
76265
|
+
registerAudioTools() {
|
|
76266
|
+
return registerAudioTools(this.mediaHost).dispose;
|
|
76267
|
+
}
|
|
76268
|
+
/**
|
|
76269
|
+
* Mount or unmount the image and video tools so that they match the setting.
|
|
76270
|
+
*
|
|
76271
|
+
* Remounted from the switch's own Remote rather than read at call time, because a
|
|
76272
|
+
* tool the model can see *is* a registration: gating `execute` instead would leave the
|
|
76273
|
+
* schema in every request, which is the cost the switch exists to remove.
|
|
76274
|
+
*/
|
|
76275
|
+
syncMediaGenerationTools() {
|
|
76276
|
+
const enabled = this.policy.get()?.mediaGenerationEnabled !== false;
|
|
76277
|
+
if (enabled === (this.mediaGenerationTools !== void 0)) return;
|
|
76278
|
+
if (!enabled) {
|
|
76279
|
+
this.disposeMediaGenerationTools();
|
|
76280
|
+
return;
|
|
76281
|
+
}
|
|
76282
|
+
const generation = registerGenerationTools(this.mediaHost);
|
|
76283
|
+
const legacy = registerAgnesMediaTools(this.agentToolsDeps());
|
|
76284
|
+
this.mediaGenerationTools = {
|
|
76285
|
+
names: [...generation.names, ...legacy.names],
|
|
76286
|
+
dispose: () => {
|
|
76287
|
+
generation.dispose();
|
|
76288
|
+
legacy.dispose();
|
|
76289
|
+
}
|
|
76290
|
+
};
|
|
76291
|
+
}
|
|
76292
|
+
/**
|
|
76293
|
+
* Rebuild the web-search binding this plugin wrote, when this process cannot serve it.
|
|
76294
|
+
*
|
|
76295
|
+
* Read once at start and never in a request path: a binding that died with the
|
|
76296
|
+
* previous process has to be whole again before the first search runs, and the
|
|
76297
|
+
* search itself must not be the thing that discovers it. Every read and write the
|
|
76298
|
+
* pass needs is injected, so `web-search-binding.ts` owns the rules and this method
|
|
76299
|
+
* owns only where they are satisfied — including the two services whose absence
|
|
76300
|
+
* leaves a binding unbuildable, which is reported rather than half-applied.
|
|
76301
|
+
*/
|
|
76302
|
+
async repairWebSearchBinding() {
|
|
76303
|
+
let reads;
|
|
76304
|
+
let report;
|
|
76305
|
+
try {
|
|
76306
|
+
reads = this.webSearchBindingReads();
|
|
76307
|
+
report = await repairWebSearchBinding({
|
|
76308
|
+
...reads,
|
|
76309
|
+
bind: (input) => webSearchBind(this.engineRemotesHost, input),
|
|
76310
|
+
writeCredential: async (ref, value) => {
|
|
76311
|
+
const credentials = this.credentials;
|
|
76312
|
+
if (credentials === void 0) throw new Error("the credentials service is not mounted, so the web-search key cannot be written");
|
|
76313
|
+
await credentials.set(credentialRef2(ref), value);
|
|
76314
|
+
},
|
|
76315
|
+
writeSection: async (patch) => {
|
|
76316
|
+
const settings = this.ctx.get("settings");
|
|
76317
|
+
if (settings === void 0) throw new Error("the settings service is not mounted, so the web-search section cannot be rewritten");
|
|
76318
|
+
await settings.update(WEB_SEARCH_SETTINGS_NAMESPACE, patch);
|
|
76319
|
+
}
|
|
76320
|
+
});
|
|
76321
|
+
} catch (error) {
|
|
76322
|
+
this.ctx.logger?.warn?.(`FreeCodeGo could not repair the web-search binding: ${error instanceof Error ? error.message : String(error)}`);
|
|
76323
|
+
return;
|
|
76324
|
+
}
|
|
76325
|
+
if (report.outcome === "rebuilt") this.ctx.logger?.info?.(`FreeCodeGo rebuilt the stale web-search binding for ${reads.remembered?.provider ?? ""}/${reads.remembered?.model ?? ""}`);
|
|
76326
|
+
if (report.outcome === "failed") this.ctx.logger?.warn?.(`FreeCodeGo could not rebuild the web-search binding: ${report.detail ?? "unknown failure"}`);
|
|
76327
|
+
}
|
|
76328
|
+
/**
|
|
76329
|
+
* The reads both web-search passes share, taken from this Host's services.
|
|
76330
|
+
*
|
|
76331
|
+
* One accessor rather than two because the answers have to agree: the boot pass
|
|
76332
|
+
* deciding a saved route is dead while the page reads it as alive would rewrite a
|
|
76333
|
+
* section the user is looking at. The remembered pair is read through the policy —
|
|
76334
|
+
* the one seam a settings read goes through — and a composition with no
|
|
76335
|
+
* configuration at all resolves to `undefined` rather than throwing here.
|
|
76336
|
+
*/
|
|
76337
|
+
webSearchBindingReads() {
|
|
76338
|
+
const settings = this.ctx.get("settings");
|
|
76339
|
+
const configured = this.policy.get();
|
|
76340
|
+
const provider = asString(configured?.webSearchBindingProvider) ?? "";
|
|
76341
|
+
const model = asString(configured?.webSearchBindingModel) ?? "";
|
|
76342
|
+
return {
|
|
76343
|
+
remembered: provider === "" || model === "" ? void 0 : {
|
|
76344
|
+
provider,
|
|
76345
|
+
model
|
|
76346
|
+
},
|
|
76347
|
+
readSection: async () => {
|
|
76348
|
+
const descriptor = settings?.describe().find((row) => row.ns === WEB_SEARCH_SETTINGS_NAMESPACE);
|
|
76349
|
+
return descriptor === void 0 ? void 0 : maybeRecord(descriptor.value);
|
|
76350
|
+
},
|
|
76351
|
+
servesBridgeRoute: (routeId) => this.claudeBridge.hasRoute(routeId)
|
|
76352
|
+
};
|
|
76353
|
+
}
|
|
76354
|
+
/** Release the image and video registrations, when any are mounted. */
|
|
76355
|
+
disposeMediaGenerationTools() {
|
|
76356
|
+
this.mediaGenerationTools?.dispose();
|
|
76357
|
+
this.mediaGenerationTools = void 0;
|
|
75927
76358
|
}
|
|
75928
76359
|
get mediaHost() {
|
|
75929
76360
|
return {
|
|
@@ -76744,13 +77175,12 @@ function hasInstalledClaudeRuntime() {
|
|
|
76744
77175
|
// packages/freecodego/bundle-latest/src/index.ts
|
|
76745
77176
|
var name = "freecodego";
|
|
76746
77177
|
var inject = [];
|
|
76747
|
-
async function apply2(ctx,
|
|
76748
|
-
await ctx.plugin(FreeCodeGoHarnessPlugin, config);
|
|
77178
|
+
async function apply2(ctx, _config = {}) {
|
|
76749
77179
|
await ctx.plugin(FreeCodeGoAgentEngineRouter, {});
|
|
76750
77180
|
}
|
|
76751
77181
|
export {
|
|
77182
|
+
FreeCodeGoHarnessPlugin,
|
|
76752
77183
|
apply2 as apply,
|
|
76753
|
-
bootstrapFreeCodeGoHarness,
|
|
76754
77184
|
inject,
|
|
76755
77185
|
name,
|
|
76756
77186
|
registerFreeCodeGoSessionEventTypes
|