From e9940d35cf5bd33b1c434a5c3f0b4c6695df2511 Mon Sep 17 00:00:00 2001 From: Tianyi Cui <53024+tianyicui@users.noreply.github.com> Date: Sun, 19 Jul 2026 18:56:11 +0800 Subject: [PATCH] fix(goal): preserve structured domain error codes --- packages/goal/goal/src/runtime.ts | 10 ++++++---- packages/goal/goal/tests/goal.spec.ts | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/goal/goal/src/runtime.ts b/packages/goal/goal/src/runtime.ts index 9cd656ccae..49184faa8c 100644 --- a/packages/goal/goal/src/runtime.ts +++ b/packages/goal/goal/src/runtime.ts @@ -1,5 +1,6 @@ /** Runtime constructors and protocol constants for the goal domain. */ +import { HarnessError } from '@deepseek-ai/dsh-llm' import type { GoalErrorCode, GoalId as GoalIdType } from './types.ts' /** Version of the goal change metadata embedded in `context/message`. */ @@ -15,13 +16,14 @@ export function GoalId(id: string): GoalIdType { } /** Error returned by the goal domain boundary. */ -export class GoalError extends Error { +export class GoalError extends HarnessError { /** * @param message - human-readable rejection reason. * @param code - stable machine-routable classification. */ - constructor(message: string, public readonly code: GoalErrorCode) { - super(message) - this.name = 'GoalError' + // Keep the constructor to narrow HarnessError's string code at this boundary. + // eslint-disable-next-line @typescript-eslint/no-useless-constructor -- type-only narrowing + constructor(message: string, code: GoalErrorCode) { + super(message, code) } } diff --git a/packages/goal/goal/tests/goal.spec.ts b/packages/goal/goal/tests/goal.spec.ts index 03b00dd699..c8aa5bc3e3 100644 --- a/packages/goal/goal/tests/goal.spec.ts +++ b/packages/goal/goal/tests/goal.spec.ts @@ -2,7 +2,7 @@ import { describe, expect, it, vi } from 'vitest' import { Context } from 'cordis' import AgentRegistry, { agentEvents } from '@deepseek-ai/dsh-agent' import type { Agent, AgentStatus, InjectOptions } from '@deepseek-ai/dsh-agent' -import type { ContentBlock, MessageSource } from '@deepseek-ai/dsh-llm' +import { HarnessError, type ContentBlock, type MessageSource } from '@deepseek-ai/dsh-llm' import SessionStore, { Session, SessionId } from '@deepseek-ai/dsh-session' import GoalService, { GoalError, @@ -161,6 +161,7 @@ describe('GoalService creation and replay', () => { code: 'GOAL_INVALID_MAX_ROUNDS', })) expect(() => ctx.goals.resolveCreate({ objective: 'x', maxGoalRounds: 1.5 })).toThrow(GoalError) + expect(() => ctx.goals.resolveCreate({ objective: 'x', maxGoalRounds: 1.5 })).toThrow(HarnessError) expect(() => ctx.goals.resolveCreate({ objective: 'x', maxGoalRounds: Number.MAX_SAFE_INTEGER + 1 })).toThrow(GoalError) expect(ctx.goals.create(agent, { objective: 'x' }).maxGoalRounds).toBe(256) })