@tea-agent/loop-agent 0.35.1-beta.4 → 0.35.2

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.
Files changed (63) hide show
  1. package/AGENTS.md +0 -2
  2. package/CHANGELOG.md +43 -26
  3. package/bin/loop-agent.js +1 -37
  4. package/dist/application/dag/generate-task-dag.js +4 -1
  5. package/dist/application/task-lifecycle/advance.js +14 -0
  6. package/dist/cli/program.js +2 -2
  7. package/dist/commands/task-advance.js +1 -0
  8. package/dist/executors/dag-pi-executor.js +0 -44
  9. package/dist/shared/package-metadata.js +0 -42
  10. package/dist/task/config-types.js +2 -0
  11. package/dist/task/contract/project.js +3 -0
  12. package/dist/task/contract/schema.js +1 -0
  13. package/dist/task/source-prepare/build-draft.js +7 -0
  14. package/dist/task/source-prepare/semantic-intake.js +37 -10
  15. package/dist/task/task-demand-routing.js +10 -0
  16. package/dist/worker/console/chat/assistant-content.js +110 -0
  17. package/dist/worker/console/chat/pi-runtime.js +13 -32
  18. package/dist/worker/console/chat/routes.js +9 -4
  19. package/dist/worker/console/chat/session-store.js +3 -0
  20. package/dist/worker/console/chat/shortcuts.js +9 -7
  21. package/dist/worker/console/chat/turn-process.js +62 -15
  22. package/dist/worker/console/operator-actions.js +72 -6
  23. package/dist/worker/console/prd-intake-bridge.js +10 -3
  24. package/dist/worker/console/prd-reference-discovery.js +124 -0
  25. package/dist/worker/console/static/assets/index-DRqZiQ7J.css +1 -0
  26. package/dist/worker/console/static/assets/index-gVHrlqI9.js +56 -0
  27. package/dist/worker/console/static/index.html +2 -2
  28. package/dist/worker/console/static-src/app/useOperatorActions.js +19 -1
  29. package/dist/worker/console/static-src/app/useRecoveryConsole.js +0 -5
  30. package/dist/worker/console/static-src/app/useTaskWizard.js +12 -0
  31. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +10 -1
  32. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +11 -6
  33. package/dist/worker/console/static-src/operator-chat/useChatThread.js +11 -6
  34. package/dist/worker/console/static-src/operator-chat/useComposer.js +15 -1
  35. package/dist/worker/loop-agent/loop-agent-client.js +3 -17
  36. package/dist/worker/observability/read-model.js +0 -20
  37. package/dist/worker/observe/spec-evidence.js +8 -3
  38. package/dist/worker/observe/static/views/dag-inspector.js +71 -6
  39. package/dist/worker/preflight.js +1 -2
  40. package/dist/workflows/dag/backend-test-scenario-param.js +23 -33
  41. package/dist/workflows/dag/dynamic-runtime/shared.js +1 -9
  42. package/dist/workflows/dag/frontend-implementation-contract.js +39 -233
  43. package/dist/workflows/dag/frontend-prewrite-gate.js +61 -364
  44. package/dist/workflows/dag/frontend-repair.js +18 -219
  45. package/dist/workflows/dag/frontend-verification-trace.js +32 -47
  46. package/dist/workflows/dag/init-hybrid.js +26 -49
  47. package/dist/workflows/dag/node-execution.js +0 -89
  48. package/dist/workflows/dag/recovery-recommendation.js +0 -58
  49. package/dist/workflows/dag/runner.js +11 -245
  50. package/dist/workflows/dag/scheduler.js +3 -257
  51. package/dist/workflows/dag/types.js +2 -130
  52. package/harness.json +1 -1
  53. package/package.json +2 -2
  54. package/dist/build-stamp.json +0 -6
  55. package/dist/worker/console/static/assets/index-CvsQgALl.js +0 -56
  56. package/dist/worker/console/static/assets/index-hJqCPs_g.css +0 -1
  57. package/dist/workflows/dag/contract-output-registry.js +0 -14
  58. package/dist/workflows/dag/contract-validator-registrations.js +0 -8
  59. package/dist/workflows/dag/frontend-recovery-plan.js +0 -73
  60. package/dist/workflows/dag/frontend-recovery-root-manifest.js +0 -123
  61. package/dist/workflows/dag/frontend-recovery-run.js +0 -539
  62. package/dist/workflows/dag/frontend-writer-recovery.js +0 -106
  63. package/dist/workflows/dag/frontend-writer-rollback.js +0 -821
@@ -1,10 +1,5 @@
1
- import { readFile } from "node:fs/promises";
2
- import path from "node:path";
3
1
  import { isPauseOnHumanDecisionGate } from "./decision-envelope.js";
4
2
  import { evaluateConditionExpression } from "./dynamic-runtime/condition.js";
5
- import { sha256Hex } from "./frontend-implementation-contract.js";
6
- import { frontendPrewriteResultV1Schema, FRONTEND_PREWRITE_RESULT_ARTIFACT_NAME, } from "./frontend-prewrite-gate.js";
7
- import { FRONTEND_RECOVERY_IMPORT_MANIFEST_REL_PATH, FRONTEND_RECOVERY_INTENT_REL_DIR, } from "./frontend-recovery-plan.js";
8
3
  export function isConditionSkippedReason(reason) {
9
4
  return Boolean(reason?.startsWith("condition "));
10
5
  }
@@ -109,58 +104,6 @@ async function mapConcurrent(items, limit, fn) {
109
104
  }
110
105
  await Promise.all(executing);
111
106
  }
112
- export const FRONTEND_WRITER_NODE_IDS = [
113
- "frontend-implement-pi",
114
- "frontend-repair-pi",
115
- ];
116
- /** Run-relative artifact location written by the prewrite gate generator. */
117
- export const FRONTEND_PREWRITE_RESULT_SOURCE_ARTIFACT = path.posix.join("contracts", FRONTEND_PREWRITE_RESULT_ARTIFACT_NAME);
118
- /**
119
- * Read and validate the frontend-prewrite-result-v1 artifact. Fail-closed:
120
- * a missing file or invalid payload returns ok:false and never throws.
121
- */
122
- export async function readFrontendPrewriteResult(runDir) {
123
- const artifactPath = path.join(runDir, "contracts", FRONTEND_PREWRITE_RESULT_ARTIFACT_NAME);
124
- let raw;
125
- try {
126
- raw = await readFile(artifactPath, "utf8");
127
- }
128
- catch (error) {
129
- if (error.code === "ENOENT") {
130
- return {
131
- ok: false,
132
- reason: `frontend prewrite result artifact missing: ${artifactPath}`,
133
- };
134
- }
135
- throw error;
136
- }
137
- const artifactHash = sha256Hex(raw);
138
- let parsed;
139
- try {
140
- parsed = JSON.parse(raw);
141
- }
142
- catch (error) {
143
- return {
144
- ok: false,
145
- reason: `frontend prewrite result artifact is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
146
- };
147
- }
148
- const result = frontendPrewriteResultV1Schema.safeParse(parsed);
149
- if (!result.success) {
150
- return {
151
- ok: false,
152
- reason: "frontend prewrite result artifact failed schema validation",
153
- };
154
- }
155
- return { ok: true, result: result.data, artifactHash };
156
- }
157
- /** Authorize only accepted / accepted-normalized classifications. */
158
- export function isFrontendWriterAuthorized(result) {
159
- return result.classification === "accepted" ||
160
- result.classification === "accepted-normalized"
161
- ? "authorized"
162
- : "denied";
163
- }
164
107
  /** Fail-closed: leave no PENDING nodes that look "still scheduled" after abort. */
165
108
  export function markPendingNodesControllerInterrupted(state, reason = "run aborted by controller (abortSignal)") {
166
109
  const affected = [];
@@ -179,166 +122,8 @@ export function markPendingNodesControllerInterrupted(state, reason = "run abort
179
122
  }
180
123
  return affected;
181
124
  }
182
- /**
183
- * True when this run is a candidate-continuation child: it has a recovery
184
- * lineage whose attemptIndex is >= 1 and whose recovery root is another run.
185
- * The root/parent keeps `recoveryRootRunId === state.runId`.
186
- */
187
- export function isFrontendRecoveryChild(state) {
188
- const recovery = state.frontendRecoveryState;
189
- return Boolean(recovery &&
190
- recovery.attemptIndex >= 1 &&
191
- recovery.recoveryRootRunId !== state.runId);
192
- }
193
- function isValidFrontendRecoveryActivationMarker(raw) {
194
- return (raw.schemaVersion === 1 &&
195
- typeof raw.requestId === "string" &&
196
- raw.requestId.length > 0 &&
197
- typeof raw.parentRunId === "string" &&
198
- raw.parentRunId.length > 0 &&
199
- typeof raw.recoveryRootRunId === "string" &&
200
- raw.recoveryRootRunId.length > 0 &&
201
- typeof raw.childRunId === "string" &&
202
- raw.childRunId.length > 0 &&
203
- typeof raw.importManifestSha256 === "string" &&
204
- /^[a-f0-9]{64}$/.test(raw.importManifestSha256));
205
- }
206
- /**
207
- * Activation marker gate (phase 3c AC-1). Fail-closed: an active child is only
208
- * executable when its parent is `child-running`, points at this child, carries
209
- * a structurally valid activation marker whose lineage matches, and the marker
210
- * hash matches the child's import manifest. Read-only and never throws.
211
- */
212
- export async function checkFrontendRecoveryActivation(state, childRunDir) {
213
- if (!isFrontendRecoveryChild(state)) {
214
- return { applicable: false };
215
- }
216
- const recovery = state.frontendRecoveryState;
217
- const parentRunId = recovery.parentRunId;
218
- const parentRunDir = path.join(path.dirname(childRunDir), parentRunId);
219
- let parentState;
220
- try {
221
- parentState = JSON.parse(await readFile(path.join(parentRunDir, "state.json"), "utf8"));
222
- }
223
- catch {
224
- return { applicable: true, ok: false, reason: "parent state unreadable" };
225
- }
226
- const parentRecovery = parentState.frontendRecoveryState;
227
- if (parentRecovery?.phase !== "child-running") {
228
- return {
229
- applicable: true,
230
- ok: false,
231
- reason: "parent phase not child-running",
232
- };
233
- }
234
- if (parentRecovery.childRunId !== state.runId) {
235
- return {
236
- applicable: true,
237
- ok: false,
238
- reason: "parent childRunId mismatch",
239
- };
240
- }
241
- const markerPath = path.join(parentRunDir, FRONTEND_RECOVERY_INTENT_REL_DIR, `${recovery.requestId}.json`);
242
- let markerRaw;
243
- try {
244
- markerRaw = JSON.parse(await readFile(markerPath, "utf8"));
245
- }
246
- catch {
247
- return {
248
- applicable: true,
249
- ok: false,
250
- reason: "activation marker missing",
251
- };
252
- }
253
- if (typeof markerRaw !== "object" ||
254
- markerRaw === null ||
255
- !isValidFrontendRecoveryActivationMarker(markerRaw)) {
256
- return {
257
- applicable: true,
258
- ok: false,
259
- reason: "activation marker invalid",
260
- };
261
- }
262
- const marker = markerRaw;
263
- if (marker.requestId !== recovery.requestId) {
264
- return {
265
- applicable: true,
266
- ok: false,
267
- reason: "marker requestId mismatch",
268
- };
269
- }
270
- if (marker.parentRunId !== parentRunId) {
271
- return {
272
- applicable: true,
273
- ok: false,
274
- reason: "marker parentRunId mismatch",
275
- };
276
- }
277
- if (marker.recoveryRootRunId !== recovery.recoveryRootRunId) {
278
- return {
279
- applicable: true,
280
- ok: false,
281
- reason: "marker recoveryRootRunId mismatch",
282
- };
283
- }
284
- if (marker.childRunId !== state.runId) {
285
- return {
286
- applicable: true,
287
- ok: false,
288
- reason: "marker childRunId mismatch",
289
- };
290
- }
291
- let manifestSha256;
292
- try {
293
- manifestSha256 = sha256Hex(await readFile(path.join(childRunDir, FRONTEND_RECOVERY_IMPORT_MANIFEST_REL_PATH), "utf8"));
294
- }
295
- catch {
296
- return {
297
- applicable: true,
298
- ok: false,
299
- reason: "import manifest unreadable",
300
- };
301
- }
302
- if (manifestSha256 !== marker.importManifestSha256) {
303
- return {
304
- applicable: true,
305
- ok: false,
306
- reason: "import manifest sha256 mismatch",
307
- };
308
- }
309
- return {
310
- applicable: true,
311
- ok: true,
312
- requestId: recovery.requestId,
313
- childRunId: state.runId,
314
- };
315
- }
316
125
  export async function executeDagRanksOnce(input) {
317
126
  let pausedByNodeId;
318
- // Activation marker gate (phase 3c AC-1): a recovery child without a valid
319
- // activation marker must never be scheduled or executed. Fail-closed before
320
- // any executeScheduledNode call, so zero writer/provider invocations happen.
321
- if (input.runDir) {
322
- const hasPending = Object.values(input.state.nodes).some((node) => node.status === "PENDING");
323
- if (hasPending) {
324
- const activation = await checkFrontendRecoveryActivation(input.state, input.runDir);
325
- if (activation.applicable && !activation.ok) {
326
- const finishedAt = new Date().toISOString();
327
- let affected = 0;
328
- for (const node of Object.values(input.state.nodes)) {
329
- if (node.status !== "PENDING")
330
- continue;
331
- node.status = "SKIPPED";
332
- node.skippedReason = "frontend-recovery-child-not-activated";
333
- node.finishedAt = finishedAt;
334
- affected += 1;
335
- }
336
- if (affected > 0)
337
- await input.persistState();
338
- return undefined;
339
- }
340
- }
341
- }
342
127
  for (const rank of input.ranks) {
343
128
  if (input.abortSignal?.aborted) {
344
129
  const marked = markPendingNodesControllerInterrupted(input.state, input.abortSignal.reason
@@ -383,45 +168,6 @@ export async function executeDagRanksOnce(input) {
383
168
  await input.persistState();
384
169
  const conditionSkippedSet = new Set(conditionSettled);
385
170
  const actuallyRunnable = runnable.filter((id) => !conditionSkippedSet.has(id));
386
- const frontendAdmissionSettled = [];
387
- if (input.runDir) {
388
- for (const id of actuallyRunnable) {
389
- if (!FRONTEND_WRITER_NODE_IDS.includes(id))
390
- continue;
391
- const node = input.state.nodes[id];
392
- const checkedAt = new Date().toISOString();
393
- const admission = await readFrontendPrewriteResult(input.runDir);
394
- if (!admission.ok) {
395
- node.status = "SKIPPED";
396
- node.skippedReason = "frontend-prewrite-not-authorized";
397
- node.finishedAt = checkedAt;
398
- frontendAdmissionSettled.push(id);
399
- continue;
400
- }
401
- const decision = isFrontendWriterAuthorized(admission.result);
402
- node.frontendWriterAdmission = {
403
- schemaVersion: 1,
404
- writerNodeId: id,
405
- decision,
406
- sourceArtifact: FRONTEND_PREWRITE_RESULT_SOURCE_ARTIFACT,
407
- artifactHash: admission.artifactHash,
408
- checkedAt,
409
- reason: decision === "denied"
410
- ? `classification: ${admission.result.classification}`
411
- : null,
412
- };
413
- if (decision === "denied") {
414
- node.status = "SKIPPED";
415
- node.skippedReason = "frontend-prewrite-not-authorized";
416
- node.finishedAt = checkedAt;
417
- frontendAdmissionSettled.push(id);
418
- }
419
- }
420
- if (frontendAdmissionSettled.length > 0)
421
- await input.persistState();
422
- }
423
- const frontendAdmissionSkippedSet = new Set(frontendAdmissionSettled);
424
- const runnableAfterAdmission = actuallyRunnable.filter((id) => !frontendAdmissionSkippedSet.has(id));
425
171
  const blocked = pending.filter((id) => {
426
172
  const task = input.tasksById.get(id);
427
173
  return (dependencyReadiness(task, input.state.nodes, input.tasksById) === "skip");
@@ -436,12 +182,12 @@ export async function executeDagRanksOnce(input) {
436
182
  if (blocked.length > 0) {
437
183
  await input.persistState();
438
184
  }
439
- const pauseGateRunnable = runnableAfterAdmission.filter((id) => {
185
+ const pauseGateRunnable = actuallyRunnable.filter((id) => {
440
186
  const task = input.tasksById.get(id);
441
187
  return isPauseOnHumanDecisionGate(task);
442
188
  });
443
- const regularRunnable = runnableAfterAdmission.filter((id) => !pauseGateRunnable.includes(id));
444
- const rankWriterNodeIds = runnableAfterAdmission.filter((id) => {
189
+ const regularRunnable = actuallyRunnable.filter((id) => !pauseGateRunnable.includes(id));
190
+ const rankWriterNodeIds = actuallyRunnable.filter((id) => {
445
191
  const task = input.tasksById.get(id);
446
192
  return (task?.executor === "pi" &&
447
193
  task.toolProfile === "write" &&
@@ -654,15 +654,8 @@ export const dagConvergenceSpecSchema = z
654
654
  chainNodeIds: z.array(z.string()).optional(),
655
655
  })
656
656
  .optional();
657
- /**
658
- * Schema ids that may opt a node into producing-node structured contract
659
- * self-validation. Validators are registered in the contract output registry
660
- * (src/workflows/dag/contract-output-registry.ts).
661
- */
662
- export const structuredContractOutputSchemaIds = [
663
- "frontend-implementation-contract-v1",
664
- ];
665
- export const dagTaskSchema = z.object({ id: z.string().regex(/^[a-z][a-z0-9-]*$/, "task id must be kebab-case"),
657
+ export const dagTaskSchema = z.object({
658
+ id: z.string().regex(/^[a-z][a-z0-9-]*$/, "task id must be kebab-case"),
666
659
  depends_on: z.array(z.string()).default([]),
667
660
  /**
668
661
  * How SKIPPED upstreams affect readiness.
@@ -711,20 +704,6 @@ export const dagTaskSchema = z.object({ id: z.string().regex(/^[a-z][a-z0-9-]*$/
711
704
  * on safe read-only Pi nodes before the node becomes ERROR.
712
705
  */
713
706
  outputProtocol: dagOutputProtocolSchema.optional(),
714
- /**
715
- * Node-level structured contract self-check: after the Pi output is
716
- * produced, validate it against the named contract schema at the node so
717
- * schema/typo/null violations become invalid-output (retryable on the node)
718
- * instead of failing later at a downstream deterministic gate. Validators
719
- * are resolved via the contract output registry keyed by schemaId.
720
- */
721
- structuredContractOutput: z
722
- .object({
723
- schemaId: z.enum(structuredContractOutputSchemaIds),
724
- retryOnInvalid: z.boolean().default(true),
725
- })
726
- .strict()
727
- .optional(),
728
707
  /**
729
708
  * Fail-closed outcome/diff consistency contract for bounded Pi writers.
730
709
  * The writer must begin with IMPLEMENTATION_OUTCOME: changed,
@@ -895,113 +874,6 @@ export const dagSpecSchema = z
895
874
  });
896
875
  }
897
876
  });
898
- export const FRONTEND_RECOVERY_STATE_SCHEMA_VERSION = 1;
899
- export const FRONTEND_RECOVERY_RESULT_SCHEMA_VERSION = 1;
900
- /**
901
- * Frontend candidate-continuation recovery phase (decision B, phase-3 subset).
902
- * Phase 3a parents converge first, so `rollback-pending` is not produced and
903
- * was removed by AC-1; the phase starts at `child-staging` and ends at
904
- * `settled`.
905
- */
906
- export const frontendRecoveryPhaseSchema = z.enum([
907
- "child-staging",
908
- "child-activating",
909
- "child-running",
910
- "settled",
911
- ]);
912
- /**
913
- * Single-writer recovery intent/lineage stored on `DagRunState`. The parent run
914
- * owns the authoritative copy and advances it via revision-guarded CAS writes;
915
- * the child carries a frozen lineage snapshot so the activation gate can prove
916
- * it is the reserved child of a child-running parent.
917
- *
918
- * Invariants: `attemptIndex ∈ {0,1}`; `continuationCount ∈ {0,1}`; a child's
919
- * `recoveryRootRunId` always equals the root runId; `revision` is the CAS
920
- * pre-comparison counter. `revision` monotonicity is enforced at runtime by the
921
- * runner's `(existing?.revision ?? 0) + 1` CAS write (the schema only bounds it
922
- * non-negative). `childRunId` may be absent through `child-activating` and must
923
- * be non-empty from `child-running` onward.
924
- */
925
- export const frontendRecoveryStateSchema = z
926
- .object({
927
- schemaVersion: z.literal(FRONTEND_RECOVERY_STATE_SCHEMA_VERSION),
928
- phase: frontendRecoveryPhaseSchema,
929
- requestId: z.string().min(1),
930
- recoveryRootRunId: z.string().min(1),
931
- parentRunId: z.string().min(1),
932
- childRunId: z.string().min(1).optional(),
933
- attemptId: z.string().min(1),
934
- attemptIndex: z.number().int().min(0).max(1),
935
- continuationCount: z.number().int().min(0).max(1),
936
- /** Node id of the reset-closure root: frontend-plan-pi /
937
- * frontend-plan-revision-pi / frontend-prewrite-gate-shell /
938
- * frontend-implement-pi (writer partial write). */
939
- failureSource: z.string().min(1).optional(),
940
- revision: z.number().int().nonnegative(),
941
- })
942
- .strict()
943
- .superRefine((value, ctx) => {
944
- const requiresChild = value.phase === "child-running" || value.phase === "settled";
945
- if (requiresChild && !value.childRunId) {
946
- ctx.addIssue({
947
- code: z.ZodIssueCode.custom,
948
- message: `phase ${value.phase} requires a non-empty childRunId`,
949
- path: ["childRunId"],
950
- });
951
- }
952
- });
953
- export const frontendRecoveryOutcomeSchema = z.enum([
954
- "none",
955
- "recovered",
956
- "candidate-contract-invalid",
957
- "prewrite-blocked",
958
- "repair-exhausted",
959
- "auto-recovery-blocked",
960
- ]);
961
- export const frontendRecoveryOriginSchema = z
962
- .object({
963
- kind: z.enum(["frontend-prewrite-gate", "frontend-writer"]),
964
- parentRunId: z.string().min(1),
965
- childRunId: z.string().min(1).optional(),
966
- requestId: z.string().min(1),
967
- failedNodeId: z.string(),
968
- })
969
- .strict();
970
- export const frontendRecoveryFailureClassSchema = z
971
- .object({
972
- code: z.enum([
973
- "candidate-contract-invalid",
974
- "prewrite-blocked",
975
- "staging-failed",
976
- "writer-transient-partial-write",
977
- ]),
978
- classification: z.string(),
979
- reason: z.string(),
980
- })
981
- .strict();
982
- export const frontendRecoveryEvidenceRefSchema = z
983
- .object({
984
- runId: z.string().min(1),
985
- relativePath: z.string().min(1),
986
- sha256: z.string().min(1),
987
- })
988
- .strict();
989
- /**
990
- * Terminal frontend recovery result. `failureClass` is absent for `none`,
991
- * `recovered` and `auto-recovery-blocked` outcomes. The schema intentionally
992
- * stays permissive (failureClass optional, evidenceRefs may be empty) so it
993
- * accepts the runner's actual phase-3a products, which do not always carry a
994
- * failure class or evidence reference.
995
- */
996
- export const frontendRecoveryResultSchema = z
997
- .object({
998
- schemaVersion: z.literal(FRONTEND_RECOVERY_RESULT_SCHEMA_VERSION),
999
- outcome: frontendRecoveryOutcomeSchema,
1000
- origin: frontendRecoveryOriginSchema,
1001
- failureClass: frontendRecoveryFailureClassSchema.optional(),
1002
- evidenceRefs: z.array(frontendRecoveryEvidenceRefSchema),
1003
- })
1004
- .strict();
1005
877
  export const DEFAULT_DAG_EXECUTOR_MODELS = {
1006
878
  pi: {
1007
879
  LOW: "gpt-5.3-codex-spark",
package/harness.json CHANGED
@@ -81,7 +81,7 @@
81
81
  "pi": {
82
82
  "description": "Pi 负责规划、评审、诊断;当 DAG toolProfile=write 时也可做有界写入。模型按复杂度三档配置,格式为 provider/model 字符串(例:wizard-local/grok-4.5);斜杠前为 Pi provider,后为 modelId,勿只写裸 modelId。",
83
83
  "LOW": "wizard-local/minimax-m3",
84
- "MED": "wizard-local/grok-4.5",
84
+ "MED": "wizard-local/glm-5.3",
85
85
  "HIGH": "wizard-local/gpt-5.6-sol"
86
86
  }
87
87
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tea-agent/loop-agent",
3
- "version": "0.35.1-beta.4",
3
+ "version": "0.35.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "loop-agent": "bin/loop-agent.js",
@@ -45,7 +45,7 @@
45
45
  "pi-prompt": "node --import tsx/esm src/cli.ts pi-prompt",
46
46
  "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
47
47
  "brand:sync": "node scripts/sync-brand-assets.mjs",
48
- "build": "npm run brand:sync && npm run clean && tsc -p tsconfig.build.json && node -e \"const fs=require('node:fs');const p='dist/worker/observe/static';fs.mkdirSync(p,{recursive:true});fs.cpSync('src/worker/observe/static',p,{recursive:true});\" && npm run console:build && node scripts/write-build-stamp.mjs",
48
+ "build": "npm run brand:sync && npm run clean && tsc -p tsconfig.build.json && node -e \"const fs=require('node:fs');const p='dist/worker/observe/static';fs.mkdirSync(p,{recursive:true});fs.cpSync('src/worker/observe/static',p,{recursive:true});\" && npm run console:build",
49
49
  "console:typecheck": "tsc -p src/worker/console/tsconfig.json",
50
50
  "console:build": "npm run console:typecheck && vite build --config src/worker/console/vite.config.ts",
51
51
  "prepack": "npm run build",
@@ -1,6 +0,0 @@
1
- {
2
- "schemaVersion": 1,
3
- "version": "0.35.1-beta.4",
4
- "gitSha": "69b11bb0e8eaced9b52c7554afe7268aef97e75f",
5
- "builtAt": "2026-08-15T04:54:32.880Z"
6
- }