@deepseek-ai/dsh-llm 0.1.6-alpha.2 → 0.1.7-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.
@@ -1,6 +1,6 @@
1
1
  /** Message value types, identity, and immutable construction helpers. */
2
2
  import type { MessageId, ToolCallId } from './brand.ts';
3
- import type { ContentBlock, ToolResultBlock } from './types.ts';
3
+ import type { ContentBlock } from './types.ts';
4
4
  /** Provider/model identity and adapter-private replay data for an assistant message. */
5
5
  export interface AssistantProviderMetadata {
6
6
  /** Provider route that produced the message. */
@@ -18,11 +18,15 @@ export interface AssistantProviderMetadata {
18
18
  export interface ModelMessageSource extends AssistantProviderMetadata {
19
19
  kind: 'model';
20
20
  }
21
- /** Required source of a user-role message carrying one tool result. */
21
+ /** Required source of a tool-role message carrying one tool result. */
22
22
  export interface ToolMessageSource {
23
23
  kind: 'tool';
24
24
  callId: ToolCallId;
25
25
  }
26
+ /** Required source of a system-role message produced by the system-prompt plugin. */
27
+ export interface SystemPromptMessageSource {
28
+ kind: 'system-prompt';
29
+ }
26
30
  /**
27
31
  * The kind of information in producer-supplied context, declared by the
28
32
  * producer in the same `MessageSource`.
@@ -88,24 +92,24 @@ export type ContextFormed = {
88
92
  readonly form: 'recall';
89
93
  };
90
94
  /**
91
- * Where a message (or injected content) came from.
92
- * Merge-extensible sum type — plugins add their own `kind`s.
95
+ * Where a message (or injected content) came from, in the harness's own
96
+ * vocabulary. Merge-extensible sum type — each producer declares its own
97
+ * `kind` in its own module; there is no shared catch-all `plugin` kind.
98
+ * Model and tool sources answer their role messages; user messages carry any
99
+ * producer's kind, and consumers fall through unknown kinds.
93
100
  */
94
101
  export interface MessageSourceMap {
95
102
  user: {
96
103
  kind: 'user';
97
104
  };
98
- plugin: {
99
- kind: 'plugin';
100
- plugin: string;
101
- } & ContextFormed;
102
105
  model: ModelMessageSource;
103
106
  tool: ToolMessageSource;
107
+ 'system-prompt': SystemPromptMessageSource;
104
108
  }
105
109
  /**
106
- * Bound for a `notice` summary. The account rides a collapsed transcript row
107
- * and is committed to the durable log, while its inputs — task labels, goal
108
- * objectives, tool arguments — are caller text with no length of their own.
110
+ * Bound for a `notice` summary. Producers commit the one-line account to the
111
+ * durable log; its inputs — task labels, goal objectives, tool arguments —
112
+ * are caller text with no length of their own.
109
113
  */
110
114
  export declare const CONTEXT_SUMMARY_MAX_CHARS = 120;
111
115
  /**
@@ -116,42 +120,62 @@ export declare const CONTEXT_SUMMARY_MAX_CHARS = 120;
116
120
  export declare function boundContextSummary(summary: string): string;
117
121
  /** Any known message source, derived from {@link MessageSourceMap}; switch on `kind` and fall through unknowns (merge-extensible). */
118
122
  export type MessageSource = MessageSourceMap[keyof MessageSourceMap];
119
- /** One immutable message representation shared by delivery, durable history, and model requests. */
120
- export interface Message {
123
+ /** Shared immutable fields of every conversation message. */
124
+ interface MessageBase {
121
125
  /** Stable identity preserved across every representation boundary. */
122
126
  readonly id: MessageId;
123
- /** Provider-neutral conversation role. */
124
- readonly role: 'system' | 'user' | 'assistant';
125
127
  /** Exact model-facing blocks. */
126
- readonly content: ContentBlock[];
127
- /** Required source fields supplied by the producer. */
128
+ readonly content: readonly ContentBlock[];
129
+ /** Required source fields supplied by the producer.
130
+ * @persistenceSource user developer
131
+ */
128
132
  readonly source: MessageSource;
129
133
  }
130
- /** A user-role specialization of the one shared message representation. */
131
- export interface UserMessage extends Message {
134
+ /** A rendered system prompt attributed to the system-prompt producer; empty content sends no prompt. */
135
+ export interface SystemMessage extends MessageBase {
136
+ readonly role: 'system';
137
+ readonly source: MessageSourceMap['system-prompt'];
138
+ }
139
+ /** Incremental agent session changes in conversation order, currently tool additions and removals. */
140
+ export interface DeveloperMessage extends MessageBase {
141
+ readonly role: 'developer';
142
+ }
143
+ /** A user-role specialization of the shared message representation. */
144
+ export interface UserMessage extends MessageBase {
132
145
  readonly role: 'user';
133
146
  }
134
147
  /** A model-produced assistant specialization of the shared message representation. */
135
- export interface AssistantMessage extends Message {
148
+ export interface AssistantMessage extends MessageBase {
136
149
  readonly role: 'assistant';
137
150
  readonly source: ModelMessageSource;
138
151
  }
152
+ /** A first-class tool-role message carrying the result of one tool invocation. */
153
+ export interface ToolResultMessage extends MessageBase {
154
+ readonly role: 'tool';
155
+ readonly source: ToolMessageSource;
156
+ /** Provider-issued id of the tool call this message answers. */
157
+ readonly toolCallId: ToolCallId;
158
+ /** Whether the tool invocation failed. */
159
+ readonly isError?: boolean;
160
+ }
139
161
  /**
140
- * A system-role specialization of the shared message representation: one
141
- * rendered system prompt attributed to the plugin that assembled it. Empty
142
- * `content` means "no system prompt" and projects to no wire message.
162
+ * The conversation messages persisted by Session, keyed by role. This map is
163
+ * closed because every model-visible role must have a durable Session event
164
+ * and an adapter projection.
143
165
  */
144
- export interface SystemMessage extends Message {
145
- readonly role: 'system';
146
- readonly source: MessageSourceMap['plugin'];
166
+ export interface MessageRoleMap {
167
+ system: SystemMessage;
168
+ developer: DeveloperMessage;
169
+ user: UserMessage;
170
+ assistant: AssistantMessage;
171
+ tool: ToolResultMessage;
147
172
  }
148
- /** A tool-result specialization whose model-facing block retains call correlation. */
149
- export interface ToolResultMessage extends Message {
150
- readonly role: 'user';
151
- readonly content: [ToolResultBlock];
152
- readonly source: ToolMessageSource;
153
- }
154
- type NewMessage = Omit<Message, 'id'>;
173
+ /** Any persisted conversation message, discriminated by its `role`. */
174
+ export type Message = MessageRoleMap[keyof MessageRoleMap];
175
+ type NewMessage = {
176
+ [Role in keyof MessageRoleMap]: Omit<MessageRoleMap[Role], 'id'>;
177
+ }[keyof MessageRoleMap];
178
+ type NewDeveloperMessage = Omit<DeveloperMessage, 'id' | 'role'>;
155
179
  type NewUserMessage = Omit<UserMessage, 'id' | 'role'>;
156
180
  type NewAssistantMessage = Omit<AssistantMessage, 'id' | 'role' | 'source'> & {
157
181
  readonly source: Omit<ModelMessageSource, 'kind'> & {
@@ -172,6 +196,15 @@ export declare function freezeMessage<T extends Message>(message: T): T;
172
196
  export declare function createMessage<T extends NewMessage>(input: T & {
173
197
  readonly id?: never;
174
198
  }): T & Pick<Message, 'id'>;
199
+ /**
200
+ * Create an identified, immutable developer message.
201
+ * @param input - content and producer source for the new message.
202
+ * @returns a detached developer message with a fresh identity.
203
+ */
204
+ export declare function createDeveloperMessage<T extends NewDeveloperMessage>(input: T & {
205
+ readonly id?: never;
206
+ readonly role?: never;
207
+ }): T & Pick<DeveloperMessage, 'id' | 'role'>;
175
208
  /**
176
209
  * Create one identified user-role message and freeze it before publication.
177
210
  * @param input - complete content and source for a new user message.
@@ -194,20 +227,19 @@ export declare function createAssistantMessage(input: NewAssistantMessage & {
194
227
  * Create and freeze one identified system-role message holding a rendered
195
228
  * system prompt.
196
229
  * @param text - the complete rendered prompt; `''` records "no system prompt".
197
- * @param plugin - the plugin that assembled the prompt.
198
230
  * @returns an immutable system message with a fresh stable identity.
199
231
  */
200
- export declare function createSystemMessage(text: string, plugin: string): SystemMessage;
232
+ export declare function createSystemMessage(text: string): SystemMessage;
201
233
  /** Input whose acceptance creates one tool-result message. */
202
234
  export interface ToolResultMessageInput {
203
235
  readonly callId: ToolCallId;
204
- readonly content: ContentBlock[];
236
+ readonly content: readonly ContentBlock[];
205
237
  readonly isError: boolean;
206
238
  }
207
239
  /**
208
240
  * Create and freeze one identified tool-result message.
209
241
  * @param input - call identity, raw result blocks, and outcome.
210
- * @returns an immutable user-role tool-result message.
242
+ * @returns an immutable tool-role message that answers the tool call.
211
243
  */
212
244
  export declare function createToolResultMessage(input: ToolResultMessageInput): ToolResultMessage;
213
245
  export {};
@@ -3,9 +3,9 @@ import { randomUUID } from '@deepseek-ai/dsh-util-crypto';
3
3
  import { brandString } from '@deepseek-ai/dsh-brand';
4
4
  import { deepFreeze } from '@deepseek-ai/dsh-util-values';
5
5
  /**
6
- * Bound for a `notice` summary. The account rides a collapsed transcript row
7
- * and is committed to the durable log, while its inputs — task labels, goal
8
- * objectives, tool arguments — are caller text with no length of their own.
6
+ * Bound for a `notice` summary. Producers commit the one-line account to the
7
+ * durable log; its inputs — task labels, goal objectives, tool arguments —
8
+ * are caller text with no length of their own.
9
9
  */
10
10
  export const CONTEXT_SUMMARY_MAX_CHARS = 120;
11
11
  /**
@@ -32,10 +32,18 @@ export function freezeMessage(message) {
32
32
  * @returns an immutable message with a fresh stable identity.
33
33
  */
34
34
  export function createMessage(input) {
35
- return freezeMessage({
35
+ return deepFreeze(structuredClone({
36
36
  ...input,
37
37
  id: brandString(randomUUID()),
38
- });
38
+ }));
39
+ }
40
+ /**
41
+ * Create an identified, immutable developer message.
42
+ * @param input - content and producer source for the new message.
43
+ * @returns a detached developer message with a fresh identity.
44
+ */
45
+ export function createDeveloperMessage(input) {
46
+ return createMessage({ ...input, role: 'developer' });
39
47
  }
40
48
  /**
41
49
  * Create one identified user-role message and freeze it before publication.
@@ -67,30 +75,27 @@ export function createAssistantMessage(input) {
67
75
  * Create and freeze one identified system-role message holding a rendered
68
76
  * system prompt.
69
77
  * @param text - the complete rendered prompt; `''` records "no system prompt".
70
- * @param plugin - the plugin that assembled the prompt.
71
78
  * @returns an immutable system message with a fresh stable identity.
72
79
  */
73
- export function createSystemMessage(text, plugin) {
80
+ export function createSystemMessage(text) {
74
81
  return createMessage({
75
82
  role: 'system',
76
83
  content: text.length === 0 ? [] : [{ type: 'text', text }],
77
- source: { kind: 'plugin', plugin },
84
+ source: { kind: 'system-prompt' },
78
85
  });
79
86
  }
80
87
  /**
81
88
  * Create and freeze one identified tool-result message.
82
89
  * @param input - call identity, raw result blocks, and outcome.
83
- * @returns an immutable user-role tool-result message.
90
+ * @returns an immutable tool-role message that answers the tool call.
84
91
  */
85
92
  export function createToolResultMessage(input) {
86
- return createUserMessage({
93
+ return createMessage({
94
+ role: 'tool',
87
95
  source: { kind: 'tool', callId: input.callId },
88
- content: [{
89
- type: 'tool-result',
90
- toolCallId: input.callId,
91
- content: input.content,
92
- isError: input.isError,
93
- }],
96
+ toolCallId: input.callId,
97
+ content: input.content,
98
+ isError: input.isError,
94
99
  });
95
100
  }
96
101
  //# sourceMappingURL=message.js.map
@@ -6,7 +6,7 @@
6
6
  import type { Branded } from '@deepseek-ai/dsh-brand';
7
7
  import type { FileAttachmentRef, ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
8
8
  import type { ToolCallId, ProviderRequestId, ReasoningEffortId } from './brand.ts';
9
- import type { Message } from './message.ts';
9
+ import type { Message, UserMessage } from './message.ts';
10
10
  declare module '@deepseek-ai/cordis' {
11
11
  interface Events {
12
12
  /**
@@ -21,7 +21,7 @@ declare module '@deepseek-ai/cordis' {
21
21
  'llm/adapters-updated'(): void;
22
22
  }
23
23
  }
24
- export type { AssistantMessage, AssistantProviderMetadata, Message, MessageSource, MessageSourceMap, ModelMessageSource, ToolMessageSource, ToolResultMessage, UserMessage, } from './message.ts';
24
+ export type { AssistantMessage, DeveloperMessage, AssistantProviderMetadata, Message, MessageSource, MessageSourceMap, ModelMessageSource, ToolMessageSource, ToolResultMessage, UserMessage, } from './message.ts';
25
25
  /** Serializable provider or transport failure facts; policy decides whether they are retryable. */
26
26
  export interface LlmFailure {
27
27
  /** Human-readable provider or transport failure. */
@@ -90,16 +90,27 @@ export interface ToolCallBlock {
90
90
  /** Raw JSON string as produced by the model. */
91
91
  arguments: string;
92
92
  }
93
- /** The result of a tool invocation, sent back to the model. */
94
- export interface ToolResultBlock {
95
- type: 'tool-result';
96
- toolCallId: ToolCallId;
97
- content: ContentBlock[];
98
- isError?: boolean;
93
+ /** Activates a tool definition from the developer event's referenced request header. */
94
+ export interface ToolAdditionBlock {
95
+ type: 'tool-addition';
96
+ /** Name of exactly one tool in the referenced historical header. */
97
+ toolName: string;
98
+ /**
99
+ * Reserved against inline definitions; the historical request header owns the schema.
100
+ * @persistenceReserved
101
+ */
102
+ tool?: never;
103
+ }
104
+ /** Records the dynamic removal of a tool identified by its session-local name. */
105
+ export interface ToolRemovalBlock {
106
+ type: 'tool-removal';
107
+ toolName: string;
99
108
  }
100
109
  /**
101
110
  * Merge-extensible content blocks keyed by `type`. New core blocks must land
102
- * with adapter, UI, and compaction support.
111
+ * with adapter, UI, and compaction support. Developer tool-change blocks are
112
+ * reserved for Session V4 persistence; providers and UI reject them until
113
+ * their producers and consumers are implemented together.
103
114
  */
104
115
  export interface ContentBlockMap {
105
116
  'text': TextBlock;
@@ -107,7 +118,8 @@ export interface ContentBlockMap {
107
118
  'image': ImageBlock;
108
119
  'file': FileBlock;
109
120
  'tool-call': ToolCallBlock;
110
- 'tool-result': ToolResultBlock;
121
+ 'tool-addition': ToolAdditionBlock;
122
+ 'tool-removal': ToolRemovalBlock;
111
123
  }
112
124
  /** The block `type` tag vocabulary; widens as plugins add entries to {@link ContentBlockMap}. */
113
125
  export type ContentBlockType = keyof ContentBlockMap;
@@ -430,11 +442,26 @@ export type StreamChunk = {
430
442
  * it from this package.
431
443
  */
432
444
  export interface ToolSchema {
445
+ /**
446
+ * Requests deferred loading of the tool definition into model context,
447
+ * independently of whether a tool-addition block records the tool.
448
+ * Uses Anthropic's defer_loading terminology.
449
+ */
450
+ deferLoading?: true;
433
451
  name: string;
434
452
  description: string;
435
453
  /** JSON Schema object for the arguments. */
436
454
  parameters: Record<string, unknown>;
437
455
  }
456
+ /** User input for one LLM request; it has no durable Session identity or source. */
457
+ export interface RequestUserInput {
458
+ readonly role: 'user';
459
+ readonly content: UserMessage['content'];
460
+ readonly id?: never;
461
+ readonly source?: never;
462
+ }
463
+ /** A durable conversation message or a user input used only for one request. */
464
+ export type RequestMessage = Message | RequestUserInput;
438
465
  /** A single model request, fully assembled. */
439
466
  export interface GenerateOptions {
440
467
  /** Registered provider route selecting the adapter instance. */
@@ -446,9 +473,9 @@ export interface GenerateOptions {
446
473
  * Ordered conversation messages, exactly as the provider sees them. A
447
474
  * loop-built request passes the derived history (dsh-agent-loop), whose
448
475
  * leading system-role message carries the system prompt; a hand-built
449
- * one-shot passes any list.
476
+ * one-shot may include identity-free user inputs.
450
477
  */
451
- messages: Message[];
478
+ messages: RequestMessage[];
452
479
  /**
453
480
  * System prompt text for one-shot callers; adapters map it to the provider's
454
481
  * system slot ahead of `messages`. Loop-built requests leave it undefined.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-llm",
3
3
  "description": "Provider-neutral LLM service interface for the DeepSeek Harness",
4
- "version": "0.1.6-alpha.2",
4
+ "version": "0.1.7-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -61,20 +61,20 @@
61
61
  ],
62
62
  "license": "MIT",
63
63
  "peerDependencies": {
64
- "@deepseek-ai/cordis": "^4.0.2"
64
+ "@deepseek-ai/cordis": "~4.0.4"
65
65
  },
66
66
  "dependencies": {
67
67
  "zod": "^4.4.3",
68
- "@deepseek-ai/dsh-brand": "^0.1.6-alpha.2",
69
- "@deepseek-ai/dsh-util-values": "^0.1.6-alpha.2",
70
- "@deepseek-ai/dsh-util-crypto": "^0.1.6-alpha.2",
71
- "@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2",
72
- "@deepseek-ai/dsh-timeout": "^0.1.6-alpha.2",
73
- "@deepseek-ai/schemastery": "^3.18.2"
68
+ "@deepseek-ai/dsh-util-crypto": "0.1.7-alpha.2",
69
+ "@deepseek-ai/schemastery": "~3.18.4",
70
+ "@deepseek-ai/dsh-timeout": "0.1.7-alpha.2",
71
+ "@deepseek-ai/dsh-brand": "0.1.7-alpha.2",
72
+ "@deepseek-ai/dsh-util-values": "0.1.7-alpha.2",
73
+ "@deepseek-ai/dsh-typert-protocol": "0.1.7-alpha.2"
74
74
  },
75
75
  "devDependencies": {
76
- "@deepseek-ai/dsh-attachment": "^0.1.6-alpha.2",
77
- "@deepseek-ai/dsh-invariants": "^0.1.6-alpha.2",
78
- "@deepseek-ai/cordis": "^4.0.2"
76
+ "@deepseek-ai/dsh-attachment": "0.1.7-alpha.2",
77
+ "@deepseek-ai/dsh-invariants": "0.1.7-alpha.2",
78
+ "@deepseek-ai/cordis": "~4.0.4"
79
79
  }
80
80
  }