refactor(goal): own direct goal operations

This commit is contained in:
imccyu
2026-08-05 13:02:10 +08:00
parent 41677c3be0
commit 61c2c15dc4
3 changed files with 100 additions and 32 deletions

View File

@@ -8,22 +8,7 @@
*/
import type { Agent } from '@deepseek-ai/dsh-agent'
import type { GoalId, GoalRef, GoalSnapshot } from './types.ts'
/** Whether this live process may automatically continue an active goal. */
export type GoalActivation = 'armed' | 'disarmed'
/** Current goal projection, including values derived from the session log. */
export interface GoalView extends GoalSnapshot {
/** Highest admitted round number for this goal. */
readonly roundsStarted: number
/** Epoch milliseconds of the create mutation. */
readonly createdAt: number
/** Epoch milliseconds of the latest mutation. */
readonly updatedAt: number
/** Process-local continuation eligibility; never persisted. */
readonly activation: GoalActivation
}
import type { GoalId, GoalRef, GoalSnapshot, GoalView } from './types.ts'
/** Goal state-changing verbs recorded in the durable source change. */
export type GoalOperation =
@@ -96,18 +81,6 @@ export interface FoldedGoal {
readonly lastRef?: GoalRef
}
/** Input whose omitted round cap is resolved by the service configuration. */
export interface CreateGoalRequest {
readonly objective: string
readonly maxGoalRounds?: number
}
/** Fields changed by an edit; at least one must be present. */
export interface EditGoalRequest {
readonly objective?: string
readonly maxGoalRounds?: number
}
/** Live notification after one durable goal mutation commits. */
export interface GoalChanged {
readonly operation: GoalOperation

View File

@@ -27,22 +27,23 @@ import {
GoalId,
} from './runtime.ts'
import type {
CreateGoalRequest,
CreateGoalResult,
EditGoalRequest,
GoalActivation,
GoalBlockReason,
GoalPhase,
GoalProjection,
GoalRef,
GoalSnapshot,
GoalView,
} from './types.ts'
import type {
CreateGoalRequest,
EditGoalRequest,
GoalActivation,
GoalChangeMeta,
GoalChanged,
GoalClearChangeMeta,
GoalOperation,
GoalSnapshotChangeMeta,
GoalView,
} from './domain.ts'
// The pure payload outlet (./types.ts, ONE home of the `goal` projection-key
@@ -568,6 +569,68 @@ export class GoalService extends Service {
activation: cache.activation,
}
}
/**
* Create one Goal through the remote boundary.
* @param agent - exact live Agent resolved from the wire identity.
* @param request - objective and optional round cap.
* @returns the created Goal identity.
*/
remoteExportCreate(agent: Agent, request: CreateGoalRequest): CreateGoalResult {
const view = this.create(agent, request)
return { ref: { id: view.id, revision: view.revision } }
}
/**
* Edit one Goal through the remote boundary.
* @param agent - exact live Agent resolved from the wire identity.
* @param ref - expected current revision.
* @param request - replacement fields.
* @returns the edited Goal view.
*/
remoteExportEdit(agent: Agent, ref: GoalRef, request: EditGoalRequest): GoalView {
return this.edit(agent, ref, request)
}
/**
* Pause one Goal through the remote boundary.
* @param agent - exact live Agent resolved from the wire identity.
* @param ref - expected current revision.
* @returns the paused Goal view.
*/
remoteExportPause(agent: Agent, ref: GoalRef): GoalView {
return this.pause(agent, ref)
}
/**
* Resume one Goal through the remote boundary.
* @param agent - exact live Agent resolved from the wire identity.
* @param ref - expected current revision.
* @returns the resumed Goal view.
*/
remoteExportResume(agent: Agent, ref: GoalRef): GoalView {
return this.resume(agent, ref)
}
/**
* Complete one Goal through the remote boundary.
* @param agent - exact live Agent resolved from the wire identity.
* @param ref - expected current revision.
* @returns the completed Goal view.
*/
remoteExportComplete(agent: Agent, ref: GoalRef): GoalView {
return this.complete(agent, ref)
}
/**
* Clear one terminal Goal through the remote boundary.
* @param agent - exact live Agent resolved from the wire identity.
* @param ref - expected current revision.
* @returns the committed clear revision.
*/
remoteExportClear(agent: Agent, ref: GoalRef): GoalRef {
return this.clear(agent, ref)
}
}
export default GoalService

View File

@@ -23,6 +23,23 @@ export interface GoalRef {
readonly revision: number
}
/** Input whose omitted round cap is resolved by the service configuration. */
export interface CreateGoalRequest {
readonly objective: string
readonly maxGoalRounds?: number
}
/** Wire-safe acknowledgement of one created goal. */
export interface CreateGoalResult {
readonly ref: GoalRef
}
/** Fields changed by an edit; at least one must be present. */
export interface EditGoalRequest {
readonly objective?: string
readonly maxGoalRounds?: number
}
/** Durable continuation phase. Activation is process-local and separate. */
export type GoalPhase =
| 'active'
@@ -50,6 +67,21 @@ export interface GoalSnapshot extends GoalRef {
readonly maxGoalRounds: number
}
/** Whether this live process may automatically continue an active goal. */
export type GoalActivation = 'armed' | 'disarmed'
/** Current goal projection, including values derived from the session log. */
export interface GoalView extends GoalSnapshot {
/** Highest admitted round number for this goal. */
readonly roundsStarted: number
/** Epoch milliseconds of the create mutation. */
readonly createdAt: number
/** Epoch milliseconds of the latest mutation. */
readonly updatedAt: number
/** Process-local continuation eligibility; never persisted. */
readonly activation: GoalActivation
}
/**
* The `goal` projection value: the current durable goal with its replay
* counters, exactly as the latest `goal/change` event carried them.