@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.
- package/README.i18n.yaml +2 -2
- package/README.md +11 -8
- package/README.zh.md +11 -8
- package/lib/index.js +41 -97
- package/lib/typert.host.js +69 -13
- package/lib/typert.remote-client.js +3 -3
- package/lib/types/assembler.d.ts +3 -3
- package/lib/types/assembler.js +4 -4
- package/lib/types/content.d.ts +30 -11
- package/lib/types/content.js +12 -64
- package/lib/types/index.d.ts +2 -2
- package/lib/types/index.js +3 -1
- package/lib/types/message.d.ts +69 -37
- package/lib/types/message.js +21 -16
- package/lib/types/types.d.ts +39 -12
- package/package.json +11 -11
package/lib/typert.host.js
CHANGED
|
@@ -74,7 +74,7 @@ export const TYPERT = {
|
|
|
74
74
|
typeSymbol: '@deepseek-ai/dsh-llm#llm/discoverModels:result',
|
|
75
75
|
create: _deepseek_ai_dsh_llm_llm_discoverModels_result$schema,
|
|
76
76
|
},
|
|
77
|
-
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":
|
|
77
|
+
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":633,"column":9},
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
id: '@deepseek-ai/dsh-llm#llm/listConfigurableProviders',
|
|
@@ -89,7 +89,7 @@ export const TYPERT = {
|
|
|
89
89
|
typeSymbol: '@deepseek-ai/dsh-llm#llm/listConfigurableProviders:result',
|
|
90
90
|
create: _deepseek_ai_dsh_llm_llm_listConfigurableProviders_result$schema,
|
|
91
91
|
},
|
|
92
|
-
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":
|
|
92
|
+
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":545,"column":3},
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
95
|
id: '@deepseek-ai/dsh-llm#llm/listProviders',
|
|
@@ -104,7 +104,7 @@ export const TYPERT = {
|
|
|
104
104
|
typeSymbol: '@deepseek-ai/dsh-llm#llm/listProviders:result',
|
|
105
105
|
create: _deepseek_ai_dsh_llm_llm_listProviders_result$schema,
|
|
106
106
|
},
|
|
107
|
-
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":
|
|
107
|
+
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":473,"column":3},
|
|
108
108
|
},
|
|
109
109
|
],
|
|
110
110
|
model: {
|
|
@@ -232,6 +232,10 @@ export const TYPERT = {
|
|
|
232
232
|
"name": "AgentMessageSource",
|
|
233
233
|
"declaration": "export interface AgentMessageSource {\n readonly kind: 'agent-message';\n readonly form: 'relay';\n readonly senderSessionId: SessionId;\n}"
|
|
234
234
|
},
|
|
235
|
+
{
|
|
236
|
+
"name": "AssistantMessage",
|
|
237
|
+
"declaration": "export interface AssistantMessage extends MessageBase {\n readonly role: 'assistant';\n readonly source: ModelMessageSource;\n}"
|
|
238
|
+
},
|
|
235
239
|
{
|
|
236
240
|
"name": "AssistantProviderMetadata",
|
|
237
241
|
"declaration": "export interface AssistantProviderMetadata {\n provider: string;\n model: string;\n replayState?: unknown;\n}"
|
|
@@ -248,13 +252,25 @@ export const TYPERT = {
|
|
|
248
252
|
"name": "BrandedNumber",
|
|
249
253
|
"declaration": "export type BrandedNumber<B extends string> = number & { readonly [BRAND]: B; };"
|
|
250
254
|
},
|
|
255
|
+
{
|
|
256
|
+
"name": "CommandId",
|
|
257
|
+
"declaration": "export type CommandId = Branded<'CommandId'>;"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"name": "CompactionCheckpointSource",
|
|
261
|
+
"declaration": "export type CompactionCheckpointSource = typeof COMPACT_CHECKPOINT_MARKER & { readonly compactionId: CompactionId; readonly sourceCommandId?: CommandId; };"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"name": "CompactionId",
|
|
265
|
+
"declaration": "export type CompactionId = Branded<'CompactionId'>;"
|
|
266
|
+
},
|
|
251
267
|
{
|
|
252
268
|
"name": "ContentBlock",
|
|
253
269
|
"declaration": "export type ContentBlock = ContentBlockMap[ContentBlockType];"
|
|
254
270
|
},
|
|
255
271
|
{
|
|
256
272
|
"name": "ContentBlockMap",
|
|
257
|
-
"declaration": "export interface ContentBlockMap {\n text: TextBlock;\n reasoning: ReasoningBlock;\n image: ImageBlock;\n file: FileBlock;\n 'tool-call': ToolCallBlock;\n 'tool-
|
|
273
|
+
"declaration": "export interface ContentBlockMap {\n text: TextBlock;\n reasoning: ReasoningBlock;\n image: ImageBlock;\n file: FileBlock;\n 'tool-call': ToolCallBlock;\n 'tool-addition': ToolAdditionBlock;\n 'tool-removal': ToolRemovalBlock;\n}"
|
|
258
274
|
},
|
|
259
275
|
{
|
|
260
276
|
"name": "ContentBlockType",
|
|
@@ -268,6 +284,10 @@ export const TYPERT = {
|
|
|
268
284
|
"name": "ContextSnapshotSection",
|
|
269
285
|
"declaration": "export interface ContextSnapshotSection {\n readonly name: string;\n readonly text: string;\n}"
|
|
270
286
|
},
|
|
287
|
+
{
|
|
288
|
+
"name": "DeveloperMessage",
|
|
289
|
+
"declaration": "export interface DeveloperMessage extends MessageBase {\n readonly role: 'developer';\n}"
|
|
290
|
+
},
|
|
271
291
|
{
|
|
272
292
|
"name": "DirectoryRegistrationHandle",
|
|
273
293
|
"declaration": "export interface DirectoryRegistrationHandle {\n (): void;\n replace(entries: readonly LlmConfigurableProvider[]): void;\n}"
|
|
@@ -290,7 +310,7 @@ export const TYPERT = {
|
|
|
290
310
|
},
|
|
291
311
|
{
|
|
292
312
|
"name": "GenerateOptions",
|
|
293
|
-
"declaration": "export interface GenerateOptions {\n provider: string;\n model: string;\n reasoningEffort?: ReasoningEffortId;\n messages:
|
|
313
|
+
"declaration": "export interface GenerateOptions {\n provider: string;\n model: string;\n reasoningEffort?: ReasoningEffortId;\n messages: RequestMessage[];\n system?: string;\n tools?: ToolSchema[];\n temperature?: number;\n maxTokens?: number;\n stop?: string[];\n signal?: AbortSignal;\n sessionId?: Branded<'SessionId'>;\n purpose?: 'compaction' | 'session-title';\n}"
|
|
294
314
|
},
|
|
295
315
|
{
|
|
296
316
|
"name": "GoalId",
|
|
@@ -374,19 +394,27 @@ export const TYPERT = {
|
|
|
374
394
|
},
|
|
375
395
|
{
|
|
376
396
|
"name": "Message",
|
|
377
|
-
"declaration": "export
|
|
397
|
+
"declaration": "export type Message = MessageRoleMap[keyof MessageRoleMap];"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
"name": "MessageBase",
|
|
401
|
+
"declaration": "export interface MessageBase {\n readonly id: MessageId;\n readonly content: readonly ContentBlock[];\n readonly source: MessageSource;\n}"
|
|
378
402
|
},
|
|
379
403
|
{
|
|
380
404
|
"name": "MessageId",
|
|
381
405
|
"declaration": "export type MessageId = Branded<'MessageId'>;"
|
|
382
406
|
},
|
|
407
|
+
{
|
|
408
|
+
"name": "MessageRoleMap",
|
|
409
|
+
"declaration": "export interface MessageRoleMap {\n system: SystemMessage;\n developer: DeveloperMessage;\n user: UserMessage;\n assistant: AssistantMessage;\n tool: ToolResultMessage;\n}"
|
|
410
|
+
},
|
|
383
411
|
{
|
|
384
412
|
"name": "MessageSource",
|
|
385
413
|
"declaration": "export type MessageSource = MessageSourceMap[keyof MessageSourceMap];"
|
|
386
414
|
},
|
|
387
415
|
{
|
|
388
416
|
"name": "MessageSourceMap",
|
|
389
|
-
"declaration": "export interface MessageSourceMap {\n user: { kind: 'user'; };\n
|
|
417
|
+
"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 'team-message': TeamMessageSource;\n goal: GoalMessageSource;\n 'compact-checkpoint': CompactionCheckpointSource;\n 'session-reference': SessionReferenceSource;\n}"
|
|
390
418
|
},
|
|
391
419
|
{
|
|
392
420
|
"name": "ModelMessageSource",
|
|
@@ -428,6 +456,14 @@ export const TYPERT = {
|
|
|
428
456
|
"name": "ReplayEnvelope",
|
|
429
457
|
"declaration": "export interface ReplayEnvelope {\n response: unknown;\n blocks?: readonly unknown[];\n}"
|
|
430
458
|
},
|
|
459
|
+
{
|
|
460
|
+
"name": "RequestMessage",
|
|
461
|
+
"declaration": "export type RequestMessage = Message | RequestUserInput;"
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
"name": "RequestUserInput",
|
|
465
|
+
"declaration": "export interface RequestUserInput {\n readonly role: 'user';\n readonly content: UserMessage['content'];\n readonly id?: never;\n readonly source?: never;\n}"
|
|
466
|
+
},
|
|
431
467
|
{
|
|
432
468
|
"name": "ResolvedAlwaysRetryPolicy",
|
|
433
469
|
"declaration": "export interface ResolvedAlwaysRetryPolicy extends ResolvedRetryBackoff {\n readonly mode: 'always';\n}"
|
|
@@ -472,6 +508,14 @@ export const TYPERT = {
|
|
|
472
508
|
"name": "SubagentSettledMessageSource",
|
|
473
509
|
"declaration": "export interface SubagentSettledMessageSource {\n readonly kind: 'subagent-settled';\n readonly form: 'notice';\n readonly summary: string;\n readonly senderSessionId: SessionId;\n}"
|
|
474
510
|
},
|
|
511
|
+
{
|
|
512
|
+
"name": "SystemMessage",
|
|
513
|
+
"declaration": "export interface SystemMessage extends MessageBase {\n readonly role: 'system';\n readonly source: MessageSourceMap['system-prompt'];\n}"
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
"name": "SystemPromptMessageSource",
|
|
517
|
+
"declaration": "export interface SystemPromptMessageSource {\n kind: 'system-prompt';\n}"
|
|
518
|
+
},
|
|
475
519
|
{
|
|
476
520
|
"name": "SystemPromptUpdate",
|
|
477
521
|
"declaration": "export type SystemPromptUpdate = 'in-history';"
|
|
@@ -496,6 +540,10 @@ export const TYPERT = {
|
|
|
496
540
|
"name": "TokenUsage",
|
|
497
541
|
"declaration": "export interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n totalTokens?: number;\n cacheReadTokens?: number;\n cacheWriteTokens?: number;\n reasoningTokens?: number;\n}"
|
|
498
542
|
},
|
|
543
|
+
{
|
|
544
|
+
"name": "ToolAdditionBlock",
|
|
545
|
+
"declaration": "export interface ToolAdditionBlock {\n type: 'tool-addition';\n toolName: string;\n tool?: never;\n}"
|
|
546
|
+
},
|
|
499
547
|
{
|
|
500
548
|
"name": "ToolCallBlock",
|
|
501
549
|
"declaration": "export interface ToolCallBlock {\n type: 'tool-call';\n id: ToolCallId;\n name: string;\n arguments: string;\n}"
|
|
@@ -509,12 +557,20 @@ export const TYPERT = {
|
|
|
509
557
|
"declaration": "export interface ToolMessageSource {\n kind: 'tool';\n callId: ToolCallId;\n}"
|
|
510
558
|
},
|
|
511
559
|
{
|
|
512
|
-
"name": "
|
|
513
|
-
"declaration": "export interface
|
|
560
|
+
"name": "ToolRemovalBlock",
|
|
561
|
+
"declaration": "export interface ToolRemovalBlock {\n type: 'tool-removal';\n toolName: string;\n}"
|
|
562
|
+
},
|
|
563
|
+
{
|
|
564
|
+
"name": "ToolResultMessage",
|
|
565
|
+
"declaration": "export interface ToolResultMessage extends MessageBase {\n readonly role: 'tool';\n readonly source: ToolMessageSource;\n readonly toolCallId: ToolCallId;\n readonly isError?: boolean;\n}"
|
|
514
566
|
},
|
|
515
567
|
{
|
|
516
568
|
"name": "ToolSchema",
|
|
517
|
-
"declaration": "export interface ToolSchema {\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n}"
|
|
569
|
+
"declaration": "export interface ToolSchema {\n deferLoading?: true;\n name: string;\n description: string;\n parameters: Record<string, unknown>;\n}"
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
"name": "UserMessage",
|
|
573
|
+
"declaration": "export interface UserMessage extends MessageBase {\n readonly role: 'user';\n}"
|
|
518
574
|
}
|
|
519
575
|
]
|
|
520
576
|
}
|
|
@@ -542,8 +598,8 @@ export const TYPERT = {
|
|
|
542
598
|
{
|
|
543
599
|
"name": "param",
|
|
544
600
|
"argument": "options",
|
|
545
|
-
"comment": "- the full request. A LOOP-built request carries the process-local {@link markAgentLoopRequest} identity and arrives deep-frozen (mutation throws): its content is a pure function of the session log (the reconstructability Agent Note), so listeners read it, never rewrite it. Hand-built calls do not carry that marker; their
|
|
546
|
-
"text": "@param options - the full request. A LOOP-built request carries the\n * process-local {@link markAgentLoopRequest} identity and arrives deep-frozen\n * (mutation throws): its content is a pure function of the session log (the\n * reconstructability Agent Note), so listeners read it, never rewrite it.\n * Hand-built calls do not carry that marker;
|
|
601
|
+
"comment": "- the full request. A LOOP-built request carries the process-local {@link markAgentLoopRequest} identity and arrives deep-frozen (mutation throws): its content is a pure function of the session log (the reconstructability Agent Note), so listeners read it, never rewrite it. Hand-built calls do not carry that marker; callers own their request inputs and must keep them unchanged until the stream settles.",
|
|
602
|
+
"text": "@param options - the full request. A LOOP-built request carries the\n * process-local {@link markAgentLoopRequest} identity and arrives deep-frozen\n * (mutation throws): its content is a pure function of the session log (the\n * reconstructability Agent Note), so listeners read it, never rewrite it.\n * Hand-built calls do not carry that marker; callers own their request\n * inputs and must keep them unchanged until the stream settles.\n *"
|
|
547
603
|
},
|
|
548
604
|
{
|
|
549
605
|
"name": "mode",
|
|
@@ -551,7 +607,7 @@ export const TYPERT = {
|
|
|
551
607
|
"text": "@mode waterfall"
|
|
552
608
|
}
|
|
553
609
|
],
|
|
554
|
-
"jsDoc": "/**\n * Waterfall around every streaming model call (retry, replay, routing).\n * Bound to the {@link LlmRuntime}; call `next()` to reach the resolved\n * adapter's stream, or yield your own chunks to short-circuit.\n * @param options - the full request. A LOOP-built request carries the\n * process-local {@link markAgentLoopRequest} identity and arrives deep-frozen\n * (mutation throws): its content is a pure function of the session log (the\n * reconstructability Agent Note), so listeners read it, never rewrite it.\n * Hand-built calls do not carry that marker;
|
|
610
|
+
"jsDoc": "/**\n * Waterfall around every streaming model call (retry, replay, routing).\n * Bound to the {@link LlmRuntime}; call `next()` to reach the resolved\n * adapter's stream, or yield your own chunks to short-circuit.\n * @param options - the full request. A LOOP-built request carries the\n * process-local {@link markAgentLoopRequest} identity and arrives deep-frozen\n * (mutation throws): its content is a pure function of the session log (the\n * reconstructability Agent Note), so listeners read it, never rewrite it.\n * Hand-built calls do not carry that marker; callers own their request\n * inputs and must keep them unchanged until the stream settles.\n * @mode waterfall\n */",
|
|
555
611
|
"name": "llm/stream",
|
|
556
612
|
"mode": "waterfall",
|
|
557
613
|
"signature": "'llm/stream'(this: LlmRuntime, options: GenerateOptions, next: () => AsyncIterable<StreamChunk>): AsyncIterable<StreamChunk>"
|
|
@@ -71,7 +71,7 @@ export const TYPERT_REMOTE = {
|
|
|
71
71
|
typeSymbol: '@deepseek-ai/dsh-llm#llm/discoverModels:result',
|
|
72
72
|
create: _deepseek_ai_dsh_llm_llm_discoverModels_result$schema,
|
|
73
73
|
},
|
|
74
|
-
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":
|
|
74
|
+
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":633,"column":9},
|
|
75
75
|
},
|
|
76
76
|
{
|
|
77
77
|
id: '@deepseek-ai/dsh-llm#llm/listConfigurableProviders',
|
|
@@ -86,7 +86,7 @@ export const TYPERT_REMOTE = {
|
|
|
86
86
|
typeSymbol: '@deepseek-ai/dsh-llm#llm/listConfigurableProviders:result',
|
|
87
87
|
create: _deepseek_ai_dsh_llm_llm_listConfigurableProviders_result$schema,
|
|
88
88
|
},
|
|
89
|
-
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":
|
|
89
|
+
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":545,"column":3},
|
|
90
90
|
},
|
|
91
91
|
{
|
|
92
92
|
id: '@deepseek-ai/dsh-llm#llm/listProviders',
|
|
@@ -101,7 +101,7 @@ export const TYPERT_REMOTE = {
|
|
|
101
101
|
typeSymbol: '@deepseek-ai/dsh-llm#llm/listProviders:result',
|
|
102
102
|
create: _deepseek_ai_dsh_llm_llm_listProviders_result$schema,
|
|
103
103
|
},
|
|
104
|
-
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":
|
|
104
|
+
sourceLocation: {"file":"packages/llm/llm/src/index.ts","line":473,"column":3},
|
|
105
105
|
},
|
|
106
106
|
],
|
|
107
107
|
}
|
package/lib/types/assembler.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module @deepseek-ai/dsh-llm/assembler
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { AssistantMessage, ModelMessageSource } from './message.ts';
|
|
9
9
|
import type { ContentBlock, FinishReason, ReplayEnvelope, StreamChunk, TokenUsage } from './types.ts';
|
|
10
10
|
/**
|
|
11
11
|
* Incrementally assembles raw {@link StreamChunk}s into complete
|
|
@@ -67,9 +67,9 @@ export declare class BlockAssembler {
|
|
|
67
67
|
get replayState(): ReplayEnvelope | undefined;
|
|
68
68
|
/**
|
|
69
69
|
* The assembled assistant message.
|
|
70
|
-
* @param source -
|
|
70
|
+
* @param source - provider/model attribution (without the `kind` tag) for the assembled message.
|
|
71
71
|
* @returns a frozen assistant-role message over `blocks()` (same open-block assembly rules).
|
|
72
72
|
*/
|
|
73
|
-
message(source
|
|
73
|
+
message(source: Omit<ModelMessageSource, 'kind'>): AssistantMessage;
|
|
74
74
|
}
|
|
75
75
|
//# sourceMappingURL=assembler.d.ts.map
|
package/lib/types/assembler.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { brandString } from '@deepseek-ai/dsh-brand';
|
|
9
9
|
import { assertNever } from '@deepseek-ai/dsh-util-values';
|
|
10
|
-
import {
|
|
10
|
+
import { createAssistantMessage } from "./message.js";
|
|
11
11
|
/**
|
|
12
12
|
* Incrementally assembles raw {@link StreamChunk}s into complete
|
|
13
13
|
* {@link ContentBlock}s and a final assistant {@link Message}.
|
|
@@ -181,11 +181,11 @@ export class BlockAssembler {
|
|
|
181
181
|
}
|
|
182
182
|
/**
|
|
183
183
|
* The assembled assistant message.
|
|
184
|
-
* @param source -
|
|
184
|
+
* @param source - provider/model attribution (without the `kind` tag) for the assembled message.
|
|
185
185
|
* @returns a frozen assistant-role message over `blocks()` (same open-block assembly rules).
|
|
186
186
|
*/
|
|
187
|
-
message(source
|
|
188
|
-
return
|
|
187
|
+
message(source) {
|
|
188
|
+
return createAssistantMessage({ content: this.blocks(), source });
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
//# sourceMappingURL=assembler.js.map
|
package/lib/types/content.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Content-block structure helpers. @module @deepseek-ai/dsh-llm/content */
|
|
2
2
|
import type { ContentBlock, ImageBlock, LlmImageRequestBudget } from './types.ts';
|
|
3
|
+
import type { RequestMessage } from './types.ts';
|
|
3
4
|
import type { Message } from './message.ts';
|
|
4
5
|
import type { AttachmentStore, FileAttachmentRef, ImageAttachmentRef, RequestImageAttachment } from '@deepseek-ai/dsh-attachment';
|
|
5
6
|
/** Execution-world path that model tools can use to read one normalized attachment. */
|
|
@@ -49,20 +50,18 @@ export declare function requestImageHandleText(ref: ImageAttachmentRef, version:
|
|
|
49
50
|
*/
|
|
50
51
|
export declare function offloadedImageText(ref: ImageAttachmentRef, access?: ImageAttachmentAccess): string;
|
|
51
52
|
/**
|
|
52
|
-
* True when typed model content contains an image block
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* survey), so a consumer cannot silently diverge on nesting depth.
|
|
53
|
+
* True when typed model content contains an image block. This is the one image
|
|
54
|
+
* walk shared by every image policy (capability gating, text-only
|
|
55
|
+
* serialization, compaction survey), so a consumer cannot silently diverge.
|
|
56
56
|
* @param content - typed model content blocks.
|
|
57
|
-
* @returns whether any
|
|
57
|
+
* @returns whether any block is an image.
|
|
58
58
|
*/
|
|
59
59
|
export declare function contentHasImage(content: readonly ContentBlock[]): boolean;
|
|
60
60
|
/**
|
|
61
|
-
* True when typed model content contains a file block
|
|
62
|
-
* tool-result content on the same recursion every file policy shares.
|
|
61
|
+
* True when typed model content contains a file block.
|
|
63
62
|
* Reads current content on every call without retaining scan results.
|
|
64
63
|
* @param content - typed model content blocks.
|
|
65
|
-
* @returns whether any
|
|
64
|
+
* @returns whether any block is a file.
|
|
66
65
|
*/
|
|
67
66
|
export declare function contentHasFile(content: readonly ContentBlock[]): boolean;
|
|
68
67
|
/**
|
|
@@ -75,7 +74,7 @@ export declare function contentHasFile(content: readonly ContentBlock[]): boolea
|
|
|
75
74
|
*/
|
|
76
75
|
export declare function fileHandleText(ref: FileAttachmentRef, readonlyPath: string | undefined): string;
|
|
77
76
|
/**
|
|
78
|
-
* Project
|
|
77
|
+
* Project request file content into deterministic handle text for every model
|
|
79
78
|
* route. Unlike images, no provider receives file blocks natively, so this
|
|
80
79
|
* projection is unconditional in request assembly.
|
|
81
80
|
* @param messages - complete request history.
|
|
@@ -83,6 +82,13 @@ export declare function fileHandleText(ref: FileAttachmentRef, readonlyPath: str
|
|
|
83
82
|
* @returns the original list without files, otherwise shallow message copies with handle text.
|
|
84
83
|
*/
|
|
85
84
|
export declare function projectFilesToText(messages: readonly Message[], resolvePath: (ref: FileAttachmentRef) => string | undefined): readonly Message[];
|
|
85
|
+
/**
|
|
86
|
+
* Project file content in mixed durable and request-only inputs.
|
|
87
|
+
* @param messages - complete request inputs.
|
|
88
|
+
* @param resolvePath - resolve a reference's execution-world read path.
|
|
89
|
+
* @returns original inputs without files, otherwise copies with handle text.
|
|
90
|
+
*/
|
|
91
|
+
export declare function projectFilesToText(messages: readonly RequestMessage[], resolvePath: (ref: FileAttachmentRef) => string | undefined): readonly RequestMessage[];
|
|
86
92
|
/**
|
|
87
93
|
* Project the surface's offloaded occurrences into deterministic text for one
|
|
88
94
|
* request. The offloaded set is a durable surface fact, so every route sends
|
|
@@ -92,6 +98,13 @@ export declare function projectFilesToText(messages: readonly Message[], resolve
|
|
|
92
98
|
* @returns the original list when nothing is offloaded, otherwise shallow message copies with placeholders.
|
|
93
99
|
*/
|
|
94
100
|
export declare function projectOffloadedImages(messages: readonly Message[], placeholder: (ref: ImageAttachmentRef) => string): readonly Message[];
|
|
101
|
+
/**
|
|
102
|
+
* Project offloaded images in mixed durable and request-only inputs.
|
|
103
|
+
* @param messages - complete request inputs.
|
|
104
|
+
* @param placeholder - replacement text for an offloaded attachment.
|
|
105
|
+
* @returns original messages or shallow copies with placeholders.
|
|
106
|
+
*/
|
|
107
|
+
export declare function projectOffloadedImages(messages: readonly RequestMessage[], placeholder: (ref: ImageAttachmentRef) => string): readonly RequestMessage[];
|
|
95
108
|
/**
|
|
96
109
|
* Number of oldest retained occurrences a route must still offload before a
|
|
97
110
|
* derived request fits its budget at the exact byte length the route sends;
|
|
@@ -102,11 +115,17 @@ export declare function projectOffloadedImages(messages: readonly Message[], pla
|
|
|
102
115
|
* @param versionBytes - exact request-version byte length of one retained occurrence.
|
|
103
116
|
* @returns how many more leading retained occurrences to offload.
|
|
104
117
|
*/
|
|
105
|
-
export declare function requiredImageOffload(messages: readonly
|
|
118
|
+
export declare function requiredImageOffload(messages: readonly RequestMessage[], budget: Pick<LlmImageRequestBudget, 'representation' | 'maxBytes' | 'maxImages' | 'byteQuantum' | 'countQuantum'>, versionBytes: (block: ImageBlock) => number): number;
|
|
106
119
|
/**
|
|
107
|
-
* Project
|
|
120
|
+
* Project request image content into deterministic text for an exact text-only model.
|
|
108
121
|
* @param messages - complete request history.
|
|
109
122
|
* @returns the original list without images, otherwise shallow message copies with stable placeholders.
|
|
110
123
|
*/
|
|
111
124
|
export declare function projectImagesForTextModel(messages: readonly Message[]): readonly Message[];
|
|
125
|
+
/**
|
|
126
|
+
* Project image content in mixed durable and request-only inputs for a text-only model.
|
|
127
|
+
* @param messages - complete request inputs.
|
|
128
|
+
* @returns original inputs without images, otherwise copies with stable placeholders.
|
|
129
|
+
*/
|
|
130
|
+
export declare function projectImagesForTextModel(messages: readonly RequestMessage[]): readonly RequestMessage[];
|
|
112
131
|
//# sourceMappingURL=content.d.ts.map
|
package/lib/types/content.js
CHANGED
|
@@ -78,28 +78,24 @@ export function offloadedImageText(ref, access) {
|
|
|
78
78
|
return `[${identity}${normalizedAccessText(ref, access)}]`;
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
81
|
-
* True when typed model content contains an image block
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* survey), so a consumer cannot silently diverge on nesting depth.
|
|
81
|
+
* True when typed model content contains an image block. This is the one image
|
|
82
|
+
* walk shared by every image policy (capability gating, text-only
|
|
83
|
+
* serialization, compaction survey), so a consumer cannot silently diverge.
|
|
85
84
|
* @param content - typed model content blocks.
|
|
86
|
-
* @returns whether any
|
|
85
|
+
* @returns whether any block is an image.
|
|
87
86
|
*/
|
|
88
87
|
export function contentHasImage(content) {
|
|
89
|
-
return content.some(block => block.type === 'image'
|
|
90
|
-
|| (block.type === 'tool-result' && contentHasImage(block.content)));
|
|
88
|
+
return content.some(block => block.type === 'image');
|
|
91
89
|
}
|
|
92
90
|
/**
|
|
93
|
-
* True when typed model content contains a file block
|
|
94
|
-
* tool-result content on the same recursion every file policy shares.
|
|
91
|
+
* True when typed model content contains a file block.
|
|
95
92
|
* Reads current content on every call without retaining scan results.
|
|
96
93
|
* @param content - typed model content blocks.
|
|
97
|
-
* @returns whether any
|
|
94
|
+
* @returns whether any block is a file.
|
|
98
95
|
*/
|
|
99
96
|
export function contentHasFile(content) {
|
|
100
97
|
for (const block of content) {
|
|
101
|
-
if (block.type === 'file'
|
|
102
|
-
|| (block.type === 'tool-result' && contentHasFile(block.content)))
|
|
98
|
+
if (block.type === 'file')
|
|
103
99
|
return true;
|
|
104
100
|
}
|
|
105
101
|
return false;
|
|
@@ -120,7 +116,7 @@ export function fileHandleText(ref, readonlyPath) {
|
|
|
120
116
|
}
|
|
121
117
|
return `[${identity}: verbatim read-only copy saved at ${quoted(readonlyPath)}. Read that path with your file tools when its contents are needed; copy it to a writable location before modifying it. When delegating file work, include this saved path in the delegation prompt; only subagents sharing this execution environment can read it.]`;
|
|
122
118
|
}
|
|
123
|
-
/** Replace every file occurrence
|
|
119
|
+
/** Replace every file occurrence with handle text. */
|
|
124
120
|
function replaceFilesWithHandles(blocks, resolvePath) {
|
|
125
121
|
let next;
|
|
126
122
|
for (const [index, block] of blocks.entries()) {
|
|
@@ -129,26 +125,10 @@ function replaceFilesWithHandles(blocks, resolvePath) {
|
|
|
129
125
|
next.push({ type: 'text', text: fileHandleText(block.attachment, resolvePath(block.attachment)) });
|
|
130
126
|
continue;
|
|
131
127
|
}
|
|
132
|
-
if (block.type === 'tool-result') {
|
|
133
|
-
const content = replaceFilesWithHandles(block.content, resolvePath);
|
|
134
|
-
if (content !== block.content) {
|
|
135
|
-
next ??= blocks.slice(0, index);
|
|
136
|
-
next.push({ ...block, content });
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
128
|
next?.push(block);
|
|
141
129
|
}
|
|
142
130
|
return next ?? blocks;
|
|
143
131
|
}
|
|
144
|
-
/**
|
|
145
|
-
* Project durable file history into deterministic handle text for every model
|
|
146
|
-
* route. Unlike images, no provider receives file blocks natively, so this
|
|
147
|
-
* projection is unconditional in request assembly.
|
|
148
|
-
* @param messages - complete request history.
|
|
149
|
-
* @param resolvePath - resolve one reference's current execution-world read path.
|
|
150
|
-
* @returns the original list without files, otherwise shallow message copies with handle text.
|
|
151
|
-
*/
|
|
152
132
|
export function projectFilesToText(messages, resolvePath) {
|
|
153
133
|
if (!messages.some(message => contentHasFile(message.content)))
|
|
154
134
|
return messages;
|
|
@@ -162,8 +142,7 @@ function base64Length(bytes) {
|
|
|
162
142
|
return Math.ceil(bytes / 3) * 4;
|
|
163
143
|
}
|
|
164
144
|
/**
|
|
165
|
-
* Visit every image occurrence of typed content in message order
|
|
166
|
-
* nested tool-result content.
|
|
145
|
+
* Visit every image occurrence of typed content in message order.
|
|
167
146
|
* @param content - typed model content blocks.
|
|
168
147
|
* @param visit - called once per occurrence.
|
|
169
148
|
*/
|
|
@@ -171,11 +150,9 @@ function visitImageBlocks(content, visit) {
|
|
|
171
150
|
for (const block of content) {
|
|
172
151
|
if (block.type === 'image')
|
|
173
152
|
visit(block);
|
|
174
|
-
else if (block.type === 'tool-result')
|
|
175
|
-
visitImageBlocks(block.content, visit);
|
|
176
153
|
}
|
|
177
154
|
}
|
|
178
|
-
/** Replace every offloaded occurrence
|
|
155
|
+
/** Replace every offloaded occurrence with its placeholder. */
|
|
179
156
|
function replaceOffloadedImages(blocks, placeholder) {
|
|
180
157
|
let next;
|
|
181
158
|
for (const [index, block] of blocks.entries()) {
|
|
@@ -184,26 +161,10 @@ function replaceOffloadedImages(blocks, placeholder) {
|
|
|
184
161
|
next.push({ type: 'text', text: placeholder(block.attachment) });
|
|
185
162
|
continue;
|
|
186
163
|
}
|
|
187
|
-
if (block.type === 'tool-result') {
|
|
188
|
-
const content = replaceOffloadedImages(block.content, placeholder);
|
|
189
|
-
if (content !== block.content) {
|
|
190
|
-
next ??= blocks.slice(0, index);
|
|
191
|
-
next.push({ ...block, content });
|
|
192
|
-
continue;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
164
|
next?.push(block);
|
|
196
165
|
}
|
|
197
166
|
return next ?? blocks;
|
|
198
167
|
}
|
|
199
|
-
/**
|
|
200
|
-
* Project the surface's offloaded occurrences into deterministic text for one
|
|
201
|
-
* request. The offloaded set is a durable surface fact, so every route sends
|
|
202
|
-
* the same set; only the placeholder text is route-owned.
|
|
203
|
-
* @param messages - derived request history.
|
|
204
|
-
* @param placeholder - build the model-visible replacement for one offloaded attachment.
|
|
205
|
-
* @returns the original list when nothing is offloaded, otherwise shallow message copies with placeholders.
|
|
206
|
-
*/
|
|
207
168
|
export function projectOffloadedImages(messages, placeholder) {
|
|
208
169
|
return messages.map((message) => {
|
|
209
170
|
const content = replaceOffloadedImages(message.content, placeholder);
|
|
@@ -263,7 +224,7 @@ export function requiredImageOffload(messages, budget, versionBytes) {
|
|
|
263
224
|
}
|
|
264
225
|
return offloadedImagePrefixCount(lengths, budget);
|
|
265
226
|
}
|
|
266
|
-
/** Replace every image occurrence
|
|
227
|
+
/** Replace every image occurrence for a text-only model. */
|
|
267
228
|
function replaceImagesForTextModel(blocks) {
|
|
268
229
|
let next;
|
|
269
230
|
for (const [index, block] of blocks.entries()) {
|
|
@@ -272,23 +233,10 @@ function replaceImagesForTextModel(blocks) {
|
|
|
272
233
|
next.push({ type: 'text', text: textOnlyImageText(block.attachment) });
|
|
273
234
|
continue;
|
|
274
235
|
}
|
|
275
|
-
if (block.type === 'tool-result') {
|
|
276
|
-
const content = replaceImagesForTextModel(block.content);
|
|
277
|
-
if (content !== block.content) {
|
|
278
|
-
next ??= blocks.slice(0, index);
|
|
279
|
-
next.push({ ...block, content });
|
|
280
|
-
continue;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
236
|
next?.push(block);
|
|
284
237
|
}
|
|
285
238
|
return next ?? blocks;
|
|
286
239
|
}
|
|
287
|
-
/**
|
|
288
|
-
* Project durable image history into deterministic text for an exact text-only model.
|
|
289
|
-
* @param messages - complete request history.
|
|
290
|
-
* @returns the original list without images, otherwise shallow message copies with stable placeholders.
|
|
291
|
-
*/
|
|
292
240
|
export function projectImagesForTextModel(messages) {
|
|
293
241
|
if (!messages.some(message => contentHasImage(message.content)))
|
|
294
242
|
return messages;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -38,8 +38,8 @@ declare module '@deepseek-ai/cordis' {
|
|
|
38
38
|
* process-local {@link markAgentLoopRequest} identity and arrives deep-frozen
|
|
39
39
|
* (mutation throws): its content is a pure function of the session log (the
|
|
40
40
|
* reconstructability Agent Note), so listeners read it, never rewrite it.
|
|
41
|
-
* Hand-built calls do not carry that marker;
|
|
42
|
-
* the
|
|
41
|
+
* Hand-built calls do not carry that marker; callers own their request
|
|
42
|
+
* inputs and must keep them unchanged until the stream settles.
|
|
43
43
|
* @mode waterfall
|
|
44
44
|
*/
|
|
45
45
|
'llm/stream'(this: LlmRuntime, options: GenerateOptions, next: () => AsyncIterable<StreamChunk>): AsyncIterable<StreamChunk>;
|
package/lib/types/index.js
CHANGED
|
@@ -773,8 +773,10 @@ let LlmRuntime = (() => {
|
|
|
773
773
|
/** Remove replay state whose historical route is owned by another adapter. */
|
|
774
774
|
forAdapter(options, adapter) {
|
|
775
775
|
const messages = options.messages.map((message) => {
|
|
776
|
+
if (message.role !== 'assistant')
|
|
777
|
+
return message;
|
|
776
778
|
const source = message.source;
|
|
777
|
-
if (
|
|
779
|
+
if (source.replayState === undefined)
|
|
778
780
|
return message;
|
|
779
781
|
if (this.adapters.get(source.provider)?.adapter === adapter)
|
|
780
782
|
return message;
|