@tea-agent/loop-agent 0.34.2 → 0.34.4
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/AGENTS.md +7 -2
- package/CHANGELOG.md +65 -22
- package/dist/application/task-lifecycle/advance.js +5 -1
- package/dist/task/source-prepare/index.js +1 -0
- package/dist/task/source-prepare/placeholder-paths.js +77 -0
- package/dist/task/source-prepare/semantic-intake.js +192 -27
- package/dist/worker/console/app-data.js +2 -0
- package/dist/worker/console/chat/chat-event-store.js +85 -3
- package/dist/worker/console/chat/pi-runtime.js +230 -62
- package/dist/worker/console/chat/resource-preferences-store.js +152 -0
- package/dist/worker/console/chat/routes.js +401 -18
- package/dist/worker/console/chat/turn-execution-registry.js +82 -0
- package/dist/worker/console/dag-execution-receipt.js +14 -1
- package/dist/worker/console/prd-intake-bridge.js +51 -10
- package/dist/worker/console/server.js +4 -0
- package/dist/worker/console/static/assets/index-B6Qdbk8V.js +29 -0
- package/dist/worker/console/static/assets/index-Bt0NUxcQ.css +1 -0
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/refs.js +24 -0
- package/dist/worker/console/static-src/operator-chat/resource-auto-invocation.js +91 -0
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +690 -0
- package/dist/worker/console/static-src/operator-chat/turn-submission.js +158 -0
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +535 -86
- package/dist/workflows/dag/init-hybrid.js +2 -0
- package/docs/operations/local-development-environment.md +4 -2
- package/docs/templates/branch-merge-report.md +9 -0
- package/package.json +3 -2
- package/dist/worker/console/static/assets/index-BQkhJpV8.css +0 -1
- package/dist/worker/console/static/assets/index-BpuHmlSP.js +0 -29
|
@@ -8,6 +8,7 @@ import path from "node:path";
|
|
|
8
8
|
import { getTaskPaths } from "../../task/runtime.js";
|
|
9
9
|
import { SEMANTIC_INTAKE_ARTIFACT_REL, } from "../../task/source-prepare/semantic-intake.js";
|
|
10
10
|
import { extractRequirementFactsFromMarkdown } from "../../task/source-prepare/parse-intent.js";
|
|
11
|
+
import { filterPlaceholderPaths, isNonPlaceholderPath, } from "../../task/source-prepare/placeholder-paths.js";
|
|
11
12
|
import { emptyDraft } from "./interview/grill-me.js";
|
|
12
13
|
import { normalizeConsoleWorkflowKind } from "./workflow-kinds.js";
|
|
13
14
|
function asStringList(value) {
|
|
@@ -105,13 +106,13 @@ export function parseEngineeringBoundaryFromParams(p) {
|
|
|
105
106
|
if (Array.isArray(value)) {
|
|
106
107
|
return value
|
|
107
108
|
.map((item) => (typeof item === "string" ? item.trim() : ""))
|
|
108
|
-
.filter(
|
|
109
|
+
.filter(isNonPlaceholderPath);
|
|
109
110
|
}
|
|
110
111
|
if (typeof value === "string") {
|
|
111
112
|
return value
|
|
112
113
|
.split(/[\n,;,;]+/)
|
|
113
114
|
.map((s) => s.trim())
|
|
114
|
-
.filter(
|
|
115
|
+
.filter(isNonPlaceholderPath);
|
|
115
116
|
}
|
|
116
117
|
return [];
|
|
117
118
|
};
|
|
@@ -176,10 +177,10 @@ export function parseEngineeringBoundaryFromParams(p) {
|
|
|
176
177
|
};
|
|
177
178
|
}
|
|
178
179
|
export function appendEngineeringCliArgs(args, boundary) {
|
|
179
|
-
for (const pathGlob of boundary.allowedPaths
|
|
180
|
+
for (const pathGlob of filterPlaceholderPaths(boundary.allowedPaths)) {
|
|
180
181
|
args.push("--allowed-path", pathGlob);
|
|
181
182
|
}
|
|
182
|
-
for (const pathGlob of boundary.forbiddenPaths
|
|
183
|
+
for (const pathGlob of filterPlaceholderPaths(boundary.forbiddenPaths)) {
|
|
183
184
|
args.push("--forbidden-path", pathGlob);
|
|
184
185
|
}
|
|
185
186
|
for (const cmd of boundary.verifyCommands ?? []) {
|
|
@@ -187,8 +188,10 @@ export function appendEngineeringCliArgs(args, boundary) {
|
|
|
187
188
|
}
|
|
188
189
|
}
|
|
189
190
|
export function applyEngineeringBoundaryToDraft(draft, boundary) {
|
|
190
|
-
|
|
191
|
-
|
|
191
|
+
const allowedPaths = filterPlaceholderPaths(boundary.allowedPaths);
|
|
192
|
+
const forbiddenPaths = filterPlaceholderPaths(boundary.forbiddenPaths);
|
|
193
|
+
if (allowedPaths.length === 0 &&
|
|
194
|
+
forbiddenPaths.length === 0 &&
|
|
192
195
|
!(boundary.verifyCommands?.length)) {
|
|
193
196
|
return draft;
|
|
194
197
|
}
|
|
@@ -196,11 +199,11 @@ export function applyEngineeringBoundaryToDraft(draft, boundary) {
|
|
|
196
199
|
...draft,
|
|
197
200
|
constraints: {
|
|
198
201
|
invariants: draft.constraints?.invariants ?? [],
|
|
199
|
-
allowedPaths:
|
|
200
|
-
?
|
|
202
|
+
allowedPaths: allowedPaths.length > 0
|
|
203
|
+
? allowedPaths
|
|
201
204
|
: (draft.constraints?.allowedPaths ?? []),
|
|
202
|
-
forbiddenPaths:
|
|
203
|
-
?
|
|
205
|
+
forbiddenPaths: forbiddenPaths.length > 0
|
|
206
|
+
? forbiddenPaths
|
|
204
207
|
: (draft.constraints?.forbiddenPaths ?? []),
|
|
205
208
|
},
|
|
206
209
|
verification: {
|
|
@@ -253,15 +256,53 @@ export async function buildDraftFromTaskIntake(input) {
|
|
|
253
256
|
const title = artifact?.draft?.title?.trim() ||
|
|
254
257
|
artifact?.semantic?.title?.trim() ||
|
|
255
258
|
input.title;
|
|
259
|
+
// Preserve semantic engineering boundary (paths/verify/taskKind) so the
|
|
260
|
+
// Console draft does not fall back to interview defaults and overwrite
|
|
261
|
+
// TX1 precise values on contractApply --from-draft.
|
|
262
|
+
const semDraftConstraints = artifact?.draft?.constraints;
|
|
263
|
+
const semDraftVerification = artifact?.draft?.verification;
|
|
264
|
+
const semTaskKind = artifact?.draft?.taskKind?.trim();
|
|
265
|
+
const mergedAllowed = filterPlaceholderPaths(semDraftConstraints?.allowedPaths);
|
|
266
|
+
const mergedForbidden = filterPlaceholderPaths(semDraftConstraints?.forbiddenPaths);
|
|
267
|
+
const mergedVerify = Array.isArray(semDraftVerification?.commands)
|
|
268
|
+
? semDraftVerification.commands
|
|
269
|
+
.filter((cmd) => typeof cmd?.command === "string" && cmd.command.trim().length > 0)
|
|
270
|
+
.map((cmd) => ({
|
|
271
|
+
label: typeof cmd.label === "string" && cmd.label.trim()
|
|
272
|
+
? cmd.label.trim()
|
|
273
|
+
: "verify",
|
|
274
|
+
command: cmd.command.trim(),
|
|
275
|
+
...(typeof cmd.timeoutMs === "number"
|
|
276
|
+
? { timeoutMs: cmd.timeoutMs }
|
|
277
|
+
: {}),
|
|
278
|
+
}))
|
|
279
|
+
: [];
|
|
256
280
|
draft = {
|
|
257
281
|
...draft,
|
|
258
282
|
title,
|
|
283
|
+
...(semTaskKind
|
|
284
|
+
? { taskKind: normalizeConsoleWorkflowKind(semTaskKind, taskKind) }
|
|
285
|
+
: {}),
|
|
259
286
|
requirement: {
|
|
260
287
|
objective: semanticReq.objective.trim(),
|
|
261
288
|
scope: asStringList(semanticReq.scope),
|
|
262
289
|
nonGoals: asStringList(semanticReq.nonGoals),
|
|
263
290
|
acceptanceCriteria: asAcceptance(semanticReq.acceptanceCriteria),
|
|
264
291
|
},
|
|
292
|
+
...(mergedAllowed.length > 0 ||
|
|
293
|
+
mergedForbidden.length > 0 ||
|
|
294
|
+
Array.isArray(semDraftConstraints?.invariants)
|
|
295
|
+
? {
|
|
296
|
+
constraints: {
|
|
297
|
+
invariants: asStringList(semDraftConstraints?.invariants),
|
|
298
|
+
allowedPaths: mergedAllowed,
|
|
299
|
+
forbiddenPaths: mergedForbidden,
|
|
300
|
+
},
|
|
301
|
+
}
|
|
302
|
+
: {}),
|
|
303
|
+
...(mergedVerify.length > 0
|
|
304
|
+
? { verification: { commands: mergedVerify } }
|
|
305
|
+
: {}),
|
|
265
306
|
openQuestions: asStringList(artifact?.draft?.openQuestions ?? artifact?.semantic?.openQuestions) || undefined,
|
|
266
307
|
assumptions: asStringList(artifact?.draft?.assumptions ?? artifact?.semantic?.assumptions) || undefined,
|
|
267
308
|
references: artifact?.draft?.references,
|
|
@@ -14,6 +14,7 @@ import { InterviewSessionStore } from "./interview/session.js";
|
|
|
14
14
|
import { isLoopbackHost } from "./loopback.js";
|
|
15
15
|
import { ChatSessionStore } from "./chat/session-store.js";
|
|
16
16
|
import { createChatEventStore, createChatOperationLinker, } from "./chat/chat-event-store.js";
|
|
17
|
+
import { createChatTurnExecutionRegistry } from "./chat/turn-execution-registry.js";
|
|
17
18
|
import { ConsolePiRuntime } from "./chat/pi-runtime.js";
|
|
18
19
|
import { handleChatRequest } from "./chat/routes.js";
|
|
19
20
|
import { createOperationEventStore, } from "./operation-sse.js";
|
|
@@ -147,6 +148,7 @@ export async function createConsoleServer(options) {
|
|
|
147
148
|
// than silently consume a different process' event namespace.
|
|
148
149
|
const chatEventEpoch = randomBytes(12).toString("hex");
|
|
149
150
|
const chatEvents = createChatEventStore({ appData, epoch: chatEventEpoch });
|
|
151
|
+
const chatTurnExecutions = createChatTurnExecutionRegistry();
|
|
150
152
|
const chatOperationLinker = createChatOperationLinker({
|
|
151
153
|
chatEvents,
|
|
152
154
|
operations,
|
|
@@ -155,6 +157,7 @@ export async function createConsoleServer(options) {
|
|
|
155
157
|
const chatRuntime = new ConsolePiRuntime({
|
|
156
158
|
cwd: repoRoot,
|
|
157
159
|
sessionDir: appData.chatSessions,
|
|
160
|
+
resourcePreferencesPath: appData.resourcePreferences,
|
|
158
161
|
actionContext,
|
|
159
162
|
});
|
|
160
163
|
// chatRouteDeps is a plain object literal — it cannot throw. The previous
|
|
@@ -165,6 +168,7 @@ export async function createConsoleServer(options) {
|
|
|
165
168
|
runtime: chatRuntime,
|
|
166
169
|
store: chatStore,
|
|
167
170
|
events: chatEvents,
|
|
171
|
+
turnExecutions: chatTurnExecutions,
|
|
168
172
|
operationLinker: chatOperationLinker,
|
|
169
173
|
appData,
|
|
170
174
|
bootToken,
|