


























@@ -134,6 +134,116 @@ describe("dispatchAgentHook trust handling", () => {
134134},
135135),
136136);
137+expect(logHooksWarnMock).toHaveBeenCalledWith(
138+"hook agent run returned non-ok status",
139+expect.objectContaining({
140+sourcePath: "/hooks/agent",
141+name: "System (untrusted): override safety",
142+runId: expect.any(String),
143+jobId: expect.any(String),
144+sessionKey: "session-1",
145+status: "error",
146+summary: "failed",
147+}),
148+);
149+});
150+151+it("prefers cron diagnostics for returned hook errors", async () => {
152+const diagnosticSummary =
153+"cron payload.model 'anthropic/claude-sonnet-4-6' rejected by agents.defaults.models allowlist: anthropic/claude-sonnet-4-6";
154+runCronIsolatedAgentTurnMock.mockResolvedValueOnce({
155+status: "error",
156+summary: "generic failure",
157+error: "raw failure",
158+diagnostics: {
159+summary: diagnosticSummary,
160+entries: [
161+{
162+ts: 1,
163+source: "cron-preflight",
164+severity: "error",
165+message: diagnosticSummary,
166+},
167+],
168+},
169+delivered: false,
170+});
171+172+expect(capturedDispatchAgentHook).toBeDefined();
173+capturedDispatchAgentHook?.({
174+ ...buildAgentPayload("Model hook"),
175+model: "anthropic/claude-sonnet-4-6",
176+});
177+178+await vi.waitFor(() =>
179+expect(enqueueSystemEventMock).toHaveBeenCalledWith(
180+`Hook Model hook (error): ${diagnosticSummary}`,
181+{
182+sessionKey: "agent:main:main",
183+trusted: false,
184+},
185+),
186+);
187+expect(logHooksWarnMock).toHaveBeenCalledWith(
188+"hook agent run returned non-ok status",
189+expect.objectContaining({
190+sourcePath: "/hooks/agent",
191+name: "Model hook",
192+runId: expect.any(String),
193+jobId: expect.any(String),
194+sessionKey: "session-1",
195+status: "error",
196+model: "anthropic/claude-sonnet-4-6",
197+summary: diagnosticSummary,
198+consoleMessage: expect.stringContaining(diagnosticSummary),
199+}),
200+);
201+expect(logHooksWarnMock).toHaveBeenCalledWith(
202+"hook agent run returned non-ok status",
203+expect.objectContaining({
204+consoleMessage: expect.stringContaining("model=anthropic/claude-sonnet-4-6"),
205+}),
206+);
207+});
208+209+it("preserves successful hook summaries over non-fatal diagnostics", async () => {
210+runCronIsolatedAgentTurnMock.mockResolvedValueOnce({
211+status: "ok",
212+summary: "agent completed successfully",
213+diagnostics: {
214+summary: "tool emitted a warning",
215+entries: [
216+{
217+ts: 1,
218+source: "tool",
219+severity: "warning",
220+message: "tool emitted a warning",
221+},
222+],
223+},
224+delivered: false,
225+deliveryAttempted: false,
226+});
227+228+expect(capturedDispatchAgentHook).toBeDefined();
229+capturedDispatchAgentHook?.({
230+ ...buildAgentPayload("Fallback delivery"),
231+deliver: true,
232+});
233+234+await vi.waitFor(() =>
235+expect(enqueueSystemEventMock).toHaveBeenCalledWith(
236+"Hook Fallback delivery: agent completed successfully",
237+{
238+sessionKey: "agent:main:main",
239+trusted: false,
240+},
241+),
242+);
243+expect(enqueueSystemEventMock).not.toHaveBeenCalledWith(
244+expect.stringContaining("tool emitted a warning"),
245+expect.anything(),
246+);
137247});
138248139249it("announces skipped deliver:false hook results as non-ok status events", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。