Merge branch 'puter/issue-9-gitea-smoke' into puter/issue-14-integration

# Conflicts:
#	packages/primitives/package.json
This commit is contained in:
-Puter
2026-07-24 02:37:09 +05:30
10 changed files with 1454 additions and 2 deletions

View File

@@ -11,7 +11,8 @@
"./project-issue": "./src/project-issue.ts",
"./project-workspace": "./src/project-workspace.ts",
"./project-work": "./src/project-work.ts",
"./signal": "./src/signal.ts"
"./signal": "./src/signal.ts",
"./smoke": "./src/smoke.ts"
},
"scripts": {
"check-types": "tsc --noEmit",

View File

@@ -6,3 +6,4 @@ export * from "./project-issue";
export * from "./project-workspace";
export * from "./project-work";
export * from "./signal";
export * from "./smoke";

View File

@@ -0,0 +1,164 @@
import { Effect } from "effect";
import { describe, expect, it } from "vitest";
import {
SmokeContractError,
advanceSmokeLoop,
decodeSmokeChatText,
decodeSmokeModelCatalog,
decodeSmokePlan,
decodeSmokeReview,
decodeSmokeWorkerReport,
initialSmokeLoopState,
redactSmokeText,
selectSmokeModelRoles,
validateSmokeCapabilities,
} from "./smoke";
const validRoleSelection = () => ({
plannerReviewerModel: "glm-5.2",
plannerReviewerProvider: "cheaptricks",
workerModel: "minimax-m3",
workerProvider: "cheaptricks",
workerToolCallMode: "serial" as const,
});
const run = <A, E>(effect: Effect.Effect<A, E>): A => Effect.runSync(effect);
describe("smoke primitives", () => {
it("selects the planner/reviewer and serial M3 worker roles", () => {
const roles = run(selectSmokeModelRoles(validRoleSelection()));
expect(roles.worker).toMatchObject({
model: "minimax-m3",
role: "worker",
toolCallMode: "serial",
});
expect(roles.plannerReviewer).toMatchObject({
model: "glm-5.2",
role: "planner-reviewer",
});
});
it("rejects a non-M3 worker or non-GLM planner", () => {
const worker = validRoleSelection();
worker.workerModel = "glm-5.2";
const workerError = run(Effect.flip(selectSmokeModelRoles(worker)));
expect(workerError).toBeInstanceOf(SmokeContractError);
expect(workerError.reason).toBe("InvalidModelRole");
const planner = validRoleSelection();
planner.plannerReviewerModel = "minimax-m3";
const plannerError = run(Effect.flip(selectSmokeModelRoles(planner)));
expect(plannerError.reason).toBe("InvalidModelRole");
});
it("advances only through the serial smoke loop", () => {
let state = initialSmokeLoopState();
state = run(advanceSmokeLoop(state, "preflight-passed"));
state = run(advanceSmokeLoop(state, "plan-validated"));
state = run(advanceSmokeLoop(state, "worker-succeeded"));
state = run(advanceSmokeLoop(state, "review-approved"));
expect(state.phase).toBe("completed");
expect(state.history).toEqual([
"preflight",
"planning",
"worker-running",
"reviewing",
"completed",
]);
});
it("turns contract failures into a terminal state", () => {
const state = run(
advanceSmokeLoop(
initialSmokeLoopState(),
"contract-failed",
"daemon is offline"
)
);
expect(state.phase).toBe("failed");
expect(state.lastError).toBe("daemon is offline");
});
it("rejects out-of-order loop transitions", () => {
const error = run(
Effect.flip(advanceSmokeLoop(initialSmokeLoopState(), "review-approved"))
);
expect(error).toBeInstanceOf(SmokeContractError);
expect(error.reason).toBe("InvalidTransition");
});
it("validates model reports at the primitive boundary", () => {
const plan = run(
decodeSmokePlan({
acceptanceCriteria: ["The button renders"],
nonGoals: [],
steps: ["Add the button", "Run the web check"],
summary: "Add a small button to the disposable project",
})
);
const worker = run(
decodeSmokeWorkerReport({
status: "completed",
summary: "Changed the project and ran the targeted check.",
})
);
const review = run(
decodeSmokeReview({
approved: true,
findings: [],
summary: "The change matches the acceptance criteria.",
})
);
expect(plan.steps).toHaveLength(2);
expect(worker.status).toBe("completed");
expect(review.approved).toBe(true);
});
it("rejects empty or malformed model output", () => {
const empty = run(
Effect.flip(
decodeSmokeChatText({ choices: [{ message: { content: " " } }] })
)
);
expect(empty.reason).toBe("InvalidModelResponse");
const malformed = run(Effect.flip(decodeSmokeReview({ approved: true })));
expect(malformed.reason).toBe("InvalidReport");
});
it("validates the canonical CPA model catalog", () => {
const catalog = run(
decodeSmokeModelCatalog({
data: [{ id: "minimax-m3" }, { id: "glm-5.2" }],
})
);
expect(catalog.data.map(({ id }) => id)).toEqual(["minimax-m3", "glm-5.2"]);
});
it("fails a capability report when any required check fails", () => {
const error = run(
Effect.flip(
validateSmokeCapabilities([
{ id: "web", message: "ready", passed: true },
{ id: "daemon", message: "daemon is offline", passed: false },
])
)
);
expect(error.reason).toBe("InvalidReport");
expect(error.message).toContain("daemon is offline");
});
it("redacts secrets without changing unrelated text", () => {
expect(
redactSmokeText("status token=secret-key endpoint=ok", ["secret-key"])
).toBe("status token=[REDACTED] endpoint=ok");
});
});

View File

@@ -0,0 +1,347 @@
/* eslint-disable max-classes-per-file -- the smoke contract keeps its schemas, errors, and transitions together. */
import { Effect, Schema } from "effect";
const MeaningfulString = Schema.String.check(
Schema.makeFilter((value) => value.trim().length > 0, {
expected: "a non-empty string",
})
);
const SmokePhase = Schema.Literals([
"preflight",
"planning",
"worker-running",
"reviewing",
"completed",
"failed",
]);
export type SmokePhase = typeof SmokePhase.Type;
const SmokeTransition = Schema.Literals([
"preflight-passed",
"plan-validated",
"worker-succeeded",
"review-approved",
"contract-failed",
"runtime-failed",
]);
type SmokeTransition = typeof SmokeTransition.Type;
export const SmokeRole = Schema.Literals(["planner-reviewer", "worker"]);
export type SmokeRole = typeof SmokeRole.Type;
const SmokeToolCallMode = Schema.Literal("serial");
export const SmokeRoleSelectionInput = Schema.Struct({
plannerReviewerModel: MeaningfulString,
plannerReviewerProvider: MeaningfulString,
workerModel: MeaningfulString,
workerProvider: MeaningfulString,
workerToolCallMode: SmokeToolCallMode,
});
export type SmokeRoleSelectionInput = typeof SmokeRoleSelectionInput.Type;
export const SmokeModelRole = Schema.Struct({
model: MeaningfulString,
provider: MeaningfulString,
role: SmokeRole,
toolCallMode: Schema.Literal("serial"),
});
export type SmokeModelRole = typeof SmokeModelRole.Type;
export const SmokeModelRoles = Schema.Struct({
plannerReviewer: SmokeModelRole,
worker: SmokeModelRole,
});
export type SmokeModelRoles = typeof SmokeModelRoles.Type;
export const SmokeContractReason = Schema.Literals([
"InvalidInput",
"InvalidModelRole",
"InvalidTransition",
"InvalidModelResponse",
"InvalidReport",
]);
export type SmokeContractReason = typeof SmokeContractReason.Type;
export class SmokeContractError extends Schema.TaggedErrorClass<SmokeContractError>()(
"SmokeContractError",
{
message: Schema.String,
reason: SmokeContractReason,
}
) {}
export const selectSmokeModelRoles = Effect.fn("Smoke.selectModelRoles")(
function* selectSmokeModelRoles(input: unknown) {
const selection: SmokeRoleSelectionInput =
yield* Schema.decodeUnknownEffect(SmokeRoleSelectionInput)(input).pipe(
Effect.mapError(
(cause) =>
new SmokeContractError({
message: cause.message,
reason: "InvalidInput",
})
)
);
if (selection.workerModel !== "minimax-m3") {
return yield* Effect.fail(
new SmokeContractError({
message: "The smoke worker must use minimax-m3",
reason: "InvalidModelRole",
})
);
}
if (selection.plannerReviewerModel !== "glm-5.2") {
return yield* Effect.fail(
new SmokeContractError({
message: "The smoke planner/reviewer must use glm-5.2",
reason: "InvalidModelRole",
})
);
}
return {
plannerReviewer: {
model: selection.plannerReviewerModel,
provider: selection.plannerReviewerProvider,
role: "planner-reviewer" as const,
toolCallMode: "serial" as const,
},
worker: {
model: selection.workerModel,
provider: selection.workerProvider,
role: "worker" as const,
toolCallMode: "serial" as const,
},
} satisfies SmokeModelRoles;
}
);
export const SmokePlan = Schema.Struct({
acceptanceCriteria: Schema.NonEmptyArray(MeaningfulString),
nonGoals: Schema.Array(MeaningfulString),
steps: Schema.NonEmptyArray(MeaningfulString),
summary: MeaningfulString,
});
export type SmokePlan = typeof SmokePlan.Type;
export const SmokeWorkerReport = Schema.Struct({
status: Schema.Literals(["completed", "blocked", "failed"]),
summary: MeaningfulString,
});
export type SmokeWorkerReport = typeof SmokeWorkerReport.Type;
export const SmokeReview = Schema.Struct({
approved: Schema.Boolean,
findings: Schema.Array(MeaningfulString),
summary: MeaningfulString,
});
export type SmokeReview = typeof SmokeReview.Type;
export const SmokeChatResponse = Schema.Struct({
choices: Schema.NonEmptyArray(
Schema.Struct({
message: Schema.Struct({ content: Schema.String }),
})
),
});
export const SmokeModelCatalog = Schema.Struct({
data: Schema.Array(Schema.Struct({ id: MeaningfulString })),
});
export type SmokeModelCatalog = typeof SmokeModelCatalog.Type;
export const decodeSmokeModelCatalog = Effect.fn("Smoke.decodeModelCatalog")(
function* decodeSmokeModelCatalog(input: unknown) {
return yield* Schema.decodeUnknownEffect(SmokeModelCatalog)(input).pipe(
Effect.mapError(
(cause) =>
new SmokeContractError({
message: cause.message,
reason: "InvalidModelResponse",
})
)
);
}
);
export const decodeSmokeChatText = Effect.fn("Smoke.decodeChatText")(
function* decodeSmokeChatText(input: unknown) {
const response = yield* Schema.decodeUnknownEffect(SmokeChatResponse)(
input
).pipe(
Effect.mapError(
(cause) =>
new SmokeContractError({
message: cause.message,
reason: "InvalidModelResponse",
})
)
);
const text = response.choices[0].message.content;
if (text.trim().length === 0) {
return yield* Effect.fail(
new SmokeContractError({
message: "The model returned an empty response",
reason: "InvalidModelResponse",
})
);
}
return text;
}
);
export const decodeSmokePlan = Effect.fn("Smoke.decodePlan")(
function* decodeSmokePlan(input: unknown) {
return yield* Schema.decodeUnknownEffect(SmokePlan)(input).pipe(
Effect.mapError(
(cause) =>
new SmokeContractError({
message: cause.message,
reason: "InvalidReport",
})
)
);
}
);
export const decodeSmokeWorkerReport = Effect.fn("Smoke.decodeWorkerReport")(
function* decodeSmokeWorkerReport(input: unknown) {
return yield* Schema.decodeUnknownEffect(SmokeWorkerReport)(input).pipe(
Effect.mapError(
(cause) =>
new SmokeContractError({
message: cause.message,
reason: "InvalidReport",
})
)
);
}
);
export const decodeSmokeReview = Effect.fn("Smoke.decodeReview")(
function* decodeSmokeReview(input: unknown) {
return yield* Schema.decodeUnknownEffect(SmokeReview)(input).pipe(
Effect.mapError(
(cause) =>
new SmokeContractError({
message: cause.message,
reason: "InvalidReport",
})
)
);
}
);
export const SmokeCapabilityCheck = Schema.Struct({
id: MeaningfulString,
message: MeaningfulString,
passed: Schema.Boolean,
});
export type SmokeCapabilityCheck = typeof SmokeCapabilityCheck.Type;
export const validateSmokeCapabilities = Effect.fn(
"Smoke.validateCapabilities"
)(function* validateSmokeCapabilities(input: unknown) {
const checks = yield* Schema.decodeUnknownEffect(
Schema.NonEmptyArray(SmokeCapabilityCheck)
)(input).pipe(
Effect.mapError(
(cause) =>
new SmokeContractError({
message: cause.message,
reason: "InvalidInput",
})
)
);
const failed = checks.filter((check) => !check.passed);
if (failed.length > 0) {
return yield* Effect.fail(
new SmokeContractError({
message: failed
.map((check) => `${check.id}: ${check.message}`)
.join("; "),
reason: "InvalidReport",
})
);
}
return checks;
});
export const SmokeLoopState = Schema.Struct({
history: Schema.Array(SmokePhase),
lastError: Schema.NullOr(Schema.String),
phase: SmokePhase,
});
export type SmokeLoopState = typeof SmokeLoopState.Type;
export const initialSmokeLoopState = (): SmokeLoopState => ({
history: ["preflight"],
lastError: null,
phase: "preflight",
});
const nextPhase: Readonly<
Record<SmokePhase, Partial<Record<SmokeTransition, SmokePhase>>>
> = {
completed: {},
failed: {},
planning: {
"plan-validated": "worker-running",
"runtime-failed": "failed",
},
preflight: {
"contract-failed": "failed",
"preflight-passed": "planning",
"runtime-failed": "failed",
},
reviewing: {
"contract-failed": "failed",
"review-approved": "completed",
"runtime-failed": "failed",
},
"worker-running": {
"contract-failed": "failed",
"runtime-failed": "failed",
"worker-succeeded": "reviewing",
},
};
export const advanceSmokeLoop = Effect.fn("Smoke.advanceLoop")(
function* advanceSmokeLoop(
state: SmokeLoopState,
transition: SmokeTransition,
error?: string
) {
const phase = nextPhase[state.phase][transition];
if (phase === undefined) {
return yield* Effect.fail(
new SmokeContractError({
message: `Cannot apply ${transition} while smoke loop is ${state.phase}`,
reason: "InvalidTransition",
})
);
}
return {
history: [...state.history, phase],
lastError: phase === "failed" ? (error ?? "Smoke loop failed") : null,
phase,
} satisfies SmokeLoopState;
}
);
export const redactSmokeText = (
text: string,
secrets: readonly string[]
): string => {
let redacted = text;
for (const secret of secrets) {
if (secret.length > 0) {
redacted = redacted.replaceAll(secret, "[REDACTED]");
}
}
return redacted;
};