@tea-agent/loop-agent 0.33.6 → 0.33.7-beta.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +39 -23
  2. package/dist/application/task-lifecycle/advance.js +4 -254
  3. package/dist/application/task-lifecycle/gates.js +0 -50
  4. package/dist/application/task-lifecycle/observe.js +2 -11
  5. package/dist/commands/init-upgrade.js +1 -32
  6. package/dist/commands/init.js +3 -94
  7. package/dist/executors/shell-executor.js +91 -4
  8. package/dist/executors/shell-write-guard.js +8 -26
  9. package/dist/shared/operator/capabilities.js +42 -72
  10. package/dist/task/source-prepare/index.js +0 -2
  11. package/dist/task/source-prepare/parse-intent.js +10 -58
  12. package/dist/task/source-prepare/prepare.js +16 -180
  13. package/dist/task/source-prepare/reference-integrity.js +2 -18
  14. package/dist/worker/console/app-data.js +0 -2
  15. package/dist/worker/console/chat/chat-event-store.js +25 -190
  16. package/dist/worker/console/chat/instruction-skills.js +217 -0
  17. package/dist/worker/console/chat/pi-console-config.js +32 -250
  18. package/dist/worker/console/chat/pi-runtime.js +71 -625
  19. package/dist/worker/console/chat/resource-loader.js +4 -5
  20. package/dist/worker/console/chat/routes.js +146 -324
  21. package/dist/worker/console/chat/runtime-context.js +12 -48
  22. package/dist/worker/console/chat/runtime-selection.js +0 -59
  23. package/dist/worker/console/chat/shortcuts.js +0 -1
  24. package/dist/worker/console/chat/tool-adapter.js +3 -9
  25. package/dist/worker/console/chat/tools.js +1 -5
  26. package/dist/worker/console/operator-actions.js +68 -559
  27. package/dist/worker/console/server.js +15 -8
  28. package/dist/worker/console/static/assets/index-CnUXAqxG.css +1 -0
  29. package/dist/worker/console/static/assets/index-CteJFFL2.js +29 -0
  30. package/dist/worker/console/static/index.html +2 -2
  31. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +8 -45
  32. package/dist/worker/console/static-src/operator-chat/refs.js +0 -9
  33. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +0 -16
  34. package/dist/worker/console/static-src/operator-chat/useChatStream.js +184 -210
  35. package/dist/worker/console/static-src/operator-chat/useChatThread.js +5 -49
  36. package/dist/worker/console/static-src/operator-chat/useComposer.js +0 -17
  37. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +74 -225
  38. package/dist/worker/delivery/final-verification.js +5 -13
  39. package/dist/worker/delivery/package.js +19 -31
  40. package/dist/worker/delivery/verification-bundle.js +4 -6
  41. package/dist/worker/observe/static/operator-chrome.css +2 -5
  42. package/dist/worker/observe/static/operator-chrome.js +1 -6
  43. package/dist/worker/observe/static/styles.css +9 -39
  44. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +462 -33
  45. package/dist/workflows/dag/backend-test-case-manifest.js +4 -0
  46. package/dist/workflows/dag/backend-test-markdown-workflow.js +25 -1
  47. package/dist/workflows/dag/backend-test-module-stem.js +5 -0
  48. package/dist/workflows/dag/backend-test-pytest-collection.js +345 -24
  49. package/dist/workflows/dag/backend-test-scenario-param.js +552 -124
  50. package/dist/workflows/dag/backend-test-writer-completeness.js +47 -16
  51. package/dist/workflows/dag/dynamic-runtime/map.js +24 -8
  52. package/dist/workflows/dag/frontend-worktree-diff.js +27 -12
  53. package/dist/workflows/dag/init-hybrid.js +49 -37
  54. package/dist/workflows/dag/types.js +7 -0
  55. package/dist/workflows/dag/workspace-checkpoint.js +27 -8
  56. package/docs/templates/backend-test-dag.json +33 -30
  57. package/harness.json +1 -1
  58. package/package.json +1 -1
  59. package/skills/loop-agent/references/command-reference.md +1 -3
  60. package/skills/loop-agent/references/source-and-plan-practice.md +0 -13
  61. package/skills/loop-agent/references/task-workflow.md +0 -4
  62. package/dist/shared/resilient-git.js +0 -133
  63. package/dist/task/source-prepare/artifact-meta.js +0 -137
  64. package/dist/task/source-prepare/semantic-intake.js +0 -404
  65. package/dist/worker/console/dag-execution-receipt.js +0 -380
  66. package/dist/worker/console/static/assets/index-BUOLppPr.js +0 -28
  67. package/dist/worker/console/static/assets/index-C1KzazY5.css +0 -1
  68. package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +0 -257
  69. package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +0 -196
@@ -24,41 +24,9 @@ function fullText(text, max = RUNTIME_CONTEXT_TEXT_MAX) {
24
24
  return cleaned;
25
25
  return `${cleaned.slice(0, max)}\n\n…[truncated ${cleaned.length - max} chars for inspect UI]`;
26
26
  }
27
- /**
28
- * Secret-scrub + length-limit a runtime text (system prompt / resource paths)
29
- * before it leaves the server. Used by the runtime snapshot projection.
30
- */
31
- export function redactRuntimeText(text, max = RUNTIME_CONTEXT_TEXT_MAX) {
32
- if (!text)
33
- return "";
34
- const cleaned = redact(text);
35
- if (cleaned.length <= max)
36
- return cleaned;
37
- return `${cleaned.slice(0, max)}\n\n…[truncated ${cleaned.length - max} chars for inspect UI]`;
38
- }
39
27
  export function projectRuntimeContext(input) {
40
28
  const systemText = fullText(input.systemPrompt) ?? "";
41
29
  const suffixText = fullText(input.systemPromptSuffix);
42
- const projectResources = (resources) => (resources ?? []).map((resource) => ({
43
- name: redactRuntimeText(resource.name, 200),
44
- description: redactRuntimeText(resource.description, 600),
45
- path: redactRuntimeText(resource.path, 400),
46
- baseDir: resource.baseDir ? redactRuntimeText(resource.baseDir, 400) : undefined,
47
- scope: resource.scope,
48
- source: redactRuntimeText(resource.source, 200),
49
- enabled: resource.enabled,
50
- version: resource.version ? redactRuntimeText(resource.version, 80) : undefined,
51
- cwd: resource.cwd ? redactRuntimeText(resource.cwd, 400) : undefined,
52
- resolved: resource.resolved?.map((item) => ({
53
- type: item.type,
54
- name: redactRuntimeText(item.name, 200),
55
- path: redactRuntimeText(item.path, 400),
56
- source: redactRuntimeText(item.source, 200),
57
- scope: item.scope,
58
- })),
59
- error: resource.error ? redactRuntimeText(resource.error, 400) : undefined,
60
- diagnostics: (resource.diagnostics ?? []).map((diag) => redactRuntimeText(diag, 400)),
61
- }));
62
30
  return {
63
31
  readOnly: true,
64
32
  systemPrompt: {
@@ -67,26 +35,22 @@ export function projectRuntimeContext(input) {
67
35
  text: systemText,
68
36
  charCount: input.systemPrompt.length,
69
37
  },
38
+ skills: input.skills.map((skill) => ({
39
+ name: skill.name,
40
+ description: summary(skill.description, 200) ?? "",
41
+ charCount: skill.charCount,
42
+ ...(skill.bodyText
43
+ ? { body: fullText(skill.bodyText, 40_000) }
44
+ : {}),
45
+ })),
70
46
  resources: {
71
- mode: "open",
72
- noContextFiles: false,
73
- noSkills: false,
74
- noExtensions: false,
47
+ mode: "closed",
48
+ noContextFiles: true,
49
+ noSkills: true,
50
+ noExtensions: true,
75
51
  hasBash: true,
76
52
  activeToolCount: input.activeTools.length,
77
53
  activeTools: [...input.activeTools],
78
- contextFiles: (input.contextFiles ?? []).map((file) => ({
79
- path: redactRuntimeText(file.path, 400),
80
- characters: file.characters,
81
- })),
82
- skills: projectResources(input.skills),
83
- extensions: projectResources(input.extensions),
84
- packages: projectResources(input.packages),
85
- diagnostics: (input.diagnostics ?? []).map((diag) => ({
86
- type: diag.type,
87
- message: redactRuntimeText(diag.message, 400),
88
- ...(diag.path ? { path: redactRuntimeText(diag.path, 400) } : {}),
89
- })),
90
54
  },
91
55
  model: input.model,
92
56
  thinkingLevel: input.thinkingLevel,
@@ -7,65 +7,6 @@
7
7
  * in a plain Node environment (the React component owns the network race
8
8
  * guards; these helpers only define what "matches" and "merged" mean).
9
9
  */
10
- /** Human-readable thinking-level labels (auto is always the first option). */
11
- export const THINKING_LEVEL_LABELS = {
12
- auto: "auto(跟随 Pi 默认等级)",
13
- off: "off · 关闭",
14
- minimal: "minimal · 极简",
15
- low: "low · 低",
16
- medium: "medium · 中",
17
- high: "high · 高",
18
- xhigh: "xhigh · 极高",
19
- max: "max · 最高",
20
- };
21
- /**
22
- * Group (and optionally filter) models by provider, preserving the provider
23
- * order of first appearance and the model order within each provider.
24
- * The query matches provider id, model id and display name (case-insensitive).
25
- * Empty query returns all models grouped — never a fake "no models" list.
26
- */
27
- export function groupModelsByProvider(models, query) {
28
- const q = query.trim().toLowerCase();
29
- const groups = new Map();
30
- for (const model of models) {
31
- if (q &&
32
- !model.provider.toLowerCase().includes(q) &&
33
- !model.id.toLowerCase().includes(q) &&
34
- !(model.name ?? "").toLowerCase().includes(q)) {
35
- continue;
36
- }
37
- const list = groups.get(model.provider) ?? [];
38
- list.push(model);
39
- groups.set(model.provider, list);
40
- }
41
- return [...groups.entries()].map(([provider, models]) => ({
42
- provider,
43
- models,
44
- }));
45
- }
46
- /**
47
- * Build the thinking menu options: `auto` is always the first option, followed
48
- * by the runtime-supported levels in their canonical order. `effective` is the
49
- * Pi actual thinking level (shown as a badge on the auto entry when provided).
50
- */
51
- export function buildThinkingMenuOptions(levels, effective) {
52
- const seen = new Set();
53
- const options = [];
54
- const push = (value) => {
55
- if (seen.has(value))
56
- return;
57
- seen.add(value);
58
- options.push({
59
- value,
60
- label: THINKING_LEVEL_LABELS[value] ?? value,
61
- ...(value === "auto" && effective ? { effective } : {}),
62
- });
63
- };
64
- push("auto");
65
- for (const level of levels)
66
- push(level);
67
- return options;
68
- }
69
10
  /** Format a model reference for `<option value>` keys and equality checks. */
70
11
  export function formatModelRef(provider, modelId) {
71
12
  return `${provider}/${modelId}`;
@@ -3,7 +3,6 @@ export const SHORTCUTS = [
3
3
  { command: "/contract", label: "Contract", description: "查看 contract diff 与 apply gate", action: "focus-panel:contract" },
4
4
  { command: "/dag", label: "DAG", description: "查看 DAG spine、确认与运行状态", action: "focus-panel:dag" },
5
5
  { command: "/interview", label: "Interview", description: "打开 Requirement Interview", action: "focus:interview" },
6
- { command: "/reload", label: "Reload session", description: "重新加载当前 Pi 会话的设置、扩展、技能、提示词、主题与上下文文件(不产生消息)", action: "reload" },
7
6
  { command: "/help", label: "Shortcuts", description: "显示可用 shortcut", action: "show-help" },
8
7
  ];
9
8
  /** Pure navigation/display resolver. It deliberately has no mutation decisions. */
@@ -9,12 +9,10 @@
9
9
  *
10
10
  * High-risk / long-running actions ARE mapped as tools (2026-07-25 widening),
11
11
  * but the registry now declares their modelCallable policy:
12
- * - "always": model can invoke; dispatch runs server-side (2026-08-11:
13
- * runDag/dagRerun/standaloneTaskRerun/workerTaskRetry are autonomous —
14
- * runDag consumes a server-issued single-use execution receipt, and the
15
- * recovery actions pass server-side read-only run-facts checks).
12
+ * - "always": model can invoke; dispatch runs server-side.
16
13
  * - "prepare-only": model can invoke but the mutation needs a human-origin
17
- * confirmation (Night Scheduler mutation-gate faces).
14
+ * confirmation (e.g. runDag needs a confirmationId consumed by a human
15
+ * confirm via the browser mutation gate — M0-B).
18
16
  * - "never": the action is the human confirmation itself (confirmDagConfirmation)
19
17
  * and MUST NOT appear as a model-callable tool (M0-B / roadmap G03).
20
18
  *
@@ -32,10 +30,6 @@ import { buildOperatorCapabilitiesDocument } from "../../../shared/operator/capa
32
30
  * prepare helpers (prepareDagConfirmation / prepareMutationGate); the browser
33
31
  * mutation gate + HMAC token perform the consuming dispatch.
34
32
  *
35
- * 2026-08-11: runDag / dagRerun / standaloneTaskRerun / workerTaskRetry are no
36
- * longer gate-only (autonomous execution + run-facts checks) and drop out of
37
- * this derived list automatically.
38
- *
39
33
  * `contractApply` is also gate-only even though its registry face remains
40
34
  * `humanConfirmation: "conditional"` (assessment soft-gate for workspace UI);
41
35
  * Chat executes it only via the contract-apply Human Gate route.
@@ -4,14 +4,10 @@
4
4
  * Operator Chat registers and activates full Pi builtins
5
5
  * (read/write/edit/bash/grep/find/ls) plus model-callable operator actions and
6
6
  * optional safe-* explore custom tools. Discipline is primarily soft
7
- * (system prompt: prefer DAG paths). Hard denies remain for non-Pi
7
+ * (system prompt: prefer DAG / Human Gate). Hard denies remain for non-Pi
8
8
  * write channels (apply_patch / full-tools / shell / coding-chat) and for
9
9
  * modelCallable="never" actions (e.g. confirmDagConfirmation).
10
10
  *
11
- * 2026-08-11: runDag / dagRerun / standaloneTaskRerun / workerTaskRetry are
12
- * model-callable (autonomous DAG execution); the browser Human Gate still
13
- * covers Night Scheduler mutations, contractApply and confirmDagConfirmation.
14
- *
15
11
  * Interview / Official surfaces keep their own OFFICIAL_DENIED path; this
16
12
  * module only filters Chat-side denial so Interview is not widened.
17
13
  */