Add gm harness with batch chance tools for play.

Main world layer can loop on the chance tool (requests array) until settlement JSON. Driver forwards output deltas; standalone chance worker accepts batch requests. play_slots.chance gates the harness.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-25 00:49:19 +08:00
co-authored by Cursor
parent 6b4156fd0f
commit 8360e885bb
9 changed files with 428 additions and 32 deletions
+2
View File
@@ -37,6 +37,7 @@ export type DriverRunInput = {
maxIterations?: number;
onThinkingDelta?: (delta: string) => void;
onThinkingDone?: (text: string) => void;
onOutputDelta?: (delta: string) => void;
handleStep: (
calls: DriverToolCall[],
) => DriverStepOutcome | Promise<DriverStepOutcome>;
@@ -109,6 +110,7 @@ export function createLocalLlmDriver(llm: LlmProvider): AgentDriver {
];
const streamCallbacks: StreamCallbacks = {
onReasoningDelta: (delta) => input.onThinkingDelta?.(delta),
onContentDelta: (delta) => input.onOutputDelta?.(delta),
};
const label = input.label ?? "driver";
+23 -11
View File
@@ -108,6 +108,8 @@ import {
import { debugLog, labelAction, logStateChange, sessionSnap } from "../log.js";
import {
executeChance,
executeChanceBatch,
resolveChanceBatchRequest,
resolveChanceRequest,
} from "../skills/chance-tools.js";
import {
@@ -1412,21 +1414,31 @@ export class PhaseRuntime {
).session;
const boardRaw = this.blackboard.getContentByTag("运行.机会请求");
const request = resolveChanceRequest({
const batch = resolveChanceBatchRequest({
workerContext: effect.workerContext ?? null,
blackboardRequestJson: boardRaw,
});
const result = request
? executeChance(request)
: {
schema: "chance.v1" as const,
op: "roll" as const,
ok: false,
summary: "机遇失败:缺少请求(workerContext.chance 或 运行.机会请求)",
detail: {},
error: "missing_request",
};
const result = batch?.length
? batch.length === 1
? executeChance(batch[0]!)
: executeChanceBatch(batch)
: (() => {
const single = resolveChanceRequest({
workerContext: effect.workerContext ?? null,
blackboardRequestJson: boardRaw,
});
if (single) return executeChance(single);
return {
schema: "chance.v1" as const,
op: "roll" as const,
ok: false,
summary:
"机遇失败:缺少请求(workerContext.chance.requests 或 运行.机会请求)",
detail: {},
error: "missing_request",
};
})();
const content = JSON.stringify(result, null, 2);
const written = this.writeWorkerTagContent(