@brainervirus/workit-pi 8.31.1 → 8.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/worker.js +1 -0
- package/dist/workit.js +79 -29
- package/package.json +1 -1
package/dist/worker.js
CHANGED
|
@@ -6860,6 +6860,7 @@ var workspaceConfigSchema = object({
|
|
|
6860
6860
|
verification: _enum(["proportional", "self", "independent"]).optional(),
|
|
6861
6861
|
delegation: unknown().optional(),
|
|
6862
6862
|
trailers: boolean2().optional(),
|
|
6863
|
+
deleteBranch: boolean2().optional(),
|
|
6863
6864
|
liveSessionGuard: boolean2().optional(),
|
|
6864
6865
|
fanout: object({ tierModels: unknown().optional() }).passthrough().optional(),
|
|
6865
6866
|
models: object({ roles: unknown().optional() }).passthrough().optional(),
|
package/dist/workit.js
CHANGED
|
@@ -7410,10 +7410,11 @@ function invalidOperation(family, input, error) {
|
|
|
7410
7410
|
const request = isObject2(input) ? input : {};
|
|
7411
7411
|
const action = typeof request.action === "string" ? request.action : "";
|
|
7412
7412
|
const actions = OPERATION_ACTIONS[family];
|
|
7413
|
-
if (!actions.includes(action))
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
});
|
|
7413
|
+
if (!actions.includes(action)) {
|
|
7414
|
+
const common = actions.find((name) => READ_ONLY_ACTIONS.has(name)) ?? actions[0];
|
|
7415
|
+
const example = JSON.stringify(exampleOperation(family, common));
|
|
7416
|
+
return failure2("invalid_input", `${family}: action must be one of ${oneOf(actions)}. Example: ${example}`, { fields: [{ path: "action", reason: `got ${JSON.stringify(request.action ?? null)}` }] });
|
|
7417
|
+
}
|
|
7417
7418
|
const own = actionKeys(family, action);
|
|
7418
7419
|
const fields = [];
|
|
7419
7420
|
const sentence = [];
|
|
@@ -8493,6 +8494,7 @@ var workspaceConfigSchema = object({
|
|
|
8493
8494
|
verification: _enum(["proportional", "self", "independent"]).optional(),
|
|
8494
8495
|
delegation: unknown().optional(),
|
|
8495
8496
|
trailers: boolean2().optional(),
|
|
8497
|
+
deleteBranch: boolean2().optional(),
|
|
8496
8498
|
liveSessionGuard: boolean2().optional(),
|
|
8497
8499
|
fanout: object({ tierModels: unknown().optional() }).passthrough().optional(),
|
|
8498
8500
|
models: object({ roles: unknown().optional() }).passthrough().optional(),
|
|
@@ -16204,7 +16206,14 @@ var sessionMarkerFile = (input, session, store) => {
|
|
|
16204
16206
|
return path19.join(dir, "hooks", `skills-${name}.json`);
|
|
16205
16207
|
};
|
|
16206
16208
|
var list2 = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
16207
|
-
var EMPTY = {
|
|
16209
|
+
var EMPTY = {
|
|
16210
|
+
nudged: [],
|
|
16211
|
+
loaded: [],
|
|
16212
|
+
raw: [],
|
|
16213
|
+
stops: [],
|
|
16214
|
+
judges: [],
|
|
16215
|
+
model: null
|
|
16216
|
+
};
|
|
16208
16217
|
var readRaw = (file) => {
|
|
16209
16218
|
try {
|
|
16210
16219
|
return fs15.readFileSync(file, "utf8");
|
|
@@ -16220,7 +16229,8 @@ var parseMarker = (text) => {
|
|
|
16220
16229
|
loaded: list2(value.loaded),
|
|
16221
16230
|
raw: list2(value.raw),
|
|
16222
16231
|
stops: list2(value.stops),
|
|
16223
|
-
judges: list2(value.judges)
|
|
16232
|
+
judges: list2(value.judges),
|
|
16233
|
+
model: typeof value.model === "string" ? value.model : null
|
|
16224
16234
|
};
|
|
16225
16235
|
} catch {
|
|
16226
16236
|
return { ...EMPTY };
|
|
@@ -16265,6 +16275,18 @@ var trackJudge = (input, agentId, running) => {
|
|
|
16265
16275
|
return { ...marker, judges: running ? [...rest, agentId] : rest };
|
|
16266
16276
|
});
|
|
16267
16277
|
};
|
|
16278
|
+
var modelSwitchedOnDisk = (input) => {
|
|
16279
|
+
const session = input.session.id;
|
|
16280
|
+
const model = input.model;
|
|
16281
|
+
const file = session && model ? sessionMarkerFile(input, session) : null;
|
|
16282
|
+
if (!file || !model)
|
|
16283
|
+
return false;
|
|
16284
|
+
const previous = readSessionMarker(file).model;
|
|
16285
|
+
if (previous === model)
|
|
16286
|
+
return false;
|
|
16287
|
+
updateSessionMarker(file, (marker) => ({ ...marker, model }));
|
|
16288
|
+
return previous !== null;
|
|
16289
|
+
};
|
|
16268
16290
|
|
|
16269
16291
|
// packages/workit-core/src/hooks/shell-words.ts
|
|
16270
16292
|
class ShellAnalysisError extends Error {
|
|
@@ -24560,7 +24582,9 @@ function decide(input, deps) {
|
|
|
24560
24582
|
if (!usable2(descriptor.context.perTurn))
|
|
24561
24583
|
return NONE6;
|
|
24562
24584
|
const current = turnContextText(input, descriptor);
|
|
24563
|
-
const
|
|
24585
|
+
const turn = resendsOnChange(descriptor) ? changedTurnContext(input, current) : current;
|
|
24586
|
+
const text = input.model && modelSwitchedOnDisk(input) ? [invariantBootstrap(), turn].filter(Boolean).join(`
|
|
24587
|
+
`) : turn;
|
|
24564
24588
|
return withContextLine(text ? { kind: "context", text } : NONE6, promptNudge(input, event.prompt));
|
|
24565
24589
|
}
|
|
24566
24590
|
case "shell.pre": {
|
|
@@ -24766,17 +24790,6 @@ var PI_DESCRIPTOR = {
|
|
|
24766
24790
|
]
|
|
24767
24791
|
};
|
|
24768
24792
|
// packages/workit-core/src/hooks/model-switch.ts
|
|
24769
|
-
var MAX_SESSIONS = 256;
|
|
24770
|
-
var modelSwitched = (models, sessionId, model) => {
|
|
24771
|
-
if (!model)
|
|
24772
|
-
return false;
|
|
24773
|
-
const previous = models.get(sessionId);
|
|
24774
|
-
models.delete(sessionId);
|
|
24775
|
-
models.set(sessionId, model);
|
|
24776
|
-
if (models.size > MAX_SESSIONS)
|
|
24777
|
-
models.delete(models.keys().next().value);
|
|
24778
|
-
return previous !== undefined && previous !== model;
|
|
24779
|
-
};
|
|
24780
24793
|
var modelKey = (model) => {
|
|
24781
24794
|
if (model === null || typeof model !== "object")
|
|
24782
24795
|
return null;
|
|
@@ -24812,13 +24825,15 @@ var taskTurnContext = (ctx) => {
|
|
|
24812
24825
|
return null;
|
|
24813
24826
|
}
|
|
24814
24827
|
};
|
|
24815
|
-
var
|
|
24816
|
-
var
|
|
24817
|
-
const
|
|
24818
|
-
const
|
|
24819
|
-
|
|
24820
|
-
|
|
24828
|
+
var switchedSessions = new Set;
|
|
24829
|
+
var noteModelSelect = (event, ctx) => {
|
|
24830
|
+
const next = modelKey(event.model);
|
|
24831
|
+
const previous = modelKey(event.previousModel);
|
|
24832
|
+
if (next && previous && next !== previous)
|
|
24833
|
+
switchedSessions.add(ctx.sessionManager.getSessionId());
|
|
24821
24834
|
};
|
|
24835
|
+
var modelSwitchContract = (ctx) => switchedSessions.delete(ctx.sessionManager.getSessionId()) && ctx.isProjectTrusted() ? invariantBootstrap() : null;
|
|
24836
|
+
var turnContext = (ctx) => taskTurnContext(ctx);
|
|
24822
24837
|
var turnInput = (ctx) => ({
|
|
24823
24838
|
host: "pi",
|
|
24824
24839
|
cwd: ctx.cwd,
|
|
@@ -24865,7 +24880,7 @@ var unfinishedTaskOffer2 = (ctx) => {
|
|
|
24865
24880
|
// packages/workit-core/src/hooks/repeat-failure.ts
|
|
24866
24881
|
import { createHash as createHash18 } from "node:crypto";
|
|
24867
24882
|
var SAME_CALL_FAILED = "Same call failed twice:";
|
|
24868
|
-
var
|
|
24883
|
+
var MAX_SESSIONS = 256;
|
|
24869
24884
|
var stable = (value) => JSON.stringify(value, (_key, entry) => entry && typeof entry === "object" && !Array.isArray(entry) ? Object.fromEntries(Object.entries(entry).toSorted(([a], [b]) => a.localeCompare(b))) : entry) ?? "null";
|
|
24870
24885
|
var hashOf = (call) => createHash18("sha256").update(call).digest("hex").slice(0, 32);
|
|
24871
24886
|
var record2 = (memo, sessionId, call, failed, next) => {
|
|
@@ -24875,7 +24890,7 @@ var record2 = (memo, sessionId, call, failed, next) => {
|
|
|
24875
24890
|
return null;
|
|
24876
24891
|
const hash = hashOf(call);
|
|
24877
24892
|
memo.set(sessionId, hash);
|
|
24878
|
-
if (memo.size >
|
|
24893
|
+
if (memo.size > MAX_SESSIONS)
|
|
24879
24894
|
memo.delete(memo.keys().next().value);
|
|
24880
24895
|
return previous === hash && next ? `${SAME_CALL_FAILED} ${next}` : null;
|
|
24881
24896
|
};
|
|
@@ -24893,6 +24908,26 @@ var escalateToolFailure = (memo, sessionId, tool, input, result) => {
|
|
|
24893
24908
|
return line && failed ? { ...result, error: `${result.error}
|
|
24894
24909
|
${line}` } : result;
|
|
24895
24910
|
};
|
|
24911
|
+
var WORKIT_COMMAND = /^\s*(?:[A-Za-z_][A-Za-z0-9_]*=\S*\s+)*workit\s/;
|
|
24912
|
+
var unblockOf = (output) => {
|
|
24913
|
+
const human = /^\s*unblock: (.+)$/m.exec(output)?.[1];
|
|
24914
|
+
if (human)
|
|
24915
|
+
return human.trim();
|
|
24916
|
+
const json = /"unblock":("(?:[^"\\]|\\.)*")/.exec(output)?.[1];
|
|
24917
|
+
if (!json)
|
|
24918
|
+
return null;
|
|
24919
|
+
try {
|
|
24920
|
+
return JSON.parse(json);
|
|
24921
|
+
} catch {
|
|
24922
|
+
return null;
|
|
24923
|
+
}
|
|
24924
|
+
};
|
|
24925
|
+
var repeatedCliFailure = (memo, sessionId, command, output) => {
|
|
24926
|
+
if (!WORKIT_COMMAND.test(command))
|
|
24927
|
+
return null;
|
|
24928
|
+
const failed = /^workit: /m.test(output) || /"ok":\s*false/.test(output);
|
|
24929
|
+
return record2(memo, sessionId, `cli\x00${command.trim()}`, failed, failed ? unblockOf(output) : null);
|
|
24930
|
+
};
|
|
24896
24931
|
|
|
24897
24932
|
// packages/workit-pi/src/tools.ts
|
|
24898
24933
|
var readOnlyActions = new Set(["list", "inspect", "preview", "explain", "export"]);
|
|
@@ -25012,11 +25047,17 @@ var enforceToolPolicy = (event, ctx) => {
|
|
|
25012
25047
|
};
|
|
25013
25048
|
var observeToolResult = (event, ctx) => {
|
|
25014
25049
|
try {
|
|
25015
|
-
if (event.toolName !== "bash"
|
|
25050
|
+
if (event.toolName !== "bash")
|
|
25016
25051
|
return;
|
|
25017
25052
|
const command = event.input?.command;
|
|
25018
25053
|
if (typeof command !== "string")
|
|
25019
25054
|
return;
|
|
25055
|
+
const shown = event.content.map((part) => part.type === "text" ? part.text : "").join(`
|
|
25056
|
+
`);
|
|
25057
|
+
const session = piContext(ctx).caller.actor;
|
|
25058
|
+
const repeated = repeatedCliFailure(failures, session, command, shown);
|
|
25059
|
+
if (event.isError)
|
|
25060
|
+
return repeated ? { content: [...event.content, { type: "text", text: repeated }] } : undefined;
|
|
25020
25061
|
const post = hookInput(ctx, {
|
|
25021
25062
|
kind: "shell.post",
|
|
25022
25063
|
command,
|
|
@@ -25028,7 +25069,10 @@ var observeToolResult = (event, ctx) => {
|
|
|
25028
25069
|
const named = process.env.WORKIT_PI_WORKER_ROLE;
|
|
25029
25070
|
const role = named === "implementer" ? "implementer" : named ? "judge" : null;
|
|
25030
25071
|
const nudge = process.env.WORKIT_PI_WORKER_SESSION ? rawGitPre(post, command, { nudge: roleSteering(role, false).nudges }) : shellNudge(post, command);
|
|
25031
|
-
|
|
25072
|
+
const extra = [nudge.kind === "context" ? nudge.text : null, repeated].filter((text) => text !== null);
|
|
25073
|
+
return extra.length > 0 ? { content: [...event.content, { type: "text", text: extra.join(`
|
|
25074
|
+
|
|
25075
|
+
`) }] } : undefined;
|
|
25032
25076
|
} catch {
|
|
25033
25077
|
return;
|
|
25034
25078
|
}
|
|
@@ -25952,6 +25996,7 @@ function extension(pi) {
|
|
|
25952
25996
|
sessions.delete(ctx.sessionManager.getSessionId());
|
|
25953
25997
|
reconcileLostWorkers(ctx);
|
|
25954
25998
|
});
|
|
25999
|
+
pi.on("model_select", (event, ctx) => noteModelSelect(event, ctx));
|
|
25955
26000
|
pi.on("before_agent_start", (event, ctx) => {
|
|
25956
26001
|
if (event.messageType !== "user")
|
|
25957
26002
|
return;
|
|
@@ -25960,7 +26005,8 @@ function extension(pi) {
|
|
|
25960
26005
|
const trusted = ctx.isProjectTrusted();
|
|
25961
26006
|
const task = turnContext(ctx);
|
|
25962
26007
|
let content;
|
|
25963
|
-
|
|
26008
|
+
const firstTurn = !sessions.has(id);
|
|
26009
|
+
if (!firstTurn) {
|
|
25964
26010
|
content = trusted ? changedTurnContext(turnInput(ctx), task) : null;
|
|
25965
26011
|
} else {
|
|
25966
26012
|
sessions.add(id);
|
|
@@ -25972,6 +26018,10 @@ function extension(pi) {
|
|
|
25972
26018
|
|
|
25973
26019
|
${offer}` : ""}`;
|
|
25974
26020
|
}
|
|
26021
|
+
const contract = modelSwitchContract(ctx);
|
|
26022
|
+
if (contract && !firstTurn)
|
|
26023
|
+
content = content ? `${contract}
|
|
26024
|
+
${content}` : contract;
|
|
25975
26025
|
if (content)
|
|
25976
26026
|
return { message: contextMessage(ctx, nudge ? `${content}
|
|
25977
26027
|
|