@deepseek-ai/dsh-goal 0.2.0-rc.2 → 0.2.1-alpha.2

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/README.i18n.yaml CHANGED
@@ -42,14 +42,14 @@
42
42
  en: 6f19e891ffc79754
43
43
  zh: 9599e3b142f1e6b5
44
44
  /deepseek-ai-dsh-goal/understand-the-implementation/source-map:
45
- en: f0451101cf73da7d
46
- zh: 73176ab69bb63a7f
45
+ en: aef62dff93f32796
46
+ zh: dba79da0466218a7
47
47
  /deepseek-ai-dsh-goal/understand-the-implementation/events-and-attribution:
48
48
  en: 502cf61dba8b22ca
49
49
  zh: 2b6f672bb2ac84ba
50
50
  /deepseek-ai-dsh-goal/further-exploration:
51
- en: d94098c1e3f3c8cf
52
- zh: f4be4de55703097a
51
+ en: 11e7ecd3115d0b6b
52
+ zh: d1dff8b7d05a2f09
53
53
  /deepseek-ai-dsh-goal/model-experience:
54
54
  en: 215e7ba838619b7b
55
55
  zh: a311da3843709f90
package/README.md CHANGED
@@ -109,7 +109,6 @@ This section explains how the service realizes the behavior above; the observabl
109
109
  | [`src/types.ts`](src/types.ts) | Pure client-safe types: `GoalView`, `GoalSnapshot`, `GoalActivationChanged`, projection-key declaration |
110
110
  | [`src/fold.ts`](src/fold.ts) | Strict replay fold and decoder for durable goal changes |
111
111
  | [`src/runtime.ts`](src/runtime.ts) | `GoalId` brand, `GoalError` codes, change-version constant |
112
- | [`src/invariant.ts`](src/invariant.ts) | Invariant companion: independent incremental fold over every attached session |
113
112
 
114
113
  ### Events and attribution
115
114
 
@@ -127,7 +126,7 @@ The package-level contract is enough for most consumers; read these when you nee
127
126
  - [Goal subsystem](../../../docs/subsystems/goal.md) — the goal types, durable change payloads, and generated service API.
128
127
  - [Goal group map](../README.md) — the goal packages and how they compose.
129
128
  - [Generated configuration catalog](../../../docs/config-catalog.md#deepseek-aidsh-goal) — every accepted config field and its source declaration.
130
- - [Goal domain Agent Note](../../../.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.md) — the domain design, alternatives, and decisions.
129
+ - [historical Goal domain Agent Note](../../../.agents/notes/archived/feature/2026-07-19-persisted-same-session-goal-domain.md) — the domain design, alternatives, and decisions.
131
130
 
132
131
  -----
133
132
 
package/README.zh.md CHANGED
@@ -109,7 +109,6 @@ view.activation // 'armed' | 'disarmed' — not persisted
109
109
  | [`src/types.ts`](src/types.ts) | 纯客户端安全类型:`GoalView`、`GoalSnapshot`、`GoalActivationChanged`、投影键声明 |
110
110
  | [`src/fold.ts`](src/fold.ts) | 持久 goal 变更的严格回放折叠与解码器 |
111
111
  | [`src/runtime.ts`](src/runtime.ts) | `GoalId` 品牌、`GoalError` 代码、变更版本常量 |
112
- | [`src/invariant.ts`](src/invariant.ts) | 不变式配套模块:对每个已挂接会话的独立增量折叠 |
113
112
 
114
113
  ### 事件与归属
115
114
 
@@ -127,7 +126,7 @@ view.activation // 'armed' | 'disarmed' — not persisted
127
126
  - [goal 子系统](../../../docs/subsystems/goal.zh.md)——goal 类型、持久的变更载荷与生成的服务 API。
128
127
  - [goal 组地图](../README.zh.md)——goal 各包及其组合方式。
129
128
  - [生成的配置目录](../../../docs/config-catalog.zh.md#deepseek-aidsh-goal)——每个受支持配置字段及其源声明。
130
- - [goal 领域 Agent Note](../../../.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.zh.md)——领域设计、备选方案与决策。
129
+ - [历史goal 领域 Agent Note](../../../.agents/notes/archived/feature/2026-07-19-persisted-same-session-goal-domain.md)——领域设计、备选方案与决策。
131
130
 
132
131
  -----
133
132
 
@@ -775,16 +775,28 @@ export const TYPERT = {
775
775
  },
776
776
  {
777
777
  "name": "LlmCallConfig",
778
- "declaration": "export interface LlmCallConfig {\n provider: string;\n model: string;\n reasoningEffort?: ReasoningEffortId;\n temperature?: number;\n maxTokens?: number;\n stop?: string[];\n}"
778
+ "declaration": "export interface LlmCallConfig extends LlmCallControls {\n provider: string;\n model: string;\n}"
779
779
  },
780
780
  {
781
781
  "name": "LlmCallConfigAdapterDefaults",
782
782
  "declaration": "export interface LlmCallConfigAdapterDefaults {\n reasoningEffort?: true;\n maxTokens?: true;\n}"
783
783
  },
784
+ {
785
+ "name": "LlmCallControls",
786
+ "declaration": "export interface LlmCallControls {\n reasoningEffort?: ReasoningEffortId;\n temperature?: number;\n maxTokens?: number;\n stop?: string[];\n}"
787
+ },
784
788
  {
785
789
  "name": "LlmFailure",
786
790
  "declaration": "export interface LlmFailure {\n readonly message: string;\n readonly code: string;\n readonly status?: number;\n readonly providerRetryAfterMs?: number;\n readonly requestId?: ProviderRequestId;\n readonly offloadImages?: number;\n}"
787
791
  },
792
+ {
793
+ "name": "LlmRetryEventData",
794
+ "declaration": "export type LlmRetryEventData = { retryId: RetryId; turn: number; step: number; provider: string; mode: 'normal'; policyKey: string; retry: number; maxRetries: number; delayMs: number; failure: LlmFailure; } | { retryId: RetryId; turn: number; step: number; provider: string; mode: 'always'; policyKey: string; retry: number; delayMs: number; failure: LlmFailure; };"
795
+ },
796
+ {
797
+ "name": "LlmRetryStartedEventData",
798
+ "declaration": "export interface LlmRetryStartedEventData {\n retryId: RetryId;\n turn: number;\n step: number;\n retry: number;\n}"
799
+ },
788
800
  {
789
801
  "name": "Message",
790
802
  "declaration": "export type Message = MessageRoleMap[keyof MessageRoleMap];"
@@ -827,7 +839,7 @@ export const TYPERT = {
827
839
  },
828
840
  {
829
841
  "name": "MessageSourceMap",
830
- "declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n model: ModelMessageSource;\n tool: ToolMessageSource;\n 'system-prompt': SystemPromptMessageSource;\n 'model-selection': { kind: 'model-selection'; } & ContextFormed;\n 'user-approval': { kind: 'user-approval'; } & ContextFormed;\n 'ptc-mode': { kind: 'ptc-mode'; };\n 'tool-registry': { kind: 'tool-registry'; };\n 'user-rpc': { kind: 'user'; rpcId: SessionRequestId; clientTimeZone?: string; };\n 'agent-message': AgentMessageSource;\n 'subagent-settled': SubagentSettledMessageSource;\n 'skill-invocation': SkillInvocationSource;\n 'cordis-host-runner': { kind: 'cordis-host-runner'; };\n goal: GoalMessageSource;\n schedule: { kind: 'schedule'; } & ContextFormed;\n 'compact-checkpoint': CompactionCheckpointSource;\n 'session-reference': SessionReferenceSource;\n 'user-question-reply': { kind: 'user-question-reply'; callId: ToolCallId; outcome: 'answered'; };\n}"
842
+ "declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n model: ModelMessageSource;\n tool: ToolMessageSource;\n 'system-prompt': SystemPromptMessageSource;\n 'model-selection': { kind: 'model-selection'; } & ContextFormed;\n 'working-directory': { kind: 'working-directory'; };\n 'user-approval': { kind: 'user-approval'; } & ContextFormed;\n 'ptc-mode': { kind: 'ptc-mode'; };\n 'tool-registry': { kind: 'tool-registry'; };\n 'user-rpc': { kind: 'user'; rpcId: SessionRequestId; clientTimeZone?: string; };\n 'agent-message': AgentMessageSource;\n 'subagent-settled': SubagentSettledMessageSource;\n 'skill-invocation': SkillInvocationSource;\n 'cordis-host-runner': { kind: 'cordis-host-runner'; };\n 'compact-checkpoint': CompactionCheckpointSource;\n 'user-question-reply': { kind: 'user-question-reply'; callId: ToolCallId; outcome: 'answered'; };\n goal: GoalMessageSource;\n schedule: { kind: 'schedule'; } & ContextFormed;\n 'session-reference': SessionReferenceSource;\n}"
831
843
  },
832
844
  {
833
845
  "name": "ModelMessageSource",
@@ -855,7 +867,7 @@ export const TYPERT = {
855
867
  },
856
868
  {
857
869
  "name": "PtcDispatchEventData",
858
- "declaration": "export interface PtcDispatchEventData extends PtcDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n error?: { name: string; code: string; reason?: string; };\n}"
870
+ "declaration": "export interface PtcDispatchEventData extends PtcDispatchStartEventData {\n isError: boolean;\n content: ContentBlock[];\n meta?: JsonValue;\n error?: { name: string; code: string; reason?: string; };\n}"
859
871
  },
860
872
  {
861
873
  "name": "PtcDispatchStartEventData",
@@ -881,6 +893,10 @@ export const TYPERT = {
881
893
  "name": "RequestHeaderReason",
882
894
  "declaration": "export type RequestHeaderReason = 'initial' | 'resume' | 'change' | 'series';"
883
895
  },
896
+ {
897
+ "name": "RetryId",
898
+ "declaration": "export type RetryId = Branded<'RetryId'>;"
899
+ },
884
900
  {
885
901
  "name": "SandboxMode",
886
902
  "declaration": "export type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';"
@@ -915,7 +931,7 @@ export const TYPERT = {
915
931
  },
916
932
  {
917
933
  "name": "SessionEventMap",
918
- "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'developer/message': { turn: number; step: number; message: DeveloperMessage; headerSeq?: SessionSeq; };\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; reason?: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'image/offload': { targets: ImageOffloadTarget[]; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'permission/preset': { preset: string; };\n 'subagent/catalog': SubagentCatalogEvent;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n 'feedback/record': FeedbackRecord;\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'schedule/change': ScheduleChange;\n}"
934
+ "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'developer/message': { turn: number; step: number; message: DeveloperMessage; headerSeq?: SessionSeq; };\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; reason?: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'working-directory/change': { cwd: string; };\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'image/offload': { targets: ImageOffloadTarget[]; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'permission/preset': { preset: string; };\n 'subagent/descriptor': SubagentDescriptorData;\n 'subagent/catalog': SubagentCatalogEvent;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n 'feedback/record': FeedbackRecord;\n 'llm/retry': LlmRetryEventData;\n 'llm/retry-started': LlmRetryStartedEventData;\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'schedule/change': ScheduleChange;\n}"
919
935
  },
920
936
  {
921
937
  "name": "SessionEventType",
@@ -975,7 +991,7 @@ export const TYPERT = {
975
991
  },
976
992
  {
977
993
  "name": "SubagentCatalogEvent",
978
- "declaration": "export type SubagentCatalogEvent = { readonly childId: SessionId; readonly childCreatedAt: number; } & (({ readonly version: 0; } & KnownCatalogMode) | ({ readonly version: 1; } & (KnownCatalogMode | { readonly mode: 'unknown'; readonly label?: string; })));"
994
+ "declaration": "export type SubagentCatalogEvent = { readonly childId: SessionId; readonly childCreatedAt: number; } & (({ readonly version: 0; } & KnownCatalogMode) | ({ readonly version: 1; } & (KnownCatalogMode | { readonly mode: 'unknown'; readonly label?: string; })) | { readonly version: 2; readonly mode: 'external'; readonly label?: string; });"
979
995
  },
980
996
  {
981
997
  "name": "SubagentDescriptorBase",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-goal",
3
3
  "description": "Event-sourced same-session goal state and lifecycle service for the DeepSeek Harness",
4
- "version": "0.2.0-rc.2",
4
+ "version": "0.2.1-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -18,10 +18,6 @@
18
18
  "types": "./lib/types/index.d.ts",
19
19
  "default": "./lib/index.js"
20
20
  },
21
- "./invariant": {
22
- "types": "./lib/types/invariant.d.ts",
23
- "default": "./lib/invariant.js"
24
- },
25
21
  "./types": {
26
22
  "types": "./lib/types/types.d.ts",
27
23
  "default": "./lib/types/types.js"
@@ -43,7 +39,6 @@
43
39
  },
44
40
  "files": [
45
41
  "lib/index.js",
46
- "lib/invariant.js",
47
42
  "lib/types/**/*.js",
48
43
  "lib/types/**/*.d.ts",
49
44
  "lib/typert.host.js",
@@ -53,36 +48,34 @@
53
48
  ],
54
49
  "license": "MIT",
55
50
  "peerDependencies": {
56
- "@deepseek-ai/dsh-session-projection": "0.2.0-rc.2",
57
- "@deepseek-ai/dsh-brand": "0.2.0-rc.2",
58
- "@deepseek-ai/dsh-invariants": "0.2.0-rc.2",
59
- "@deepseek-ai/dsh-agent": "0.2.0-rc.2",
60
- "@deepseek-ai/dsh-llm": "0.2.0-rc.2",
61
- "@deepseek-ai/dsh-session": "0.2.0-rc.2",
62
- "@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2",
63
- "@deepseek-ai/cordis": "~4.0.4",
64
- "@deepseek-ai/dsh-scope": "0.2.0-rc.2"
51
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
52
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
53
+ "@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
54
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
55
+ "@deepseek-ai/dsh-scope": "0.2.1-alpha.2",
56
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
57
+ "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2",
58
+ "@deepseek-ai/cordis": "~4.0.5-alpha.1"
65
59
  },
66
60
  "dependencies": {
67
- "zod": "^4.4.3",
68
- "@deepseek-ai/schemastery": "~3.18.4"
61
+ "@deepseek-ai/schemastery": "~3.18.5-alpha.1",
62
+ "zod": "^4.4.3"
69
63
  },
70
64
  "devDependencies": {
71
- "@deepseek-ai/dsh-agent": "0.2.0-rc.2",
72
- "@deepseek-ai/dsh-bash-local": "0.2.0-rc.2",
73
- "@deepseek-ai/dsh-agent-loop": "0.2.0-rc.2",
74
- "@deepseek-ai/dsh-agent-loop-testkit": "0.2.0-rc.2",
75
- "@deepseek-ai/dsh-session-projection": "0.2.0-rc.2",
76
- "@deepseek-ai/dsh-brand": "0.2.0-rc.2",
77
- "@deepseek-ai/dsh-invariants": "0.2.0-rc.2",
78
- "@deepseek-ai/dsh-scope": "0.2.0-rc.2",
79
- "@deepseek-ai/dsh-session": "0.2.0-rc.2",
80
- "@deepseek-ai/dsh-session-checkpoint-policy": "0.2.0-rc.2",
81
- "@deepseek-ai/dsh-session-persistence-jsonl": "0.2.0-rc.2",
82
- "@deepseek-ai/dsh-subprocess-local": "0.2.0-rc.2",
83
- "@deepseek-ai/cordis": "~4.0.4",
84
- "@deepseek-ai/dsh-loader-smoke": "0.2.0-rc.2",
85
- "@deepseek-ai/dsh-llm": "0.2.0-rc.2",
86
- "@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2"
65
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
66
+ "@deepseek-ai/dsh-agent-loop": "0.2.1-alpha.2",
67
+ "@deepseek-ai/dsh-agent-loop-testkit": "0.2.1-alpha.2",
68
+ "@deepseek-ai/dsh-bash-local": "0.2.1-alpha.2",
69
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
70
+ "@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
71
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
72
+ "@deepseek-ai/dsh-loader-smoke": "0.2.1-alpha.2",
73
+ "@deepseek-ai/dsh-scope": "0.2.1-alpha.2",
74
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
75
+ "@deepseek-ai/dsh-session-checkpoint-policy": "0.2.1-alpha.2",
76
+ "@deepseek-ai/dsh-session-persistence-jsonl": "0.2.1-alpha.2",
77
+ "@deepseek-ai/dsh-subprocess-local": "0.2.1-alpha.2",
78
+ "@deepseek-ai/dsh-typert-protocol": "0.2.1-alpha.2",
79
+ "@deepseek-ai/cordis": "~4.0.5-alpha.1"
87
80
  }
88
81
  }
package/lib/invariant.js DELETED
@@ -1,332 +0,0 @@
1
- import "@deepseek-ai/dsh-llm";
2
- //#region lib/types/runtime.js
3
- /**
4
- * Brand a string as a goal id.
5
- * @param id - raw goal identifier.
6
- * @returns the same string with the compile-time brand.
7
- */
8
- function GoalId(id) {
9
- return id;
10
- }
11
- //#endregion
12
- //#region lib/types/fold.js
13
- /** Pure replay fold and strict decoder for durable goal changes. */
14
- const SNAPSHOT_OPERATIONS = new Set([
15
- "create",
16
- "edit",
17
- "pause",
18
- "resume",
19
- "complete",
20
- "block"
21
- ]);
22
- const PHASES = new Set([
23
- "active",
24
- "paused",
25
- "blocked",
26
- "complete"
27
- ]);
28
- /**
29
- * Build an empty replay accumulator.
30
- * @returns mutable state with no current goal or prior ref.
31
- */
32
- function emptyGoalFoldState() {
33
- return {
34
- goal: void 0,
35
- roundsStarted: 0,
36
- createdAt: void 0,
37
- updatedAt: void 0,
38
- lastRef: void 0,
39
- seenGoalIds: /* @__PURE__ */ new Set()
40
- };
41
- }
42
- /** Whether a value is a JSON record rather than an array. */
43
- function isRecord(value) {
44
- return typeof value === "object" && value !== null && !Array.isArray(value);
45
- }
46
- /** Require one positive safe integer. */
47
- function positiveInteger(value, field) {
48
- if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1) throw new Error(`goal change ${field} must be a positive safe integer`);
49
- return value;
50
- }
51
- /** Require one non-negative safe integer. */
52
- function nonNegativeInteger(value, field) {
53
- if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) throw new Error(`goal change ${field} must be a non-negative safe integer`);
54
- return value;
55
- }
56
- /** Decode one canonical blocker explanation. */
57
- function decodeBlockReason(value) {
58
- if (!isRecord(value) || Object.keys(value).sort().join(",") !== "code,message") throw new Error("goal change goal.blockedReason must have exactly code and message fields");
59
- if (typeof value["code"] !== "string" || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(value["code"])) throw new Error("goal change goal.blockedReason.code must be lower-kebab-case");
60
- if (typeof value["message"] !== "string" || value["message"].trim().length === 0 || value["message"] !== value["message"].trim()) throw new Error("goal change goal.blockedReason.message must be non-empty and normalized");
61
- return {
62
- code: value["code"],
63
- message: value["message"]
64
- };
65
- }
66
- /** Decode and validate one snapshot. */
67
- function decodeSnapshot(value) {
68
- if (!isRecord(value)) throw new Error("goal change goal must be a record");
69
- if (typeof value["id"] !== "string" || value["id"].length === 0) throw new Error("goal change goal.id must be a non-empty string");
70
- if (typeof value["objective"] !== "string" || value["objective"].trim().length === 0 || value["objective"] !== value["objective"].trim()) throw new Error("goal change goal.objective must be non-empty and normalized");
71
- if (typeof value["phase"] !== "string" || !PHASES.has(value["phase"])) throw new Error("goal change goal.phase is invalid");
72
- const phase = value["phase"];
73
- const expectedKeys = phase === "blocked" ? "blockedReason,id,maxGoalRounds,objective,phase,revision" : "id,maxGoalRounds,objective,phase,revision";
74
- if (Object.keys(value).sort().join(",") !== expectedKeys) throw new Error(`goal change goal for phase ${phase} must have exactly ${expectedKeys} fields`);
75
- return {
76
- id: GoalId(value["id"]),
77
- revision: positiveInteger(value["revision"], "goal.revision"),
78
- objective: value["objective"],
79
- phase,
80
- maxGoalRounds: positiveInteger(value["maxGoalRounds"], "goal.maxGoalRounds"),
81
- ...phase === "blocked" ? { blockedReason: decodeBlockReason(value["blockedReason"]) } : {}
82
- };
83
- }
84
- /** Decode and validate one ref. */
85
- function decodeRef(value) {
86
- if (!isRecord(value) || Object.keys(value).sort().join(",") !== "id,revision") throw new Error("goal clear tombstone must have exactly id and revision fields");
87
- if (typeof value["id"] !== "string" || value["id"].length === 0) throw new Error("goal clear tombstone id must be a non-empty string");
88
- return {
89
- id: GoalId(value["id"]),
90
- revision: positiveInteger(value["revision"], "cleared.revision")
91
- };
92
- }
93
- /**
94
- * Decode a value that declares itself as a goal change. Unrelated values
95
- * return `undefined`; malformed goal changes fail replay loudly.
96
- * @param value - candidate source change.
97
- * @returns validated goal change or `undefined` for another value kind.
98
- */
99
- function decodeGoalChange(value) {
100
- if (!isRecord(value) || value["kind"] !== "goal/change") return void 0;
101
- if (value["version"] !== 1) throw new Error(`unsupported goal change version ${String(value["version"])}`);
102
- if (value["operation"] === "clear") {
103
- const allowed = [
104
- "cleared",
105
- "clearedAt",
106
- "kind",
107
- "operation",
108
- "version"
109
- ];
110
- if (Object.keys(value).sort().join(",") !== allowed.sort().join(",")) throw new Error(`goal clear change must have exactly ${allowed.sort().join(",")} fields`);
111
- return {
112
- kind: "goal/change",
113
- version: 1,
114
- operation: "clear",
115
- cleared: decodeRef(value["cleared"]),
116
- clearedAt: nonNegativeInteger(value["clearedAt"], "clearedAt")
117
- };
118
- }
119
- if (typeof value["operation"] !== "string" || !SNAPSHOT_OPERATIONS.has(value["operation"])) throw new Error("goal change operation is invalid");
120
- const allowed = [
121
- "createdAt",
122
- "goal",
123
- "kind",
124
- "operation",
125
- "roundsStarted",
126
- "updatedAt",
127
- "version"
128
- ];
129
- if (Object.keys(value).sort().join(",") !== allowed.sort().join(",")) throw new Error(`goal snapshot change must have exactly ${allowed.sort().join(",")} fields`);
130
- const createdAt = nonNegativeInteger(value["createdAt"], "createdAt");
131
- const updatedAt = nonNegativeInteger(value["updatedAt"], "updatedAt");
132
- if (updatedAt < createdAt) throw new Error("goal change updatedAt cannot precede createdAt");
133
- return {
134
- kind: "goal/change",
135
- version: 1,
136
- operation: value["operation"],
137
- goal: decodeSnapshot(value["goal"]),
138
- roundsStarted: nonNegativeInteger(value["roundsStarted"], "roundsStarted"),
139
- createdAt,
140
- updatedAt
141
- };
142
- }
143
- /** Narrow model attribution to a valid goal source. */
144
- function goalSource(source) {
145
- if (source.kind !== "goal") return void 0;
146
- if (typeof source.goalId !== "string" || source.goalId.length === 0 || !Number.isSafeInteger(source.revision) || source.revision < 1 || !Number.isSafeInteger(source.round) || source.round < 1) throw new Error("goal message source is invalid");
147
- return source;
148
- }
149
- /** Require two snapshots to retain fields that only `edit` may replace. */
150
- function requireSameDefinition(current, next, operation) {
151
- if (next.objective !== current.objective || next.maxGoalRounds !== current.maxGoalRounds) throw new Error(`goal ${operation} cannot change objective or maxGoalRounds`);
152
- }
153
- /** Require one exact next revision of the current goal. */
154
- function requireNextRevision(current, next, operation) {
155
- if (next.id !== current.id || next.revision !== current.revision + 1) throw new Error(`goal ${operation} must advance the current goal by one revision`);
156
- }
157
- /** Validate one non-create snapshot operation against the preceding projection. */
158
- function validateSnapshotTransition(state, change, current) {
159
- const next = change.goal;
160
- requireNextRevision(current, next, change.operation);
161
- /* v8 ignore next -- a current goal established by this fold always has an updatedAt */
162
- if (state.updatedAt === void 0) throw new Error("current goal fold lacks updatedAt");
163
- if (change.createdAt !== state.createdAt || change.updatedAt < state.updatedAt || change.roundsStarted !== state.roundsStarted) throw new Error(`goal ${change.operation} does not preserve the current counters and timestamps`);
164
- switch (change.operation) {
165
- case "edit":
166
- if (next.phase !== current.phase || JSON.stringify(next.blockedReason) !== JSON.stringify(current.blockedReason)) throw new Error("goal edit cannot change phase or blocked reason");
167
- break;
168
- case "pause":
169
- requireSameDefinition(current, next, change.operation);
170
- if (current.phase !== "active" || next.phase !== "paused") throw new Error("goal pause has an invalid phase transition");
171
- break;
172
- case "resume":
173
- requireSameDefinition(current, next, change.operation);
174
- if (!new Set([
175
- "active",
176
- "paused",
177
- "blocked"
178
- ]).has(current.phase) || next.phase !== "active" || state.roundsStarted >= next.maxGoalRounds) throw new Error("goal resume has an invalid phase transition or exhausted round budget");
179
- break;
180
- case "complete":
181
- requireSameDefinition(current, next, change.operation);
182
- if (current.phase === "complete" || next.phase !== "complete") throw new Error("goal complete has an invalid phase transition");
183
- break;
184
- case "block":
185
- requireSameDefinition(current, next, change.operation);
186
- if (current.phase !== "active" || next.phase !== "blocked") throw new Error("goal block has an invalid phase transition");
187
- break;
188
- /* v8 ignore start -- the caller excludes create and GoalOperation is closed; these arms retain fail-loud exhaustiveness */
189
- case "create": throw new Error("goal create cannot be validated as a current-goal transition");
190
- default:
191
- change.operation;
192
- throw new Error("unknown goal snapshot operation");
193
- }
194
- }
195
- /**
196
- * Return the revision identity carried by a snapshot or tombstone.
197
- * @param change - decoded goal mutation.
198
- * @returns stable identity used to reconcile a deferred change with its log event.
199
- */
200
- function goalChangeRef(change) {
201
- return change.operation === "clear" ? change.cleared : {
202
- id: change.goal.id,
203
- revision: change.goal.revision
204
- };
205
- }
206
- /**
207
- * Validate and apply one decoded change to a mutable accumulator.
208
- * @param state - preceding durable goal projection.
209
- * @param change - decoded full snapshot or clear tombstone.
210
- */
211
- function applyGoalChange(state, change) {
212
- const ref = goalChangeRef(change);
213
- if (change.operation === "clear") {
214
- const current = state.goal;
215
- if (current === void 0) throw new Error("goal clear requires a current goal");
216
- requireNextRevision(current, change.cleared, change.operation);
217
- /* v8 ignore next -- a current goal established by this fold always has an updatedAt */
218
- if (state.updatedAt === void 0) throw new Error("current goal fold lacks updatedAt");
219
- if (change.clearedAt < state.updatedAt) throw new Error("goal clear timestamp cannot precede the current goal update");
220
- state.goal = void 0;
221
- state.roundsStarted = 0;
222
- state.createdAt = void 0;
223
- state.updatedAt = void 0;
224
- state.lastRef = ref;
225
- return;
226
- }
227
- if (change.operation === "create") {
228
- if (change.goal.revision !== 1 || change.goal.phase !== "active" || change.roundsStarted !== 0 || state.goal !== void 0 && state.goal.phase !== "complete" || state.seenGoalIds.has(change.goal.id)) throw new Error("goal create requires a fresh active revision-one goal with zero rounds");
229
- state.seenGoalIds.add(change.goal.id);
230
- } else {
231
- const current = state.goal;
232
- if (current === void 0) throw new Error(`goal ${change.operation} requires a current goal`);
233
- validateSnapshotTransition(state, change, current);
234
- }
235
- state.goal = change.goal;
236
- state.roundsStarted = change.roundsStarted;
237
- state.createdAt = change.createdAt;
238
- state.updatedAt = change.updatedAt;
239
- state.lastRef = ref;
240
- }
241
- /**
242
- * Apply one session event to the strict durable goal fold.
243
- * @param state - mutable fold accumulator.
244
- * @param event - next event in sequence order.
245
- */
246
- function applyGoalEvent(state, event) {
247
- if (event.type === "goal/change") {
248
- const change = decodeGoalChange(event.data);
249
- /* v8 ignore next -- the event's declared payload always identifies itself as a goal change. */
250
- if (change === void 0) throw new Error(`goal change at session event ${event.seq} has an invalid kind`);
251
- applyGoalChange(state, change);
252
- return;
253
- }
254
- if (event.type === "user/message") {
255
- const source = goalSource(event.data.source);
256
- if (source === void 0) return;
257
- const current = state.goal;
258
- if (current === void 0 || current.phase !== "active" || source.goalId !== current.id || source.revision !== current.revision || source.round !== state.roundsStarted + 1 || source.round > current.maxGoalRounds) throw new Error(`goal round at session event ${event.seq} is not the next admitted round of the active goal`);
259
- state.roundsStarted = source.round;
260
- }
261
- }
262
- //#endregion
263
- //#region lib/types/invariant.js
264
- /** Package-owned durable goal-stream invariants. @module @deepseek-ai/dsh-goal/invariant */
265
- const PACKAGE_NAME = "@deepseek-ai/dsh-goal";
266
- /** Cordis companion plugin name. */
267
- const name = "goal-invariant";
268
- /** Service required before the companion can reserve package ownership. */
269
- const inject = ["invariants"];
270
- /** Copy the independent fold before validating one candidate event. */
271
- function cloneState(state) {
272
- return {
273
- goal: state.goal,
274
- roundsStarted: state.roundsStarted,
275
- createdAt: state.createdAt,
276
- updatedAt: state.updatedAt,
277
- lastRef: state.lastRef,
278
- seenGoalIds: new Set(state.seenGoalIds)
279
- };
280
- }
281
- /** Apply one event through the strict goal decoder and attribute failures. */
282
- function applyChecked(state, event, fail) {
283
- try {
284
- applyGoalEvent(state, event);
285
- } catch (error) {
286
- /* v8 ignore next -- the strict goal decoder throws Error instances */
287
- const message = error instanceof Error ? error.message : String(error);
288
- fail(`session event ${event.seq} violates the durable goal stream: ${message}`);
289
- }
290
- }
291
- /** Install an independent incremental fold over every attached session. */
292
- const install = Object.assign((ctx, fail) => {
293
- const states = /* @__PURE__ */ new WeakMap();
294
- const staged = /* @__PURE__ */ new WeakMap();
295
- const seed = (session) => {
296
- const state = emptyGoalFoldState();
297
- for (const event of session.snapshotEvents()) applyChecked(state, event, fail);
298
- states.set(session, state);
299
- return state;
300
- };
301
- /* v8 ignore next -- session/event always follows list() or session/created seeding */
302
- const stateFor = (session) => states.get(session) ?? seed(session);
303
- for (const session of ctx.sessions.list()) seed(session);
304
- ctx.on("session/created", (session) => {
305
- seed(session);
306
- }, { global: true });
307
- ctx.on("internal/dispatch", (_mode, eventName, args) => {
308
- if (eventName !== "session/event") return;
309
- const [session, event] = args;
310
- const state = cloneState(stateFor(session));
311
- applyChecked(state, event, fail);
312
- staged.set(event, {
313
- session,
314
- state
315
- });
316
- }, { global: true });
317
- ctx.on("session/event", (session, event) => {
318
- const candidate = staged.get(event);
319
- /* v8 ignore next 2 -- internal/dispatch stages the exact callback arguments */
320
- if (candidate === void 0 || candidate.session !== session) return fail("session/event reached publication without matching goal-fold validation");
321
- staged.delete(event);
322
- states.set(session, candidate.state);
323
- }, { global: true });
324
- }, { inject: ["sessions"] });
325
- /**
326
- * Register the goal-stream invariant companion.
327
- * @param ctx - Cordis context carrying the invariant service.
328
- * @returns the installed registration's disposer after setup succeeds.
329
- */
330
- const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
331
- //#endregion
332
- export { apply, inject, name };
@@ -1,13 +0,0 @@
1
- /** Package-owned durable goal-stream invariants. @module @deepseek-ai/dsh-goal/invariant */
2
- import type { Context } from '@deepseek-ai/cordis';
3
- /** Cordis companion plugin name. */
4
- export declare const name = "goal-invariant";
5
- /** Service required before the companion can reserve package ownership. */
6
- export declare const inject: string[];
7
- /**
8
- * Register the goal-stream invariant companion.
9
- * @param ctx - Cordis context carrying the invariant service.
10
- * @returns the installed registration's disposer after setup succeeds.
11
- */
12
- export declare const apply: (ctx: Context) => Promise<() => void>;
13
- //# sourceMappingURL=invariant.d.ts.map
@@ -1,71 +0,0 @@
1
- /** Package-owned durable goal-stream invariants. @module @deepseek-ai/dsh-goal/invariant */
2
- import { applyGoalEvent, emptyGoalFoldState } from "./fold.js";
3
- const PACKAGE_NAME = '@deepseek-ai/dsh-goal';
4
- /** Cordis companion plugin name. */
5
- export const name = 'goal-invariant';
6
- /** Service required before the companion can reserve package ownership. */
7
- export const inject = ['invariants'];
8
- /** Copy the independent fold before validating one candidate event. */
9
- function cloneState(state) {
10
- return {
11
- goal: state.goal,
12
- roundsStarted: state.roundsStarted,
13
- createdAt: state.createdAt,
14
- updatedAt: state.updatedAt,
15
- lastRef: state.lastRef,
16
- seenGoalIds: new Set(state.seenGoalIds),
17
- };
18
- }
19
- /** Apply one event through the strict goal decoder and attribute failures. */
20
- function applyChecked(state, event, fail) {
21
- try {
22
- applyGoalEvent(state, event);
23
- }
24
- catch (error) {
25
- /* v8 ignore next -- the strict goal decoder throws Error instances */
26
- const message = error instanceof Error ? error.message : String(error);
27
- fail(`session event ${event.seq} violates the durable goal stream: ${message}`);
28
- }
29
- }
30
- /** Install an independent incremental fold over every attached session. */
31
- const install = Object.assign((ctx, fail) => {
32
- const states = new WeakMap();
33
- const staged = new WeakMap();
34
- const seed = (session) => {
35
- const state = emptyGoalFoldState();
36
- // oxlint-disable-next-line typescript/no-deprecated -- Existing Session history read; migration deferred.
37
- for (const event of session.snapshotEvents())
38
- applyChecked(state, event, fail);
39
- states.set(session, state);
40
- return state;
41
- };
42
- /* v8 ignore next -- session/event always follows list() or session/created seeding */
43
- const stateFor = (session) => states.get(session) ?? seed(session);
44
- for (const session of ctx.sessions.list())
45
- seed(session);
46
- ctx.on('session/created', (session) => { seed(session); }, { global: true });
47
- ctx.on('internal/dispatch', (_mode, eventName, args) => {
48
- if (eventName !== 'session/event')
49
- return;
50
- const [session, event] = args;
51
- const state = cloneState(stateFor(session));
52
- applyChecked(state, event, fail);
53
- staged.set(event, { session, state });
54
- }, { global: true });
55
- ctx.on('session/event', (session, event) => {
56
- const candidate = staged.get(event);
57
- /* v8 ignore next 2 -- internal/dispatch stages the exact callback arguments */
58
- if (candidate === undefined || candidate.session !== session) {
59
- return fail('session/event reached publication without matching goal-fold validation');
60
- }
61
- staged.delete(event);
62
- states.set(session, candidate.state);
63
- }, { global: true });
64
- }, { inject: ['sessions'] });
65
- /**
66
- * Register the goal-stream invariant companion.
67
- * @param ctx - Cordis context carrying the invariant service.
68
- * @returns the installed registration's disposer after setup succeeds.
69
- */
70
- export const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
71
- //# sourceMappingURL=invariant.js.map