@xopcai/xopc 0.0.243 → 0.0.245
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-CAah-_8h.js → activity-store-BlxqErph.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DDH4HgP7.js → agent-avatar-dicebear-DRQnogaU.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-BDCfJZhh.js → agent-defaults-settings-panel-CpOxGbMD.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-B0ZWgf-U.js → agents-flnXZLaT.js} +1 -1
- package/dist/gateway/static/root/assets/{api-B2tKxbcz.js → api-BbXzyQMj.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Blfwszzn.js → app-management-settings-panel-CZl6n2xi.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-C3V7Na75.js → appearance-settings-Bglp-pn6.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-BiEks0-F.js → apps-page-CmsWarVB.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-BmSx7wzY.js → archive-plugin-DD2SweEH.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BS-S4LJ9.js → attachment-load-G0HenUmG.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-C7Y3L30D.js → automations-page-B78bFjH2.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-A3zPkPuo.js → automations-workspace-BMQGmn50.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-BM9B5kcm.js → binary-plugins-BbSQmXqn.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-BbnpkYP9.js → block-editor-DutTIH81.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-Dk4FQ7fY.js → browser-settings-page-CALiFKm4.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-CRnkgZHI.js → browser-workflow-inputs-BAAc151l.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-B9qGL-it.js → browser-workflows-page-DE5HPrHZ.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel--tR_El9e.js → capabilities-settings-panel-Dts7XtP3.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-D347vl_J.js → channels-settings-CWEd3wzh.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-status-swr-DuY4MGxe.js → channels-status-swr-CCBCtLDg.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-DABPvwBT.js → chat-terminal-dock-Bp1fXQm1.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-B-tvJkRJ.js → connectors-page-CQ6wVNLm.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-expression-D3bsKbNd.js → cron-expression-B8HA5IRb.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-BsGM6Yty.js → date-picker-DD8b7oad.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-Dj3g6YXZ.js → dependency-picker-BC9zwIyH.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-C1QT0Sur.js → desktop-pet-DsrsPZTW.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-r6kAOnfY.js → desktop-pet-settings-D7gp_HNA.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DOkf7nh9.js → extension-debug-page-BoKbOX7x.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Cq2IA4Ho.js → extension-page-BegL4FW8.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-DQn4qjDZ.js → extension-settings-page-CjPqq57s.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-DM3poL22.js → gateway-config-api-DaG57o4X.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BC3pgb_P.js → gateway-config-swr-826dipyU.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DPgH1hnh.js → gateway-settings-DkJGpgm6.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-uMcSfLru.js → gateway-startup-retry-DyvcAIMm.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-Bk80-E3b.js → heartbeat-settings-BLZ48kSU.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-DKo5JiMR.js → home-page-Dtw7Ipt1.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-D1qlQA-A.js → image-generation-api-D7cyfks6.js} +1 -1
- package/dist/gateway/static/root/assets/{index-B0WJL9N1.js → index-DG5CfYat.js} +10 -10
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BEwvd8ZU.js → keyboard-shortcuts-settings-D2Has7-N.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page--eJ5rmNj.js → local-app-workbench-page-BWidWY93.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-CgkY9E-r.js → local-apps-page-Bkekjoxf.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-CMZljTJx.js → locale-store-CBoCuIMx.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-Z49Td0J9.js → logs-page-C5zSSgvA.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-Dv8NSJKt.js → management-settings-B8c62vRS.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-Cm0RBB-t.js → markdown-split-3kxTTGO7.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-PPCLt7fu.js → markdown-view-BXsHghJd.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-Bcr5sU1f.js → media-plugins-BW8J1nCG.js} +1 -1
- package/dist/gateway/static/root/assets/messages-BbdwoxVo.js +3 -0
- package/dist/gateway/static/root/assets/{mobile-pairing-wizard-kKDiXofY.js → mobile-pairing-wizard-nwQ8iUcd.js} +1 -1
- package/dist/gateway/static/root/assets/models-hub-cache-88f4fzYS.js +1 -0
- package/dist/gateway/static/root/assets/{notes-page-CgsaRaGi.js → notes-page-DdybD0QM.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-C1DEE09k.js → notes-workbench-IYfpy2Jx.js} +2 -2
- package/dist/gateway/static/root/assets/{oauth-api-4VeMbkTJ.js → oauth-api-BjSUDIgq.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-BU0HiZtv.js → product-open-page-CAJeUXeU.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-isRapnp5.js → project-detail-page-4wjw-b7h.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-zvsjg0mi.js → projects-page-CCMj9PeL.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-CWOtPFrE.js → registry-api-BhGKnvLP.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-C9TGZ9Hc.js → remote-access-hub-DsBJqWIk.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-2zm9edMA.js → runtime-tools-settings-panel-B4IDcqx0.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-54A5gzkN.js → schema-form-DiGUUjO6.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-BP8RyiUn.js → sessions-page-BwGj0t-2.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BJCfUghk.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-DzDhoyxv.js → settings-page-CVQUsAhd.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-uDicHU1w.js → setup-status-panel-CQACRh1i.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-lOmLCWFS.js → share-preview-page-DTP1dtuS.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-T4Yvouvv.js → shares-settings-D_YPh6Rw.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-B43xlJlX.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-CnyNH3To.js → skills-page-Czpn7Y28.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-CgDtf2qs.js → skills-page.utils-d39rm3hb.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-C8yWfwtR.js → system-settings-panel-CXXySCSp.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-Tzfjlbf3.js → task-detail-page-DHiOqQMx.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-uxUwr10D.js → theme-store-hybK3oC9.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-Bvg679no.js → tunnel-api-BiBGK7O2.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-D88VGoyG.js → use-autosave-DjpzpeIm.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-RijPtyfO.js → user-context-page-1XBRV5gX.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CBHLsMcc.js → voice-api-key-field-CUIPNmOc.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-MqyI6cgq.js → voice-config-api-CBbiF1T3.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-GGe2TQ98.js → work-discovery-overlay-DVNxhb1x.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C0layUE9.js → workflow-run-setup-panel-HxxFQFY7.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-DQXIzBAc.js → workflows-page-BCgL7PRm.js} +1 -1
- package/dist/gateway/static/root/index.html +11 -11
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/turn-outcome.js +3 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +3 -1
- package/dist/src/agent/agent-manager.d.ts +2 -4
- package/dist/src/agent/agent-manager.js +24 -28
- package/dist/src/agent/background-review/coordinator.js +1 -1
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/child-agent-factory.d.ts +10 -7
- package/dist/src/agent/child-agent-factory.js +112 -158
- package/dist/src/agent/coding/index.d.ts +1 -1
- package/dist/src/agent/coding/index.js +2 -2
- package/dist/src/agent/coding/repository-instructions.d.ts +12 -0
- package/dist/src/agent/coding/repository-instructions.js +76 -0
- package/dist/src/agent/coding/run-verification.d.ts +34 -0
- package/dist/src/agent/coding/run-verification.js +134 -0
- package/dist/src/agent/coding/verification-command.d.ts +3 -0
- package/dist/src/agent/coding/verification-command.js +50 -0
- package/dist/src/agent/coding/workspace-revision.d.ts +2 -0
- package/dist/src/agent/coding/workspace-revision.js +77 -0
- package/dist/src/agent/commands/command-isolation.d.ts +21 -0
- package/dist/src/agent/commands/command-isolation.js +71 -0
- package/dist/src/agent/commands/command-registry.d.ts +56 -0
- package/dist/src/agent/commands/command-registry.js +259 -0
- package/dist/src/agent/embedded/index.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +2 -1
- package/dist/src/agent/embedded/run-turn.js +88 -25
- package/dist/src/agent/embedded/session-tool-result-guard.js +2 -2
- package/dist/src/agent/embedded/subscribe-session.d.ts +2 -1
- package/dist/src/agent/embedded/subscribe-session.js +2 -1
- package/dist/src/agent/embedded/types.d.ts +3 -1
- package/dist/src/agent/embedded/xopc-tools-bridge.js +4 -1
- package/dist/src/agent/image/index.js +1 -1
- package/dist/src/agent/index.js +3 -3
- package/dist/src/agent/memory/user-context-coordinator.js +1 -1
- package/dist/src/agent/middleware/index.d.ts +0 -5
- package/dist/src/agent/middleware/index.js +1 -2
- package/dist/src/agent/orchestration/agent-event-handler.d.ts +0 -5
- package/dist/src/agent/orchestration/agent-event-handler.js +1 -96
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
- package/dist/src/agent/orchestration/agent-turn-policy.js +5 -5
- package/dist/src/agent/orchestration/index.d.ts +1 -1
- package/dist/src/agent/orchestration/index.js +2 -2
- package/dist/src/agent/orchestration/loop-guard.d.ts +4 -31
- package/dist/src/agent/orchestration/loop-guard.js +14 -99
- package/dist/src/agent/prompt/sections/tooling.js +2 -4
- package/dist/src/agent/sandbox/types.d.ts +2 -2
- package/dist/src/agent/sandbox/types.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +1 -1
- package/dist/src/agent/service.d.ts +0 -2
- package/dist/src/agent/service.js +6 -23
- package/dist/src/agent/tasks/task-judge-service.d.ts +7 -0
- package/dist/src/agent/tasks/task-judge-service.js +24 -2
- package/dist/src/agent/tools/delegate-tool.d.ts +2 -1
- package/dist/src/agent/tools/delegate-tool.js +102 -124
- package/dist/src/agent/tools/exec-command.d.ts +8 -1
- package/dist/src/agent/tools/exec-command.js +77 -169
- package/dist/src/agent/tools/executor.js +9 -2
- package/dist/src/agent/tools/factory.js +50 -5
- package/dist/src/agent/tools/find.d.ts +10 -13
- package/dist/src/agent/tools/find.js +33 -80
- package/dist/src/agent/tools/grep.d.ts +14 -18
- package/dist/src/agent/tools/grep.js +56 -144
- package/dist/src/agent/tools/index.d.ts +0 -1
- package/dist/src/agent/tools/index.js +2 -3
- package/dist/src/agent/tools/language-diagnostics.d.ts +11 -0
- package/dist/src/agent/tools/language-diagnostics.js +62 -0
- package/dist/src/agent/tools/managed-job-tool.d.ts +2 -1
- package/dist/src/agent/tools/managed-job-tool.js +58 -118
- package/dist/src/agent/tools/read.js +24 -7
- package/dist/src/agent/tools/repository-search.d.ts +5 -0
- package/dist/src/agent/tools/repository-search.js +56 -0
- package/dist/src/agent/tools/review-workspace.d.ts +2 -0
- package/dist/src/agent/tools/review-workspace.js +103 -0
- package/dist/src/agent/tools/write.js +4 -4
- package/dist/src/agent/transcript/index.js +2 -2
- package/dist/src/agent/transcript/transcript-hygiene.js +2 -2
- package/dist/src/agent/workflow/subagent-runner.d.ts +0 -2
- package/dist/src/agent/workflow/subagent-runner.js +12 -31
- package/dist/src/agent-config/schema.d.ts +42 -0
- package/dist/src/agent-config/schema.js +5 -0
- package/dist/src/automations/draft/automation-draft-service.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/config/schema.d.ts +28 -0
- package/dist/src/execution-environments/local-worktree-manager.d.ts +3 -1
- package/dist/src/execution-environments/local-worktree-manager.js +8 -3
- package/dist/src/execution-environments/session-environment-service.js +5 -3
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +7 -0
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +23 -23
- package/dist/src/gateway/hono/routes/sessions.js +1 -1
- package/dist/src/gateway/media-access.js +1 -1
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/run-gateway-agent.js +4 -1
- package/dist/src/gateway/service.js +1 -1
- package/dist/src/gateway/session-reset-service.js +1 -1
- package/dist/src/gateway/workspace-ripgrep.d.ts +0 -6
- package/dist/src/gateway/workspace-ripgrep.js +2 -40
- package/dist/src/infra/ripgrep.d.ts +13 -0
- package/dist/src/infra/ripgrep.js +46 -0
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/proactive/execution/agent-executor.js +1 -1
- package/dist/src/session/store.js +1 -1
- package/dist/src/session/turn-outcome-projector.js +26 -6
- package/dist/src/tasks/task-run-coordinator.d.ts +2 -2
- package/dist/src/tasks/task-run-coordinator.js +14 -12
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/messages-CTSgFlE4.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-cache-ZrbGRiGY.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D4EMxWAZ.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DVb7nrXz.js +0 -1
- package/dist/src/agent/coding/turn-diff-tracker.d.ts +0 -67
- package/dist/src/agent/coding/turn-diff-tracker.js +0 -231
- package/dist/src/agent/middleware/self-verify.d.ts +0 -136
- package/dist/src/agent/middleware/self-verify.js +0 -380
- package/dist/src/agent/tools/execute-code-tool.d.ts +0 -11
- package/dist/src/agent/tools/execute-code-tool.js +0 -208
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
|
+
import { EmbeddedRunConflictError, abortEmbeddedRun, acquireEmbeddedRunLease, queueEmbeddedSteer } from "./runs.js";
|
|
4
|
+
import { lastAssistantPlainText, subscribeEmbeddedSessionEvents } from "./subscribe-session.js";
|
|
5
|
+
import { isContextOverflowError } from "../orchestration/context-overflow.js";
|
|
6
|
+
import { getAssistantTurnErrorMessage, isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure, stripTrailingErrorAssistantMessages } from "../orchestration/llm-turn-retry.js";
|
|
3
7
|
import { isAgentTurnUnsettledError, resolveAgentTurnTimeoutMs, runAgentTurnWithTimeout } from "../orchestration/run-agent-turn-with-timeout.js";
|
|
8
|
+
import { detectToolLoops } from "../orchestration/loop-guard.js";
|
|
9
|
+
import { tryApplySessionTranscriptHygiene } from "../transcript/transcript-hygiene.js";
|
|
4
10
|
import { resolvePromptCachePolicy } from "../../providers/prompt-cache-plan.js";
|
|
5
11
|
import { wrapStreamFnForXopcExtensions } from "./xopc-stream-bridge.js";
|
|
6
12
|
import { acquireEmbeddedSessionRunner, evictEmbeddedSessionRunner } from "./session-runner.js";
|
|
7
|
-
import { markTurnToolResult } from "../memory/turn-provenance.js";
|
|
8
|
-
import { isContextOverflowError } from "../orchestration/context-overflow.js";
|
|
9
|
-
import { getAssistantTurnErrorMessage, isAssistantTurnAborted, isAssistantTurnFailed, maybeRetryTurnAfterTransientLlmFailure, stripTrailingErrorAssistantMessages } from "../orchestration/llm-turn-retry.js";
|
|
10
13
|
import { projectContextForModel } from "../memory/context-budget.js";
|
|
11
|
-
import { EmbeddedRunConflictError, abortEmbeddedRun, acquireEmbeddedRunLease, queueEmbeddedSteer } from "./runs.js";
|
|
12
|
-
import { lastAssistantPlainText, subscribeEmbeddedSessionEvents } from "./subscribe-session.js";
|
|
13
|
-
import { detectToolLoops } from "../orchestration/loop-guard.js";
|
|
14
|
-
import { tryApplySessionTranscriptHygiene } from "../transcript/transcript-hygiene.js";
|
|
15
14
|
import { createSqliteTranscriptRuntime } from "./transcript-runtime.js";
|
|
16
15
|
import { buildPromptCacheSnapshot, observePromptCacheSnapshot } from "../../providers/prompt-cache-observability.js";
|
|
17
16
|
import { isPromptCacheExpired, recordPromptCacheTouch } from "../../providers/prompt-cache-lifecycle.js";
|
|
17
|
+
import { markTurnToolResult } from "../memory/turn-provenance.js";
|
|
18
|
+
import { RepositoryInstructions } from "../coding/repository-instructions.js";
|
|
19
|
+
import { RunVerification } from "../coding/run-verification.js";
|
|
18
20
|
//#region src/agent/embedded/run-turn.ts
|
|
19
21
|
init_logger();
|
|
20
22
|
const log = createLogger("EmbeddedRun");
|
|
@@ -30,12 +32,17 @@ function extractTextFromContent(content) {
|
|
|
30
32
|
}).map((block) => block.text).join("");
|
|
31
33
|
}
|
|
32
34
|
function extractRecentToolCalls(messages) {
|
|
35
|
+
const lastUser = messages.findLastIndex((message) => message.role === "user");
|
|
36
|
+
messages = messages.slice(Math.max(0, lastUser));
|
|
33
37
|
const resultByToolCallId = /* @__PURE__ */ new Map();
|
|
38
|
+
const revisionByToolCallId = /* @__PURE__ */ new Map();
|
|
34
39
|
for (const message of messages) {
|
|
35
40
|
if (message.role !== "toolResult") continue;
|
|
36
41
|
const toolCallId = message.toolCallId;
|
|
37
42
|
if (typeof toolCallId !== "string" || !toolCallId) continue;
|
|
38
|
-
resultByToolCallId.set(toolCallId,
|
|
43
|
+
resultByToolCallId.set(toolCallId, extractTextFromContent(message.content));
|
|
44
|
+
const revision = message.details?.workspaceRevision;
|
|
45
|
+
if (typeof revision === "string") revisionByToolCallId.set(toolCallId, revision);
|
|
39
46
|
}
|
|
40
47
|
const calls = [];
|
|
41
48
|
for (const message of messages) {
|
|
@@ -45,11 +52,12 @@ function extractRecentToolCalls(messages) {
|
|
|
45
52
|
calls.push({
|
|
46
53
|
name: toolCall.name,
|
|
47
54
|
params: toolCall.arguments,
|
|
55
|
+
...toolCall.id && revisionByToolCallId.has(toolCall.id) ? { revision: revisionByToolCallId.get(toolCall.id) } : {},
|
|
48
56
|
...toolCall.id && resultByToolCallId.has(toolCall.id) ? { resultPreview: resultByToolCallId.get(toolCall.id) } : {}
|
|
49
57
|
});
|
|
50
58
|
}
|
|
51
59
|
}
|
|
52
|
-
return calls;
|
|
60
|
+
return calls.slice(-12);
|
|
53
61
|
}
|
|
54
62
|
function getLastUserMessagePreview(messages) {
|
|
55
63
|
for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex--) {
|
|
@@ -119,6 +127,8 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
119
127
|
sessionId: transcriptRuntime.sessionId,
|
|
120
128
|
runId
|
|
121
129
|
});
|
|
130
|
+
const instructions = await RepositoryInstructions.open(workspaceDir);
|
|
131
|
+
const rootInstructions = await instructions.load(".", true);
|
|
122
132
|
runner = await acquireEmbeddedSessionRunner({
|
|
123
133
|
runtimeId: transcriptRuntime.runtimeId,
|
|
124
134
|
sessionId: transcriptRuntime.sessionId,
|
|
@@ -126,7 +136,7 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
126
136
|
model: resolvedModel,
|
|
127
137
|
modelRef: params.modelRef,
|
|
128
138
|
tools,
|
|
129
|
-
systemPrompt,
|
|
139
|
+
systemPrompt: [systemPrompt, rootInstructions].filter(Boolean).join("\n\n"),
|
|
130
140
|
thinkingLevel: thinkingLevel ?? "medium",
|
|
131
141
|
transcriptRuntime
|
|
132
142
|
});
|
|
@@ -143,6 +153,7 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
143
153
|
runner.piSm.setActiveTurnId?.(runId);
|
|
144
154
|
const streamFnWithXopcExtensions = wrapStreamFnForXopcExtensions(session.agent.streamFunction, params.promptCachePolicy);
|
|
145
155
|
const loggingStreamFn = (streamModel, context, options) => {
|
|
156
|
+
instructions.acknowledge();
|
|
146
157
|
const sourceMessages = [...context.messages];
|
|
147
158
|
const hygienicMessages = tryApplySessionTranscriptHygiene(sourceMessages, streamModel);
|
|
148
159
|
const loopGuard = detectToolLoops(extractRecentToolCalls(hygienicMessages));
|
|
@@ -150,19 +161,14 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
150
161
|
...context,
|
|
151
162
|
messages: hygienicMessages
|
|
152
163
|
};
|
|
153
|
-
if (loopGuard.injection
|
|
154
|
-
|
|
164
|
+
if (loopGuard.injection) effectiveContext = {
|
|
165
|
+
...effectiveContext,
|
|
166
|
+
messages: [...hygienicMessages, {
|
|
155
167
|
role: "user",
|
|
156
168
|
content: loopGuard.injection,
|
|
157
169
|
timestamp: Date.now()
|
|
158
|
-
}]
|
|
159
|
-
|
|
160
|
-
effectiveContext = {
|
|
161
|
-
...context,
|
|
162
|
-
messages,
|
|
163
|
-
tools: contextTools
|
|
164
|
-
};
|
|
165
|
-
}
|
|
170
|
+
}]
|
|
171
|
+
};
|
|
166
172
|
const projection = projectContextForModel({
|
|
167
173
|
messages: effectiveContext.messages,
|
|
168
174
|
contextWindow: streamModel.contextWindow ?? 128e3,
|
|
@@ -203,7 +209,6 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
203
209
|
toolCount: effectiveContext.tools?.length ?? 0,
|
|
204
210
|
lastUserMessagePreview: getLastUserMessagePreview(effectiveContext.messages),
|
|
205
211
|
loopWarningInjected: !!loopGuard.injection,
|
|
206
|
-
hiddenToolCount: loopGuard.hiddenTools.size,
|
|
207
212
|
promptCache: promptCacheSnapshot,
|
|
208
213
|
promptCacheChanges,
|
|
209
214
|
...process.env.XOPC_LOG_LLM_PAYLOAD === "true" ? { effectiveContext: {
|
|
@@ -215,10 +220,53 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
215
220
|
return streamFnWithXopcExtensions(streamModel, effectiveContext, { ...options });
|
|
216
221
|
};
|
|
217
222
|
session.agent.streamFunction = loggingStreamFn;
|
|
223
|
+
const verification = await RunVerification.open(workspaceDir);
|
|
224
|
+
const checkpoints = runner.piSm.getBranch?.() ?? [];
|
|
225
|
+
const lastStart = checkpoints.findLastIndex((entry) => entry.type === "custom" && entry.customType === "coding_run_started");
|
|
226
|
+
const lastSummary = checkpoints.findLastIndex((entry) => entry.type === "custom" && entry.customType === "coding_verification");
|
|
227
|
+
const checkpoint = checkpoints[params.resumeLastUserMessage && lastSummary >= lastStart ? lastSummary : lastStart];
|
|
228
|
+
if (checkpoint?.type === "custom" && (params.resumeLastUserMessage || lastStart > lastSummary)) verification.restore(checkpoint.data, params.resumeLastUserMessage === true && lastSummary >= lastStart);
|
|
229
|
+
runner.piSm.appendCustomEntry("coding_run_started", {
|
|
230
|
+
runId,
|
|
231
|
+
workspace: workspaceDir,
|
|
232
|
+
required: params.verifyChanges ?? sessionKey.startsWith("agent:coder:"),
|
|
233
|
+
...await verification.summary()
|
|
234
|
+
});
|
|
235
|
+
let policyStopped = false;
|
|
218
236
|
params.turnPolicy?.reset();
|
|
219
|
-
session.agent.beforeToolCall =
|
|
220
|
-
|
|
221
|
-
|
|
237
|
+
session.agent.beforeToolCall = async (context, signal) => {
|
|
238
|
+
const decision = await params.turnPolicy?.beforeToolCall(context, signal);
|
|
239
|
+
if (decision?.block) {
|
|
240
|
+
policyStopped ||= decision.terminate === true;
|
|
241
|
+
return decision;
|
|
242
|
+
}
|
|
243
|
+
if (context.toolCall.name !== "read_file") {
|
|
244
|
+
const scoped = await instructions.forTool(context.toolCall.name, context.args);
|
|
245
|
+
if (scoped) return {
|
|
246
|
+
block: true,
|
|
247
|
+
reason: `${scoped}\n\nApply these instructions, then retry the operation.`
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
await verification.beforeTool(context.toolCall.id, context.toolCall.name);
|
|
251
|
+
return decision;
|
|
252
|
+
};
|
|
253
|
+
session.agent.afterToolCall = async (context) => {
|
|
254
|
+
const scoped = context.toolCall.name === "read_file" ? await instructions.forTool(context.toolCall.name, context.args) : "";
|
|
255
|
+
const checked = await verification.afterTool(context);
|
|
256
|
+
if (scoped) checked.result.content.unshift({
|
|
257
|
+
type: "text",
|
|
258
|
+
text: scoped
|
|
259
|
+
});
|
|
260
|
+
await params.turnPolicy?.afterToolCall({
|
|
261
|
+
...context,
|
|
262
|
+
...checked
|
|
263
|
+
});
|
|
264
|
+
return checked;
|
|
265
|
+
};
|
|
266
|
+
session.agent.shouldStopAfterTurn = (context) => {
|
|
267
|
+
policyStopped ||= params.turnPolicy?.shouldStopAfterTurn(context) ?? false;
|
|
268
|
+
return policyStopped;
|
|
269
|
+
};
|
|
222
270
|
unsubscribe = subscribeEmbeddedSessionEvents(session, (event) => {
|
|
223
271
|
if (event.type === "message_end" && event.message.role === "assistant") recordPromptCacheTouch(sessionKey, resolvedModel, event.message.usage);
|
|
224
272
|
if (event.type === "tool_execution_end") markTurnToolResult(sessionKey, runId, event.toolName);
|
|
@@ -226,7 +274,7 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
226
274
|
...event,
|
|
227
275
|
runId
|
|
228
276
|
});
|
|
229
|
-
});
|
|
277
|
+
}, params.onAgentEvent);
|
|
230
278
|
const abortListener = () => {
|
|
231
279
|
session.abort();
|
|
232
280
|
};
|
|
@@ -253,7 +301,22 @@ async function runXopcEmbeddedTurn(params) {
|
|
|
253
301
|
abortSignal: runAbortSignal,
|
|
254
302
|
onEvent
|
|
255
303
|
});
|
|
304
|
+
const pending = await verification.pendingContext();
|
|
305
|
+
if ((params.verifyChanges ?? sessionKey.startsWith("agent:coder:")) && pending && !policyStopped && !runAbortSignal.aborted && !isAssistantTurnFailed(session.agent) && !isAssistantTurnAborted(session.agent)) {
|
|
306
|
+
await session.sendCustomMessage({
|
|
307
|
+
customType: "coding_verification",
|
|
308
|
+
content: pending,
|
|
309
|
+
display: false
|
|
310
|
+
}, { triggerTurn: true });
|
|
311
|
+
await session.agent.waitForIdle();
|
|
312
|
+
}
|
|
256
313
|
}, timeoutMs);
|
|
314
|
+
runner.piSm.appendCustomEntry("coding_verification", {
|
|
315
|
+
runId,
|
|
316
|
+
workspace: workspaceDir,
|
|
317
|
+
required: params.verifyChanges ?? sessionKey.startsWith("agent:coder:"),
|
|
318
|
+
...await verification.summary()
|
|
319
|
+
});
|
|
257
320
|
if (runAbortSignal.aborted) return {
|
|
258
321
|
ok: false,
|
|
259
322
|
errorMessage: "aborted"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { init_string_coerce, normalizeOptionalString } from "../../utils/string-coerce.js";
|
|
2
|
+
import { extractToolCallsFromAssistant, extractToolResultId } from "../transcript/tool-call-id.js";
|
|
3
|
+
import { makeMissingToolResult, sanitizeToolCallInputs } from "../transcript/session-transcript-repair.js";
|
|
2
4
|
import { boundedJsonUtf8Bytes, firstEnumerableOwnKeys, jsonUtf8BytesOrInfinity } from "../../infra/json-utf8-bytes.js";
|
|
3
5
|
import { emitSessionTranscriptUpdate } from "../../session/transcript-events.js";
|
|
4
6
|
import { formatContextLimitTruncationNotice } from "./tool-result-context-guard.js";
|
|
5
7
|
import { resolveLiveToolResultMaxChars, truncateToolResultMessage } from "./tool-result-truncation.js";
|
|
6
|
-
import { extractToolCallsFromAssistant, extractToolResultId } from "../transcript/tool-call-id.js";
|
|
7
|
-
import { makeMissingToolResult, sanitizeToolCallInputs } from "../transcript/session-transcript-repair.js";
|
|
8
8
|
//#region src/agent/embedded/session-tool-result-guard.ts
|
|
9
9
|
init_string_coerce();
|
|
10
10
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AgentSession } from '@earendil-works/pi-coding-agent';
|
|
2
|
+
import type { AgentEvent } from '@earendil-works/pi-agent-core';
|
|
2
3
|
import type { EmbeddedStreamEvent } from './types.js';
|
|
3
|
-
export declare function subscribeEmbeddedSessionEvents(session: AgentSession, onEvent: (event: EmbeddedStreamEvent) => void): () => void;
|
|
4
|
+
export declare function subscribeEmbeddedSessionEvents(session: AgentSession, onEvent: (event: EmbeddedStreamEvent) => void, onAgentEvent?: (event: AgentEvent) => void): () => void;
|
|
4
5
|
export declare function lastAssistantPlainText(session: AgentSession): string | undefined;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { extractTextContent } from "../context/workspace.js";
|
|
2
2
|
//#region src/agent/embedded/subscribe-session.ts
|
|
3
|
-
function subscribeEmbeddedSessionEvents(session, onEvent) {
|
|
3
|
+
function subscribeEmbeddedSessionEvents(session, onEvent, onAgentEvent) {
|
|
4
4
|
return session.subscribe((event) => {
|
|
5
5
|
const base = event;
|
|
6
|
+
onAgentEvent?.(base);
|
|
6
7
|
switch (base.type) {
|
|
7
8
|
case "agent_start":
|
|
8
9
|
onEvent({ type: "agent_start" });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentMessage, AgentToolResult, ThinkingLevel } from '@earendil-works/pi-agent-core';
|
|
1
|
+
import type { AgentEvent, AgentMessage, AgentToolResult, ThinkingLevel } from '@earendil-works/pi-agent-core';
|
|
2
2
|
import type { AssistantMessageEvent, Model, Api, ImageContent } from '@earendil-works/pi-ai';
|
|
3
3
|
import type { TurnOutcome } from '@xopcai/gateway-contract';
|
|
4
4
|
import type { SessionStore } from '../../session/store.js';
|
|
@@ -106,9 +106,11 @@ export type RunXopcEmbeddedTurnParams = {
|
|
|
106
106
|
turnPolicy?: AgentTurnPolicy;
|
|
107
107
|
abortSignal?: AbortSignal;
|
|
108
108
|
onEvent?: (event: EmbeddedStreamEvent) => void;
|
|
109
|
+
onAgentEvent?: (event: AgentEvent) => void;
|
|
109
110
|
images?: ImageContent[];
|
|
110
111
|
/** Continue from the persisted trailing user row instead of appending it again. */
|
|
111
112
|
resumeLastUserMessage?: boolean;
|
|
113
|
+
verifyChanges?: boolean;
|
|
112
114
|
};
|
|
113
115
|
export type RunXopcEmbeddedTurnResult = {
|
|
114
116
|
ok: boolean;
|
|
@@ -84,7 +84,10 @@ function invalidApplyPatchEnvelopeResult(error) {
|
|
|
84
84
|
type: "text",
|
|
85
85
|
text: `apply_patch input rejected (${error.issue}). Expected: ${error.expected}.${received} ${error.retryHint} Use this exact envelope:\n${APPLY_PATCH_BEGIN_MARKER}\n*** Update File: path\n@@\n-old\n+new\n${APPLY_PATCH_END_MARKER}`
|
|
86
86
|
}],
|
|
87
|
-
details:
|
|
87
|
+
details: {
|
|
88
|
+
...error,
|
|
89
|
+
status: "failed"
|
|
90
|
+
}
|
|
88
91
|
};
|
|
89
92
|
}
|
|
90
93
|
/** Map xopc {@link AgentTool} instances to pi-coding-agent {@link ToolDefinition}s for `createAgentSession`. */
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getImageUnderstandingProvider, listImageUnderstandingProviders, registerImageUnderstandingProvider } from "./understanding/provider-registry.js";
|
|
2
2
|
import { resolveImageModelConfigForTool } from "./tool-model-config.js";
|
|
3
3
|
import { describeImages, describeImagesWithFallback } from "./understanding/runtime.js";
|
|
4
|
+
import { modelSupportsVision, resolveImageHandlingStrategy } from "./vision-detection.js";
|
|
4
5
|
import { runWithImageModelFallback } from "./image-model-fallback.js";
|
|
5
6
|
import { loadImageForToolInput } from "./load-image-media.js";
|
|
6
7
|
import { getImageGenerationProvider, listImageGenerationProviders } from "./generation/provider-registry.js";
|
|
7
8
|
import { generateImage, listImageGenerationProvidersSummary } from "./generation/runtime.js";
|
|
8
|
-
import { modelSupportsVision, resolveImageHandlingStrategy } from "./vision-detection.js";
|
|
9
9
|
export { describeImages, describeImagesWithFallback, generateImage, getImageGenerationProvider, getImageUnderstandingProvider, listImageGenerationProviders, listImageGenerationProvidersSummary, listImageUnderstandingProviders, loadImageForToolInput, modelSupportsVision, registerImageUnderstandingProvider, resolveImageHandlingStrategy, resolveImageModelConfigForTool, runWithImageModelFallback };
|
package/dist/src/agent/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { resolveTranscriptPolicy } from "./transcript/transcript-policy.js";
|
|
2
|
+
import { dropThinkingBlocks } from "./transcript/thinking.js";
|
|
1
3
|
import { extractToolCallsFromAssistant, extractToolResultId, sanitizeToolCallId, sanitizeToolCallIdsForCloudCodeAssist } from "./transcript/tool-call-id.js";
|
|
2
4
|
import { makeMissingToolResult, repairToolUseResultPairing, sanitizeToolCallInputs, sanitizeToolUseResultPairing, stripToolResultDetails } from "./transcript/session-transcript-repair.js";
|
|
5
|
+
import { applySessionTranscriptHygiene, applySessionTranscriptHygieneForPersistence, applySessionTranscriptHygieneWithPolicy, resolvePolicyForModel, tryApplySessionTranscriptHygiene, tryApplySessionTranscriptHygieneForPersistence } from "./transcript/transcript-hygiene.js";
|
|
3
6
|
import { createResponseMessage, createSignalMessage, createTaskMessage, isValidIPCMessage } from "./ipc/types.js";
|
|
4
7
|
import { AgentInbox } from "./ipc/inbox.js";
|
|
5
8
|
import { AgentBus } from "./ipc/bus.js";
|
|
6
9
|
import { AgentSocketClient, AgentSocketServer, isSocketAvailable } from "./ipc/socket.js";
|
|
7
10
|
import "./ipc/index.js";
|
|
8
|
-
import { resolveTranscriptPolicy } from "./transcript/transcript-policy.js";
|
|
9
|
-
import { dropThinkingBlocks } from "./transcript/thinking.js";
|
|
10
|
-
import { applySessionTranscriptHygiene, applySessionTranscriptHygieneForPersistence, applySessionTranscriptHygieneWithPolicy, resolvePolicyForModel, tryApplySessionTranscriptHygiene, tryApplySessionTranscriptHygieneForPersistence } from "./transcript/transcript-hygiene.js";
|
|
11
11
|
import { AgentService } from "./service.js";
|
|
12
12
|
import { stripToolMessages } from "./transcript/strip-tool-messages.js";
|
|
13
13
|
import "./transcript/index.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
|
|
2
|
+
import { consumeTurnMemoryProvenance, markTurnRecalledContext } from "./turn-provenance.js";
|
|
2
3
|
import { assembleTaskContext } from "../../tasks/task-context-assembler.js";
|
|
3
4
|
import { shouldPlanUserContextThisTurn } from "./memory-config.js";
|
|
4
5
|
import { UserContextPlanner, prependAgentContext } from "../../user-context/planner.js";
|
|
5
6
|
import { extractAgentUserPlainText } from "./user-message-text.js";
|
|
6
|
-
import { consumeTurnMemoryProvenance, markTurnRecalledContext } from "./turn-provenance.js";
|
|
7
7
|
import { planTrustedRecall } from "./trusted-recall.js";
|
|
8
8
|
//#region src/agent/memory/user-context-coordinator.ts
|
|
9
9
|
init_session_key();
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agent middleware — request-scoped log context (`ContextMiddleware`) and
|
|
3
|
-
* harness-style self-verify tracking (`SelfVerifyMiddleware`).
|
|
4
|
-
*/
|
|
5
|
-
export { SelfVerifyMiddleware, type FileEditRecord, type SelfVerifyConfig, type SelfVerifyAgentKind, type SelfVerifyState, type VerificationTask, type VerificationRecord, } from './self-verify.js';
|
|
6
1
|
export { ContextMiddleware, type RequestContext } from './context.js';
|
|
@@ -18,11 +18,9 @@ import type { ToolErrorTracker } from '../tools/error-tracker.js';
|
|
|
18
18
|
import type { RequestLimiter } from '../models/request-limiter.js';
|
|
19
19
|
import type { LifecycleManager } from '../lifecycle/index.js';
|
|
20
20
|
import type { ToolChainTracker } from '../tools/chain-tracker.js';
|
|
21
|
-
import type { SelfVerifyMiddleware } from '../middleware/index.js';
|
|
22
21
|
import type { SystemReminder } from '../prompt/system-reminder.js';
|
|
23
22
|
import type { ToolUsageAnalyzer } from '../tools/usage-analyzer.js';
|
|
24
23
|
import type { ErrorPatternMatcher } from '../tools/error-pattern-matcher.js';
|
|
25
|
-
import type { TurnDiffTracker } from '../coding/index.js';
|
|
26
24
|
export type SessionEventListener = (event: AgentEvent, context: SessionContext) => void;
|
|
27
25
|
export type SessionEventTypeFilter = AgentEvent['type'] | 'all';
|
|
28
26
|
/**
|
|
@@ -35,17 +33,14 @@ export declare class SessionEventBus {
|
|
|
35
33
|
on(type: SessionEventTypeFilter, listener: SessionEventListener): () => void;
|
|
36
34
|
dispatch(event: AgentEvent, context: SessionContext | null): void;
|
|
37
35
|
}
|
|
38
|
-
export declare function readChangedPathsFromToolEnd(toolName: string, args: unknown, result: unknown): string[];
|
|
39
36
|
export interface AgentEventHandlerConfig {
|
|
40
37
|
errorTracker: ToolErrorTracker;
|
|
41
38
|
requestLimiter: RequestLimiter;
|
|
42
39
|
lifecycleManager: LifecycleManager;
|
|
43
40
|
toolChainTracker: ToolChainTracker;
|
|
44
|
-
selfVerifyMiddleware: SelfVerifyMiddleware;
|
|
45
41
|
systemReminder: SystemReminder;
|
|
46
42
|
toolUsageAnalyzer: ToolUsageAnalyzer;
|
|
47
43
|
errorPatternMatcher: ErrorPatternMatcher;
|
|
48
|
-
turnDiffTracker?: TurnDiffTracker;
|
|
49
44
|
}
|
|
50
45
|
/**
|
|
51
46
|
* Thin façade over {@link SessionEventBus} that pre-registers all built-in
|
|
@@ -122,58 +122,6 @@ function installSystemReminderListener(bus, systemReminder) {
|
|
|
122
122
|
e.result = systemReminder.appendToResult(e.result, e.toolName);
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
|
-
function appendTextToToolResult(result, text) {
|
|
126
|
-
if (!text.trim()) return result;
|
|
127
|
-
if (result && typeof result === "object") {
|
|
128
|
-
const res = result;
|
|
129
|
-
if (Array.isArray(res.content)) {
|
|
130
|
-
res.content = [...res.content, {
|
|
131
|
-
type: "text",
|
|
132
|
-
text: `\n${text}`
|
|
133
|
-
}];
|
|
134
|
-
return res;
|
|
135
|
-
}
|
|
136
|
-
if (typeof res.content === "string") {
|
|
137
|
-
res.content = `${res.content}\n${text}`;
|
|
138
|
-
return res;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return result;
|
|
142
|
-
}
|
|
143
|
-
function readRecord(value) {
|
|
144
|
-
return value && typeof value === "object" ? value : null;
|
|
145
|
-
}
|
|
146
|
-
function readToolResultDetails(result) {
|
|
147
|
-
const rec = readRecord(result);
|
|
148
|
-
if (!rec) return null;
|
|
149
|
-
return readRecord(rec.details);
|
|
150
|
-
}
|
|
151
|
-
function readStringArray(value) {
|
|
152
|
-
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
153
|
-
}
|
|
154
|
-
function readChangedPathsFromToolEnd(toolName, args, result) {
|
|
155
|
-
const name = toolName.toLowerCase();
|
|
156
|
-
const details = readToolResultDetails(result);
|
|
157
|
-
if (name === "apply_patch") {
|
|
158
|
-
const files = readStringArray(details?.files);
|
|
159
|
-
if (files.length > 0) return files;
|
|
160
|
-
return (Array.isArray(details?.changes) ? details.changes : []).flatMap((change) => {
|
|
161
|
-
const rec = readRecord(change);
|
|
162
|
-
if (!rec) return [];
|
|
163
|
-
return readStringArray([rec.moveTo, rec.path]);
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
if (name === "write_file") {
|
|
167
|
-
if (typeof details?.size !== "number") return [];
|
|
168
|
-
const rec = readRecord(args);
|
|
169
|
-
return typeof rec?.path === "string" ? [rec.path] : [];
|
|
170
|
-
}
|
|
171
|
-
if (name.includes("write") || name.includes("edit")) {
|
|
172
|
-
const rec = readRecord(args);
|
|
173
|
-
return typeof rec?.path === "string" ? [rec.path] : [];
|
|
174
|
-
}
|
|
175
|
-
return [];
|
|
176
|
-
}
|
|
177
125
|
function installToolChainListener(bus, toolChainTracker) {
|
|
178
126
|
bus.on("turn_start", (_event, context) => {
|
|
179
127
|
toolChainTracker.startChain(context.sessionKey);
|
|
@@ -231,47 +179,6 @@ function installErrorTrackingListener(bus, deps) {
|
|
|
231
179
|
deps.errorTracker.reset();
|
|
232
180
|
});
|
|
233
181
|
}
|
|
234
|
-
function installSelfVerifyListener(bus, selfVerifyMiddleware) {
|
|
235
|
-
bus.on("tool_execution_end", (event, context) => {
|
|
236
|
-
const e = event;
|
|
237
|
-
const name = e.toolName?.toLowerCase() ?? "";
|
|
238
|
-
const args = e.args;
|
|
239
|
-
if (name === "exec_command") {
|
|
240
|
-
selfVerifyMiddleware.recordVerification(e.toolName, args, {
|
|
241
|
-
isError: e.isError,
|
|
242
|
-
result: e.result
|
|
243
|
-
}, context.sessionKey);
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
if (!e.isError) {
|
|
247
|
-
const changedPaths = readChangedPathsFromToolEnd(e.toolName, args, e.result);
|
|
248
|
-
for (const path of changedPaths) selfVerifyMiddleware.recordEdit(path, name.includes("write") ? "write" : "edit", context.sessionKey);
|
|
249
|
-
if (changedPaths.length > 0) {
|
|
250
|
-
e.result = appendTextToToolResult(e.result, selfVerifyMiddleware.consumePostEditReminder(context.sessionKey));
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
selfVerifyMiddleware.recordVerification(e.toolName, args, {
|
|
254
|
-
isError: e.isError,
|
|
255
|
-
result: e.result
|
|
256
|
-
}, context.sessionKey);
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
bus.on("turn_start", (_event, context) => {
|
|
260
|
-
selfVerifyMiddleware.onTurnStart(context.sessionKey);
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
function installTurnDiffTrackerListener(bus, turnDiffTracker) {
|
|
264
|
-
bus.on("tool_execution_end", (event, context) => {
|
|
265
|
-
const e = event;
|
|
266
|
-
turnDiffTracker.recordToolResult({
|
|
267
|
-
sessionKey: context.sessionKey,
|
|
268
|
-
toolName: e.toolName,
|
|
269
|
-
args: e.args,
|
|
270
|
-
result: e.result,
|
|
271
|
-
isError: e.isError
|
|
272
|
-
});
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
182
|
/**
|
|
276
183
|
* Thin façade over {@link SessionEventBus} that pre-registers all built-in
|
|
277
184
|
* listeners in their required order. `handle(event, ctx)` is the entry point
|
|
@@ -288,8 +195,6 @@ var AgentEventHandler = class {
|
|
|
288
195
|
});
|
|
289
196
|
installLifecycleHookListener(this.bus, config.lifecycleManager);
|
|
290
197
|
installSystemReminderListener(this.bus, config.systemReminder);
|
|
291
|
-
if (config.turnDiffTracker) installTurnDiffTrackerListener(this.bus, config.turnDiffTracker);
|
|
292
|
-
installSelfVerifyListener(this.bus, config.selfVerifyMiddleware);
|
|
293
198
|
installToolUsageListener(this.bus, config.toolUsageAnalyzer);
|
|
294
199
|
installToolChainListener(this.bus, config.toolChainTracker);
|
|
295
200
|
installErrorTrackingListener(this.bus, {
|
|
@@ -312,4 +217,4 @@ var AgentEventHandler = class {
|
|
|
312
217
|
}
|
|
313
218
|
};
|
|
314
219
|
//#endregion
|
|
315
|
-
export { AgentEventHandler, SessionEventBus
|
|
220
|
+
export { AgentEventHandler, SessionEventBus };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createLogger } from "../../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../../utils/logger.js";
|
|
3
3
|
import { runContextConsolidation } from "../../user-context/consolidation.js";
|
|
4
|
+
import { abortEmbeddedRun } from "../embedded/runs.js";
|
|
4
5
|
import { persistInboundAttachments } from "../../channels/attachments/inbound-persist.js";
|
|
5
6
|
import { buildTranscriptUserMessage, clearPendingTranscriptUserMessage, hydrateUserTurnForLlm, setPendingTranscriptUserMessage } from "../inbound/attachment-pipeline.js";
|
|
6
7
|
import { extractAgentUserPlainText } from "../memory/user-message-text.js";
|
|
7
8
|
import { resolveEffectiveThinkingLevel } from "../../session/thinking-resolve.js";
|
|
8
|
-
import { abortEmbeddedRun } from "../embedded/runs.js";
|
|
9
9
|
import { runEmbeddedTurnForSession } from "../embedded/run-for-session.js";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
//#region src/agent/orchestration/agent-orchestrator.ts
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
//#region src/agent/orchestration/agent-turn-policy.ts
|
|
2
|
-
function assistantMessageCount(messages) {
|
|
3
|
-
return messages.filter((message) => message.role === "assistant").length;
|
|
4
|
-
}
|
|
5
2
|
/** One user-visible run policy. A fresh instance is created for every embedded run. */
|
|
6
3
|
function createAgentTurnPolicy(options) {
|
|
7
4
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
8
5
|
let toolFailures = 0;
|
|
6
|
+
let assistantTurns = 0;
|
|
9
7
|
return {
|
|
10
8
|
reset() {
|
|
11
9
|
toolCalls.clear();
|
|
12
10
|
toolFailures = 0;
|
|
11
|
+
assistantTurns = 0;
|
|
13
12
|
},
|
|
14
13
|
async beforeToolCall(context, signal) {
|
|
15
14
|
const limit = options.resolveToolLimit?.(context.toolCall.name, context.args);
|
|
@@ -27,8 +26,9 @@ function createAgentTurnPolicy(options) {
|
|
|
27
26
|
async afterToolCall(context) {
|
|
28
27
|
if (context.isError) toolFailures += 1;
|
|
29
28
|
},
|
|
30
|
-
shouldStopAfterTurn(
|
|
31
|
-
|
|
29
|
+
shouldStopAfterTurn(_context) {
|
|
30
|
+
assistantTurns += 1;
|
|
31
|
+
return Boolean(options.maxTurns && assistantTurns >= options.maxTurns || options.maxToolFailures && toolFailures >= options.maxToolFailures);
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
}
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Orchestration Layer - Exports all orchestration-related modules
|
|
3
3
|
*/
|
|
4
4
|
export { AgentOrchestrator, type AgentOrchestratorConfig } from './agent-orchestrator.js';
|
|
5
|
-
export { AgentEventHandler, SessionEventBus,
|
|
5
|
+
export { AgentEventHandler, SessionEventBus, type AgentEventHandlerConfig, type SessionEventListener, type SessionEventTypeFilter, } from './agent-event-handler.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { AgentOrchestrator } from "./agent-orchestrator.js";
|
|
2
|
-
import { AgentEventHandler, SessionEventBus
|
|
3
|
-
export { AgentEventHandler, AgentOrchestrator, SessionEventBus
|
|
2
|
+
import { AgentEventHandler, SessionEventBus } from "./agent-event-handler.js";
|
|
3
|
+
export { AgentEventHandler, AgentOrchestrator, SessionEventBus };
|
|
@@ -1,37 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loop Guard — Detects repetitive tool call patterns within an agent turn
|
|
3
|
-
* and produces context injections for the LLM.
|
|
4
|
-
*
|
|
5
|
-
* Design: pure function that analyzes recent tool call history (already in
|
|
6
|
-
* the transcript) and returns:
|
|
7
|
-
* - A developer-role message to inject into the next LLM request
|
|
8
|
-
* - A set of tool names to temporarily hide from the model
|
|
9
|
-
*
|
|
10
|
-
* This operates at the orchestration layer (before LLM sees tools/messages)
|
|
11
|
-
* rather than the execution layer, so the model naturally stops calling
|
|
12
|
-
* blocked tools without receiving confusing "fake" tool outputs.
|
|
13
|
-
*/
|
|
14
1
|
export interface RecentToolCall {
|
|
15
2
|
name: string;
|
|
16
3
|
params: unknown;
|
|
17
|
-
/** Optional: tool result text (for same-result detection). */
|
|
18
4
|
resultPreview?: string;
|
|
5
|
+
revision?: string;
|
|
19
6
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
softThreshold: number;
|
|
23
|
-
/** Consecutive identical calls before hiding the tool (default: 3). */
|
|
24
|
-
hideThreshold: number;
|
|
25
|
-
}
|
|
26
|
-
export interface LoopGuardResult {
|
|
27
|
-
/** Developer message to inject into LLM context (null = no loop). */
|
|
7
|
+
/** Warn on a stalled tail, without removing tools needed to recover or verify a repair. */
|
|
8
|
+
export declare function detectToolLoops(recentCalls: readonly RecentToolCall[]): {
|
|
28
9
|
injection: string | null;
|
|
29
|
-
|
|
30
|
-
hiddenTools: Set<string>;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Analyze recent tool calls and produce loop guard result.
|
|
34
|
-
*
|
|
35
|
-
* Pure function — no side effects, no shared state.
|
|
36
|
-
*/
|
|
37
|
-
export declare function detectToolLoops(recentCalls: readonly RecentToolCall[], config?: Partial<LoopGuardConfig>): LoopGuardResult;
|
|
10
|
+
};
|