@memberjunction/ai 6.1.0-edge.6 → 6.1.0-edge.7
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/dist/generic/baseLLM.d.ts +14 -0
- package/dist/generic/baseLLM.d.ts.map +1 -1
- package/dist/generic/baseLLM.js +40 -3
- package/dist/generic/baseLLM.js.map +1 -1
- package/dist/generic/baseRealtime.d.ts +110 -7
- package/dist/generic/baseRealtime.d.ts.map +1 -1
- package/dist/generic/baseRealtime.js +17 -7
- package/dist/generic/baseRealtime.js.map +1 -1
- package/dist/generic/chat.types.d.ts +202 -2
- package/dist/generic/chat.types.d.ts.map +1 -1
- package/dist/generic/chat.types.js +114 -1
- package/dist/generic/chat.types.js.map +1 -1
- package/dist/generic/modelConfiguration.d.ts +146 -31
- package/dist/generic/modelConfiguration.d.ts.map +1 -1
- package/dist/generic/modelConfiguration.js +22 -11
- package/dist/generic/modelConfiguration.js.map +1 -1
- package/dist/generic/openAICompatibleTools.d.ts +129 -0
- package/dist/generic/openAICompatibleTools.d.ts.map +1 -0
- package/dist/generic/openAICompatibleTools.js +94 -0
- package/dist/generic/openAICompatibleTools.js.map +1 -0
- package/dist/generic/realtimeProxyRegistry.d.ts +19 -0
- package/dist/generic/realtimeProxyRegistry.d.ts.map +1 -1
- package/dist/generic/realtimeProxyRegistry.js +10 -0
- package/dist/generic/realtimeProxyRegistry.js.map +1 -1
- package/dist/generic/realtimeToolBatchBarrier.d.ts +67 -0
- package/dist/generic/realtimeToolBatchBarrier.d.ts.map +1 -0
- package/dist/generic/realtimeToolBatchBarrier.js +119 -0
- package/dist/generic/realtimeToolBatchBarrier.js.map +1 -0
- package/dist/generic/toolTurnEncoding.d.ts +26 -0
- package/dist/generic/toolTurnEncoding.d.ts.map +1 -0
- package/dist/generic/toolTurnEncoding.js +46 -0
- package/dist/generic/toolTurnEncoding.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { BaseParams, BaseResult, ModelUsage } from "./baseModel.js";
|
|
2
2
|
/**
|
|
3
3
|
* The possible roles for a chat message.
|
|
4
|
+
*
|
|
5
|
+
* `tool` carries the RESULT of a native tool call back to the model and is only ever produced
|
|
6
|
+
* alongside a preceding `assistant` turn whose {@link ChatMessage.toolCalls} it answers. Its
|
|
7
|
+
* content is one or more `tool_result` {@link ChatMessageContentBlock}s. Drivers that do not
|
|
8
|
+
* implement tools (`BaseLLM.SupportsTools === false`) map it to `user` like any other non-assistant
|
|
9
|
+
* role, so an unsupported driver degrades to prose rather than erroring.
|
|
4
10
|
*/
|
|
5
11
|
export declare const ChatMessageRole: {
|
|
6
12
|
readonly system: "system";
|
|
7
13
|
readonly user: "user";
|
|
8
14
|
readonly assistant: "assistant";
|
|
15
|
+
readonly tool: "tool";
|
|
9
16
|
};
|
|
10
17
|
export type ChatMessageRole = typeof ChatMessageRole[keyof typeof ChatMessageRole];
|
|
11
18
|
/**
|
|
@@ -15,15 +22,32 @@ export type ChatMessageRole = typeof ChatMessageRole[keyof typeof ChatMessageRol
|
|
|
15
22
|
export type ChatMessageContentBlock = {
|
|
16
23
|
/**
|
|
17
24
|
* The type of content block.
|
|
18
|
-
* Can be 'text', 'image_url', 'video_url', 'audio_url', or '
|
|
25
|
+
* Can be 'text', 'image_url', 'video_url', 'audio_url', 'file_url', or 'tool_result'.
|
|
19
26
|
*/
|
|
20
|
-
type: 'text' | 'image_url' | 'video_url' | 'audio_url' | 'file_url';
|
|
27
|
+
type: 'text' | 'image_url' | 'video_url' | 'audio_url' | 'file_url' | 'tool_result';
|
|
21
28
|
/**
|
|
22
29
|
* The content of the block.
|
|
23
30
|
* This can be a string. In the case of 'image_url', 'video_url', 'audio_url', or 'file_url', it should be a URL to the resource, OR it can be a base64 encoded string.
|
|
24
31
|
* representing the content of the item. For base64 images, use the data URL format: data:image/png;base64,<data>
|
|
32
|
+
* For 'tool_result', this is the result payload the model should see — stringify non-text results.
|
|
25
33
|
*/
|
|
26
34
|
content: string;
|
|
35
|
+
/**
|
|
36
|
+
* For 'tool_result' blocks: the {@link ChatToolCall.id} this block answers. Required on
|
|
37
|
+
* 'tool_result'; providers use it to pair a result with the call that requested it.
|
|
38
|
+
*/
|
|
39
|
+
toolCallId?: string;
|
|
40
|
+
/**
|
|
41
|
+
* For 'tool_result' blocks: the name of the tool that was called. Optional — carried for
|
|
42
|
+
* providers (and logs) that key results by name rather than id.
|
|
43
|
+
*/
|
|
44
|
+
toolName?: string;
|
|
45
|
+
/**
|
|
46
|
+
* For 'tool_result' blocks: whether the result represents a FAILED tool execution. Providers
|
|
47
|
+
* that model this natively (Anthropic's `is_error`) get it mapped through; others receive the
|
|
48
|
+
* error text as an ordinary result.
|
|
49
|
+
*/
|
|
50
|
+
isError?: boolean;
|
|
27
51
|
/**
|
|
28
52
|
* Optional MIME type for media content (e.g., 'image/png', 'image/jpeg', 'audio/mp3').
|
|
29
53
|
* When content is a data URL, this can be extracted from the URL. When content is raw base64, this field is required.
|
|
@@ -50,6 +74,91 @@ export type ChatMessageContentBlock = {
|
|
|
50
74
|
* Union type for the content of a chat message.
|
|
51
75
|
*/
|
|
52
76
|
export type ChatMessageContent = string | ChatMessageContentBlock[];
|
|
77
|
+
/**
|
|
78
|
+
* A single tool made available to the model for this request.
|
|
79
|
+
*
|
|
80
|
+
* Provider-neutral by design: every major vendor declares tool parameters as JSON Schema with
|
|
81
|
+
* per-property `description` strings, so that is the interchange format here — `input_schema`
|
|
82
|
+
* (Anthropic), `parameters` (OpenAI), `parameters` / `parametersJsonSchema` (Gemini).
|
|
83
|
+
*/
|
|
84
|
+
export interface ChatTool {
|
|
85
|
+
/**
|
|
86
|
+
* The tool's name, as the model will call it. Providers constrain this to `[a-zA-Z0-9_-]`,
|
|
87
|
+
* 64 characters or fewer; callers building tools from names that can contain other characters
|
|
88
|
+
* (MJ Action names, say) must sanitize deterministically and keep a reverse map.
|
|
89
|
+
*/
|
|
90
|
+
name: string;
|
|
91
|
+
/**
|
|
92
|
+
* What the tool does and — more importantly for call accuracy — WHEN the model should call it.
|
|
93
|
+
* Prescriptive phrasing ("Call this when…") measurably outperforms a bare description.
|
|
94
|
+
*/
|
|
95
|
+
description?: string;
|
|
96
|
+
/**
|
|
97
|
+
* JSON Schema for the tool's input. Stick to the cross-provider common subset — `type`,
|
|
98
|
+
* `description`, `enum`, `items`, `properties`, `required` — because Gemini's classic
|
|
99
|
+
* function-declaration schema is an OpenAPI subset that rejects keywords like
|
|
100
|
+
* `additionalProperties`. Drivers adapt anything beyond that subset.
|
|
101
|
+
*/
|
|
102
|
+
inputSchema: Record<string, unknown>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Controls how the model may use the tools declared for this request.
|
|
106
|
+
*
|
|
107
|
+
* - `'auto'` — the model decides whether to call a tool. The default whenever tools are present.
|
|
108
|
+
* - `'none'` — tools stay declared (and cached) but the model must not call one this turn. The
|
|
109
|
+
* way to force a prose/JSON answer without changing the cached tool block.
|
|
110
|
+
* - `'required'` — the model must call some tool.
|
|
111
|
+
* - `{ name }` — the model must call the named tool.
|
|
112
|
+
*
|
|
113
|
+
* Forcing a call typically SUPPRESSES text output, and Anthropic additionally disables extended
|
|
114
|
+
* thinking under a forced tool choice — never assume text accompanies a forced call.
|
|
115
|
+
*/
|
|
116
|
+
export type ChatToolChoice = 'auto' | 'none' | 'required' | {
|
|
117
|
+
name: string;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* One tool call the model asked for, normalized across providers.
|
|
121
|
+
*/
|
|
122
|
+
export interface ChatToolCall {
|
|
123
|
+
/**
|
|
124
|
+
* The provider's call id, echoed back on the matching `tool_result` block so the provider can
|
|
125
|
+
* pair result to call. Drivers synthesize a stable id for providers that do not supply one
|
|
126
|
+
* (Gemini names calls rather than identifying them).
|
|
127
|
+
*/
|
|
128
|
+
id: string;
|
|
129
|
+
/** The tool name the model called — matches a {@link ChatTool.name} that was declared. */
|
|
130
|
+
name: string;
|
|
131
|
+
/**
|
|
132
|
+
* The call arguments, already PARSED. Providers that transmit arguments as a JSON string
|
|
133
|
+
* (OpenAI) parse them in the driver, so consumers never see a string here.
|
|
134
|
+
*/
|
|
135
|
+
arguments: Record<string, unknown>;
|
|
136
|
+
/**
|
|
137
|
+
* Opaque provider data that must travel with the call when it is replayed into history.
|
|
138
|
+
* Gemini 3 attaches a `thoughtSignature` to each function-call part and rejects a replayed call
|
|
139
|
+
* that lacks it (HTTP 400); the driver stores it here on the way in and
|
|
140
|
+
* sends it back on the way out. Other providers leave this undefined. Never read by the loop.
|
|
141
|
+
*/
|
|
142
|
+
providerMetadata?: Record<string, unknown>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* The normalized `finish_reason` a driver reports when the model ended its turn by calling one or
|
|
146
|
+
* more tools. Consumers branch on this rather than on any provider-specific stop reason.
|
|
147
|
+
*
|
|
148
|
+
* This is currently the ONLY normalized value: every other `finish_reason` is whatever the driver's
|
|
149
|
+
* SDK returned (`'stop'`, `"completed"`, `"STOP"`, …). Normalizing the rest is tracked in
|
|
150
|
+
* MemberJunction/MJ#4335, which must preserve unrecognized values rather than map onto a closed
|
|
151
|
+
* union — a shipped action overloads the field as a channel selector.
|
|
152
|
+
*/
|
|
153
|
+
export declare const CHAT_FINISH_REASON_TOOL_CALLS = "tool_calls";
|
|
154
|
+
/**
|
|
155
|
+
* The normalized `finish_reason` a driver reports when the model tried to call a tool but the call
|
|
156
|
+
* could not be read — Gemini's `MALFORMED_FUNCTION_CALL`, typically an oversized or syntactically
|
|
157
|
+
* broken argument object. The turn then carries whatever text preceded the broken call and NO
|
|
158
|
+
* `toolCalls`, so without this marker a consumer reads leftover narration as the model's answer.
|
|
159
|
+
* The agent loop turns it into a corrective retry.
|
|
160
|
+
*/
|
|
161
|
+
export declare const CHAT_FINISH_REASON_MALFORMED_TOOL_CALL = "malformed_tool_call";
|
|
53
162
|
/**
|
|
54
163
|
* Defines the shape of an individual chat message.
|
|
55
164
|
*
|
|
@@ -71,6 +180,15 @@ export type ChatMessage<M = any> = {
|
|
|
71
180
|
* the core ChatMessage type.
|
|
72
181
|
*/
|
|
73
182
|
metadata?: M;
|
|
183
|
+
/**
|
|
184
|
+
* For `assistant` turns that called tools: the calls the model made, so a prior tool-calling
|
|
185
|
+
* turn round-trips back to the provider on the next request. Every provider requires the
|
|
186
|
+
* assistant's own call turn to be present in history before the matching results.
|
|
187
|
+
*
|
|
188
|
+
* Set this from {@link ChatCompletionMessage.toolCalls} when appending the model's reply to
|
|
189
|
+
* the conversation; the `tool` turn that answers it follows immediately.
|
|
190
|
+
*/
|
|
191
|
+
toolCalls?: ChatToolCall[];
|
|
74
192
|
};
|
|
75
193
|
/**
|
|
76
194
|
* Defines the shape of an individual message from the model in response to a chat completion request.
|
|
@@ -89,6 +207,17 @@ export type ChatCompletionMessage = {
|
|
|
89
207
|
* Not all providers/models support this field.
|
|
90
208
|
*/
|
|
91
209
|
thinking?: string | null;
|
|
210
|
+
/**
|
|
211
|
+
* Tool calls the model made on this turn, normalized across providers. Absent or empty when
|
|
212
|
+
* the model did not call a tool.
|
|
213
|
+
*
|
|
214
|
+
* A turn can carry BOTH `content` and `toolCalls` — the tool-capable providers structurally
|
|
215
|
+
* allow it (Anthropic `text` + `tool_use` blocks, OpenAI nullable `content` alongside
|
|
216
|
+
* `tool_calls`, Gemini `text` + `functionCall` parts) — so this is never an either/or with
|
|
217
|
+
* `content`. Equally, nothing downstream may assume `content` is non-empty on a tool-call
|
|
218
|
+
* turn: a forced {@link ChatToolChoice} usually suppresses text entirely.
|
|
219
|
+
*/
|
|
220
|
+
toolCalls?: ChatToolCall[];
|
|
92
221
|
};
|
|
93
222
|
/**
|
|
94
223
|
* Interface for streaming chat completion callbacks
|
|
@@ -235,6 +364,26 @@ export declare class ChatParams extends BaseParams {
|
|
|
235
364
|
* Typically ranges from 2-20, depending on the provider.
|
|
236
365
|
*/
|
|
237
366
|
topLogProbs?: number;
|
|
367
|
+
/**
|
|
368
|
+
* Tool declarations for this request. When present and the driver reports
|
|
369
|
+
* `SupportsTools === true`, these are passed to the provider's native tool-calling API.
|
|
370
|
+
*
|
|
371
|
+
* A driver with `SupportsTools === false` IGNORES this and notes the fact in
|
|
372
|
+
* `modelSpecificResponseDetails` — the prompt runner's capability gate should mean that never
|
|
373
|
+
* happens, but Layer 2 stays safe on its own.
|
|
374
|
+
*/
|
|
375
|
+
tools?: ChatTool[];
|
|
376
|
+
/**
|
|
377
|
+
* How the model may use {@link ChatParams.tools}. Ignored when no tools are declared.
|
|
378
|
+
* Defaults to the provider's own default (`'auto'`) when omitted.
|
|
379
|
+
*/
|
|
380
|
+
toolChoice?: ChatToolChoice;
|
|
381
|
+
/**
|
|
382
|
+
* Whether the model may emit several tool calls in a single turn. Omit to accept the
|
|
383
|
+
* provider's default (parallel calls allowed). Maps to OpenAI `parallel_tool_calls` and
|
|
384
|
+
* Anthropic `tool_choice.disable_parallel_tool_use`.
|
|
385
|
+
*/
|
|
386
|
+
parallelToolCalls?: boolean;
|
|
238
387
|
}
|
|
239
388
|
/**
|
|
240
389
|
* Returns the first user message from the chat params
|
|
@@ -391,6 +540,57 @@ export declare function hasImageContent(content: ChatMessageContent): boolean;
|
|
|
391
540
|
* @returns A plain text string with all text blocks joined
|
|
392
541
|
*/
|
|
393
542
|
export declare function getTextFromContent(content: ChatMessageContent): string;
|
|
543
|
+
/**
|
|
544
|
+
* Validates that every tool result in a conversation answers a tool call the model actually made.
|
|
545
|
+
*
|
|
546
|
+
* The contract providers enforce: a `tool_result` is only meaningful next to the assistant turn
|
|
547
|
+
* whose `tool_use` / `tool_calls` it answers. The easy way to break it is to append the model's
|
|
548
|
+
* reply to the conversation WITHOUT copying {@link ChatCompletionMessage.toolCalls} onto the
|
|
549
|
+
* assistant {@link ChatMessage}, then append the results — the calls vanish and the results are
|
|
550
|
+
* orphaned. Anthropic rejects that outright, and the provider's own error names an opaque id rather
|
|
551
|
+
* than the mistake, so this catches it at the MJ boundary with a message that says what to fix.
|
|
552
|
+
*
|
|
553
|
+
* Only runs where it can find a problem: conversations with no tool turns are untouched.
|
|
554
|
+
*
|
|
555
|
+
* @param messages The conversation to check
|
|
556
|
+
* @throws Error naming the unmatched tool-call ids and how to fix the history
|
|
557
|
+
*/
|
|
558
|
+
export declare function validateToolConversation(messages: ChatMessage[]): void;
|
|
559
|
+
/**
|
|
560
|
+
* Collapses an MJ role onto the three roles every chat API understands.
|
|
561
|
+
*
|
|
562
|
+
* `tool` becomes `user`, which is how a tool result reads to a provider with no tool support — the
|
|
563
|
+
* user handing the model some text. Drivers that DO implement tools must not use this for `tool`
|
|
564
|
+
* turns; they map those onto their SDK's own tool-result shape.
|
|
565
|
+
*
|
|
566
|
+
* @param role The MJ message role
|
|
567
|
+
* @returns The equivalent classic role
|
|
568
|
+
*/
|
|
569
|
+
export declare function toClassicChatMessageRole(role: ChatMessageRole): 'system' | 'user' | 'assistant';
|
|
570
|
+
/**
|
|
571
|
+
* Extracts the `tool_result` blocks from a message's content, ignoring everything else.
|
|
572
|
+
* Returns an empty array for plain-string content.
|
|
573
|
+
*
|
|
574
|
+
* @param content The message content to inspect
|
|
575
|
+
* @returns The tool-result blocks, in order
|
|
576
|
+
*/
|
|
577
|
+
export declare function getToolResultBlocks(content: ChatMessageContent): ChatMessageContentBlock[];
|
|
578
|
+
/**
|
|
579
|
+
* Builds the `tool` turn that answers one or more tool calls.
|
|
580
|
+
*
|
|
581
|
+
* Providers require the results for a given assistant turn's calls to arrive TOGETHER, in the
|
|
582
|
+
* single turn that immediately follows it — so pass every result for that turn in one call rather
|
|
583
|
+
* than appending a message per result.
|
|
584
|
+
*
|
|
585
|
+
* @param results One entry per tool call being answered
|
|
586
|
+
* @returns A `tool`-role message whose content is the corresponding `tool_result` blocks
|
|
587
|
+
*/
|
|
588
|
+
export declare function createToolResultMessage(results: Array<{
|
|
589
|
+
toolCallId: string;
|
|
590
|
+
toolName?: string;
|
|
591
|
+
content: string;
|
|
592
|
+
isError?: boolean;
|
|
593
|
+
}>): ChatMessage;
|
|
394
594
|
/**
|
|
395
595
|
* Parses a base64 data URL into its components.
|
|
396
596
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.types.d.ts","sourceRoot":"","sources":["../../src/generic/chat.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAIhE
|
|
1
|
+
{"version":3,"file":"chat.types.d.ts","sourceRoot":"","sources":["../../src/generic/chat.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,37 @@
|
|
|
1
1
|
import { BaseParams, BaseResult } from "./baseModel.js";
|
|
2
2
|
/**
|
|
3
3
|
* The possible roles for a chat message.
|
|
4
|
+
*
|
|
5
|
+
* `tool` carries the RESULT of a native tool call back to the model and is only ever produced
|
|
6
|
+
* alongside a preceding `assistant` turn whose {@link ChatMessage.toolCalls} it answers. Its
|
|
7
|
+
* content is one or more `tool_result` {@link ChatMessageContentBlock}s. Drivers that do not
|
|
8
|
+
* implement tools (`BaseLLM.SupportsTools === false`) map it to `user` like any other non-assistant
|
|
9
|
+
* role, so an unsupported driver degrades to prose rather than erroring.
|
|
4
10
|
*/
|
|
5
11
|
export const ChatMessageRole = {
|
|
6
12
|
system: 'system',
|
|
7
13
|
user: 'user',
|
|
8
|
-
assistant: 'assistant'
|
|
14
|
+
assistant: 'assistant',
|
|
15
|
+
tool: 'tool'
|
|
9
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* The normalized `finish_reason` a driver reports when the model ended its turn by calling one or
|
|
19
|
+
* more tools. Consumers branch on this rather than on any provider-specific stop reason.
|
|
20
|
+
*
|
|
21
|
+
* This is currently the ONLY normalized value: every other `finish_reason` is whatever the driver's
|
|
22
|
+
* SDK returned (`'stop'`, `"completed"`, `"STOP"`, …). Normalizing the rest is tracked in
|
|
23
|
+
* MemberJunction/MJ#4335, which must preserve unrecognized values rather than map onto a closed
|
|
24
|
+
* union — a shipped action overloads the field as a channel selector.
|
|
25
|
+
*/
|
|
26
|
+
export const CHAT_FINISH_REASON_TOOL_CALLS = 'tool_calls';
|
|
27
|
+
/**
|
|
28
|
+
* The normalized `finish_reason` a driver reports when the model tried to call a tool but the call
|
|
29
|
+
* could not be read — Gemini's `MALFORMED_FUNCTION_CALL`, typically an oversized or syntactically
|
|
30
|
+
* broken argument object. The turn then carries whatever text preceded the broken call and NO
|
|
31
|
+
* `toolCalls`, so without this marker a consumer reads leftover narration as the model's answer.
|
|
32
|
+
* The agent loop turns it into a corrective retry.
|
|
33
|
+
*/
|
|
34
|
+
export const CHAT_FINISH_REASON_MALFORMED_TOOL_CALL = 'malformed_tool_call';
|
|
10
35
|
export class ChatParams extends BaseParams {
|
|
11
36
|
constructor() {
|
|
12
37
|
super(...arguments);
|
|
@@ -130,6 +155,94 @@ export function getTextFromContent(content) {
|
|
|
130
155
|
.map(block => block.content)
|
|
131
156
|
.join('\n');
|
|
132
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Validates that every tool result in a conversation answers a tool call the model actually made.
|
|
160
|
+
*
|
|
161
|
+
* The contract providers enforce: a `tool_result` is only meaningful next to the assistant turn
|
|
162
|
+
* whose `tool_use` / `tool_calls` it answers. The easy way to break it is to append the model's
|
|
163
|
+
* reply to the conversation WITHOUT copying {@link ChatCompletionMessage.toolCalls} onto the
|
|
164
|
+
* assistant {@link ChatMessage}, then append the results — the calls vanish and the results are
|
|
165
|
+
* orphaned. Anthropic rejects that outright, and the provider's own error names an opaque id rather
|
|
166
|
+
* than the mistake, so this catches it at the MJ boundary with a message that says what to fix.
|
|
167
|
+
*
|
|
168
|
+
* Only runs where it can find a problem: conversations with no tool turns are untouched.
|
|
169
|
+
*
|
|
170
|
+
* @param messages The conversation to check
|
|
171
|
+
* @throws Error naming the unmatched tool-call ids and how to fix the history
|
|
172
|
+
*/
|
|
173
|
+
export function validateToolConversation(messages) {
|
|
174
|
+
const declaredCallIds = new Set();
|
|
175
|
+
const orphaned = [];
|
|
176
|
+
for (const message of messages) {
|
|
177
|
+
// Assistant turns declare ids; results may only reference ids declared BEFORE them, so the
|
|
178
|
+
// two are collected in a single forward pass.
|
|
179
|
+
if (message.role === ChatMessageRole.assistant) {
|
|
180
|
+
for (const call of message.toolCalls ?? []) {
|
|
181
|
+
declaredCallIds.add(call.id);
|
|
182
|
+
}
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
for (const block of getToolResultBlocks(message.content)) {
|
|
186
|
+
if (!block.toolCallId || !declaredCallIds.has(block.toolCallId)) {
|
|
187
|
+
orphaned.push(block.toolCallId ?? '(missing toolCallId)');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (orphaned.length > 0) {
|
|
192
|
+
throw new Error(`Tool result(s) with no matching tool call in the conversation: ${orphaned.join(', ')}. ` +
|
|
193
|
+
`Every tool_result must answer a call declared by an EARLIER assistant message — set ` +
|
|
194
|
+
`ChatMessage.toolCalls from the model's ChatCompletionMessage.toolCalls when you append ` +
|
|
195
|
+
`its reply, before appending the results.`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Collapses an MJ role onto the three roles every chat API understands.
|
|
200
|
+
*
|
|
201
|
+
* `tool` becomes `user`, which is how a tool result reads to a provider with no tool support — the
|
|
202
|
+
* user handing the model some text. Drivers that DO implement tools must not use this for `tool`
|
|
203
|
+
* turns; they map those onto their SDK's own tool-result shape.
|
|
204
|
+
*
|
|
205
|
+
* @param role The MJ message role
|
|
206
|
+
* @returns The equivalent classic role
|
|
207
|
+
*/
|
|
208
|
+
export function toClassicChatMessageRole(role) {
|
|
209
|
+
return role === ChatMessageRole.tool ? ChatMessageRole.user : role;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Extracts the `tool_result` blocks from a message's content, ignoring everything else.
|
|
213
|
+
* Returns an empty array for plain-string content.
|
|
214
|
+
*
|
|
215
|
+
* @param content The message content to inspect
|
|
216
|
+
* @returns The tool-result blocks, in order
|
|
217
|
+
*/
|
|
218
|
+
export function getToolResultBlocks(content) {
|
|
219
|
+
if (typeof content === 'string') {
|
|
220
|
+
return [];
|
|
221
|
+
}
|
|
222
|
+
return content.filter(block => block.type === 'tool_result');
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Builds the `tool` turn that answers one or more tool calls.
|
|
226
|
+
*
|
|
227
|
+
* Providers require the results for a given assistant turn's calls to arrive TOGETHER, in the
|
|
228
|
+
* single turn that immediately follows it — so pass every result for that turn in one call rather
|
|
229
|
+
* than appending a message per result.
|
|
230
|
+
*
|
|
231
|
+
* @param results One entry per tool call being answered
|
|
232
|
+
* @returns A `tool`-role message whose content is the corresponding `tool_result` blocks
|
|
233
|
+
*/
|
|
234
|
+
export function createToolResultMessage(results) {
|
|
235
|
+
return {
|
|
236
|
+
role: ChatMessageRole.tool,
|
|
237
|
+
content: results.map(r => ({
|
|
238
|
+
type: 'tool_result',
|
|
239
|
+
content: r.content,
|
|
240
|
+
toolCallId: r.toolCallId,
|
|
241
|
+
toolName: r.toolName,
|
|
242
|
+
isError: r.isError
|
|
243
|
+
}))
|
|
244
|
+
};
|
|
245
|
+
}
|
|
133
246
|
/**
|
|
134
247
|
* Parses a base64 data URL into its components.
|
|
135
248
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.types.js","sourceRoot":"","sources":["../../src/generic/chat.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAc,MAAM,aAAa,CAAA;AAIhE
|
|
1
|
+
{"version":3,"file":"chat.types.js","sourceRoot":"","sources":["../../src/generic/chat.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The canonical
|
|
2
|
+
* The canonical AI configuration shapes + the pure cascade resolvers.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* scalar `SupportsPrefill` / `PrefillFallbackText` cascade those same three entities already carry):
|
|
4
|
+
* The AI stack carries `nvarchar(max)` JSONType configuration bags at five levels, in two cascades.
|
|
5
|
+
* The MODEL CATALOG cascade describes the model:
|
|
7
6
|
*
|
|
8
7
|
* ```
|
|
9
8
|
* MJ: AI Model Types . ModelConfiguration (type-wide default — e.g. every Realtime model)
|
|
@@ -11,18 +10,29 @@
|
|
|
11
10
|
* < MJ: AI Model Vendors . ModelConfiguration (per model-on-this-provider — the winner)
|
|
12
11
|
* ```
|
|
13
12
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
13
|
+
* The PROMPT cascade describes what a given prompt asks for, and layers on top of the catalog:
|
|
14
|
+
*
|
|
15
|
+
* ```
|
|
16
|
+
* MJ: AI Prompts . PromptConfiguration (per-prompt)
|
|
17
|
+
* < MJ: AI Prompt Models . PromptConfiguration (per prompt-on-this-model — the winner)
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Both compose the SAME per-modality section types ({@link LLMConfigurationSettings},
|
|
21
|
+
* {@link RealtimeConfigurationSettings}, …) — one definition of what "the LLM configuration" means,
|
|
22
|
+
* reused at every layer. Only the outer per-table type differs.
|
|
23
|
+
*
|
|
24
|
+
* **Lockstep contract**: these interfaces mirror
|
|
25
|
+
* `metadata/entities/JSONType-interfaces/IAIConfiguration.ts`, which is pushed into
|
|
26
|
+
* `EntityField.JSONTypeDefinition` and drives the CodeGen-generated `ModelConfigurationObject` /
|
|
27
|
+
* `PromptConfigurationObject` accessors on the five entities. Keep the two in step when adding a section
|
|
28
|
+
* or property — the same pact `IAgentSettings` follows with `@memberjunction/ai-core-plus`.
|
|
19
29
|
*
|
|
20
30
|
* **Boundary rule** (also documented on the metadata interface): anything the engine filters,
|
|
21
31
|
* sorts, or joins on stays a COLUMN (`PowerRank`, `IsActive`, `Priority`, `Status` — SQL cannot
|
|
22
|
-
* cheaply predicate into this bag); anything a driver consumes at
|
|
23
|
-
* New capability knobs go in
|
|
32
|
+
* cheaply predicate into this bag); anything a driver or runner consumes at call time belongs HERE.
|
|
33
|
+
* New capability knobs go in the bag — do not add a capability column per knob. A knob graduates to
|
|
34
|
+
* a real column when it needs a foreign key or becomes a first-class platform concept.
|
|
24
35
|
*/
|
|
25
|
-
import { JSONObject } from './baseRealtime.js';
|
|
26
36
|
/**
|
|
27
37
|
* MJ-normalized turn-detection mode vocabulary — provider-neutral by design so a shared model
|
|
28
38
|
* catalog is safe on every provider:
|
|
@@ -53,40 +63,145 @@ export interface RealtimeTurnDetectionSettings {
|
|
|
53
63
|
/** Server-VAD trailing-silence duration in ms; ignored by profiles without a mapping. */
|
|
54
64
|
SilenceDurationMs?: number;
|
|
55
65
|
}
|
|
56
|
-
/**
|
|
57
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Which plane handles reasoning during a realtime session:
|
|
68
|
+
* - `'local'` — the application/agent loop handles reasoning, Actions, and tool results (MJ default).
|
|
69
|
+
* - `'remote'` — the model delegates reasoning to a remote model or hosted agent backend.
|
|
70
|
+
*/
|
|
71
|
+
export type RealtimeReasoningPlane = 'local' | 'remote';
|
|
72
|
+
/**
|
|
73
|
+
* Configuration for remote reasoning delegation.
|
|
74
|
+
*/
|
|
75
|
+
export interface RealtimeRemoteReasoning {
|
|
76
|
+
/** What the remote reference denotes. `model` = Live/Inworld; `hostedAgent` = ElevenLabs. */
|
|
77
|
+
Kind?: 'model' | 'hostedAgent';
|
|
78
|
+
/** 'gpt-5.6-terra' | 'anthropic/claude-sonnet-4-6' | 'MJ Realtime Co-Agent'. */
|
|
79
|
+
Ref?: string;
|
|
80
|
+
/** Reasoning effort level for supported models. */
|
|
81
|
+
Effort?: 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';
|
|
82
|
+
/** Maximum output tokens for the remote reasoning pass. */
|
|
83
|
+
MaxOutputTokens?: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Realtime reasoning settings controlling dual delegation.
|
|
87
|
+
*/
|
|
88
|
+
export interface RealtimeReasoningSettings {
|
|
89
|
+
/** Absent = 'local'. Session-creation-time only — NOT runtime-switchable. */
|
|
90
|
+
Plane?: RealtimeReasoningPlane;
|
|
91
|
+
/** Remote reasoning target when Plane is 'remote'. */
|
|
92
|
+
Remote?: RealtimeRemoteReasoning;
|
|
93
|
+
}
|
|
94
|
+
/** The `Realtime` section — knobs the realtime drivers consume. */
|
|
95
|
+
export interface RealtimeConfigurationSettings {
|
|
58
96
|
/**
|
|
59
97
|
* Catalog-level turn-detection default for this model. Folded into the session Config bag as
|
|
60
98
|
* the `turnDetection` key BELOW the agent/app config cascade (`realtime.session.turnDetection`)
|
|
61
99
|
* and the runtime override — the catalog supplies the default, agents/apps/callers refine it.
|
|
62
100
|
*/
|
|
63
|
-
TurnDetection?: RealtimeTurnDetectionSettings;
|
|
101
|
+
TurnDetection?: RealtimeTurnDetectionSettings | null;
|
|
102
|
+
/**
|
|
103
|
+
* Reasoning plane settings — dual delegation configuration.
|
|
104
|
+
* Absent defaults to 'local'.
|
|
105
|
+
*/
|
|
106
|
+
Reasoning?: RealtimeReasoningSettings;
|
|
64
107
|
}
|
|
65
108
|
/**
|
|
66
|
-
* The `LLM` section
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
109
|
+
* The `LLM` section — knobs the LLM drivers and the prompt runner consume at call time.
|
|
110
|
+
*
|
|
111
|
+
* Every flag here is TRI-STATE (`boolean | null | absent`), and the three differ. The cascade
|
|
112
|
+
* REPLACES on any explicit value (including `null`) and only skips a layer that OMITS the property.
|
|
113
|
+
* So absent means "inherit", while an explicit value at a higher layer overrides a lower one even
|
|
114
|
+
* when that value is `false`.
|
|
115
|
+
*
|
|
116
|
+
* Properties are marked with the layers that HONOR them. Setting one at a layer that does not honor
|
|
117
|
+
* it is inert rather than an error — deliberate tolerance, so a knob can move between layers
|
|
118
|
+
* without a schema change.
|
|
119
|
+
*
|
|
120
|
+
* Deliberately NO index signature: this interface must stay structurally identical to the JSONType
|
|
121
|
+
* source, because CodeGen emits per-entity copies of that source and runtime code assigns those
|
|
122
|
+
* generated types straight into this one. An index signature here (and not there) makes the two
|
|
123
|
+
* incompatible. Unknown keys in stored JSON still round-trip fine at runtime — the parse is
|
|
124
|
+
* tolerant; what is lost is only a compile-time affordance nothing needs.
|
|
70
125
|
*/
|
|
71
|
-
export interface
|
|
72
|
-
/**
|
|
126
|
+
export interface LLMConfigurationSettings {
|
|
127
|
+
/**
|
|
128
|
+
* **Catalog layers only.** Whether this model — or this vendor's serving of it — supports native
|
|
129
|
+
* tool/function calling. CAPABILITY flag, and a hard gate: no policy or preference at any layer
|
|
130
|
+
* can force tools onto a (model, vendor) whose resolved value is not true.
|
|
131
|
+
*
|
|
132
|
+
* Set `false` only for a model or serving path verified NOT to support tools; leave absent when
|
|
133
|
+
* support is unknown, because absent is the honest value and it inherits.
|
|
134
|
+
*/
|
|
135
|
+
SupportsNativeToolCalling?: boolean | null;
|
|
136
|
+
/**
|
|
137
|
+
* **Catalog layers only.** Whether prompts run against this model default to native tool calling
|
|
138
|
+
* when they express no preference of their own. POLICY flag — subordinate to
|
|
139
|
+
* {@link LLMConfigurationSettings.SupportsNativeToolCalling}.
|
|
140
|
+
*/
|
|
141
|
+
DefaultToNativeToolCalling?: boolean | null;
|
|
142
|
+
/**
|
|
143
|
+
* **Prompt layers only.** Whether THIS prompt asks for native tool calling. PREFERENCE — it
|
|
144
|
+
* outranks the catalog's `DefaultToNativeToolCalling` and is still subordinate to the capability
|
|
145
|
+
* gate. Absent means "no preference; fall through to the model's default".
|
|
146
|
+
*/
|
|
147
|
+
UseNativeToolCalling?: boolean | null;
|
|
148
|
+
/**
|
|
149
|
+
* **Catalog layers only.** How control flow is expressed when a request resolves to native tool
|
|
150
|
+
* calling. `'envelope'` (the default when absent) is the hybrid: Actions are tools, everything
|
|
151
|
+
* else — completion, chat, delegation, payload changes — is the JSON envelope. `'implicit'` is the
|
|
152
|
+
* implicit protocol: sub-agents, `payload_change_request` and `ask_user` are tools too, a tool call
|
|
153
|
+
* continues the loop, and plain text with no call ends the turn as task completion. Consulted only
|
|
154
|
+
* when the gate resolves native; subordinate to {@link LLMConfigurationSettings.SupportsNativeToolCalling}.
|
|
155
|
+
*/
|
|
156
|
+
NativeControlFlow?: 'envelope' | 'implicit' | null;
|
|
157
|
+
/**
|
|
158
|
+
* **Catalog layers only.** Whether action results are returned to the model as native tool-result
|
|
159
|
+
* turns instead of a markdown "Action results" user message. Absent means `false`. Consulted
|
|
160
|
+
* only when the gate resolves native.
|
|
161
|
+
*/
|
|
162
|
+
NativeToolResults?: boolean | null;
|
|
163
|
+
}
|
|
164
|
+
/** Vision knobs. Reserved — no consumers yet. */
|
|
165
|
+
export interface VisionConfigurationSettings {
|
|
166
|
+
[key: string]: unknown;
|
|
167
|
+
}
|
|
168
|
+
/** Audio (TTS/STT) knobs. Reserved — no consumers yet. */
|
|
169
|
+
export interface AudioConfigurationSettings {
|
|
73
170
|
[key: string]: unknown;
|
|
74
171
|
}
|
|
75
172
|
/**
|
|
76
|
-
* The per-modality
|
|
77
|
-
*
|
|
78
|
-
* per-modality so one catalog row can configure everything its model does.
|
|
173
|
+
* The per-modality bag common to every AI configuration column. Sections are optional and
|
|
174
|
+
* per-modality so one row can configure everything the thing it describes does.
|
|
79
175
|
*/
|
|
80
|
-
export interface
|
|
81
|
-
/** Text-generation knobs.
|
|
82
|
-
LLM?:
|
|
83
|
-
/** Realtime (speech-to-speech) knobs
|
|
84
|
-
Realtime?:
|
|
176
|
+
export interface AIConfigurationSections {
|
|
177
|
+
/** Text-generation knobs. */
|
|
178
|
+
LLM?: LLMConfigurationSettings | null;
|
|
179
|
+
/** Realtime (speech-to-speech) knobs. */
|
|
180
|
+
Realtime?: RealtimeConfigurationSettings | null;
|
|
85
181
|
/** Vision knobs. Reserved. */
|
|
86
|
-
Vision?:
|
|
182
|
+
Vision?: VisionConfigurationSettings | null;
|
|
87
183
|
/** Audio (TTS/STT) knobs. Reserved. */
|
|
88
|
-
Audio?:
|
|
184
|
+
Audio?: AudioConfigurationSettings | null;
|
|
89
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* The `ModelConfiguration` column on `MJ: AI Model Types`, `MJ: AI Models` and
|
|
188
|
+
* `MJ: AI Model Vendors` — the model-catalog cascade.
|
|
189
|
+
*/
|
|
190
|
+
export type AIModelConfiguration = AIConfigurationSections;
|
|
191
|
+
/**
|
|
192
|
+
* The `PromptConfiguration` column on `MJ: AI Prompts` — per-prompt call-time knobs, layered on top of
|
|
193
|
+
* the resolved model-catalog configuration by the prompt runner.
|
|
194
|
+
*/
|
|
195
|
+
export type AIPromptConfiguration = AIConfigurationSections;
|
|
196
|
+
/**
|
|
197
|
+
* The `PromptConfiguration` column on `MJ: AI Prompt Models` — the most specific layer, overriding both
|
|
198
|
+
* the prompt's own bag and the model catalog for this one (prompt, model) pairing.
|
|
199
|
+
*/
|
|
200
|
+
export type AIPromptModelConfiguration = AIConfigurationSections;
|
|
201
|
+
/** @deprecated Renamed to {@link RealtimeConfigurationSettings}; the sections are shared now. */
|
|
202
|
+
export type RealtimeModelConfigurationSection = RealtimeConfigurationSettings;
|
|
203
|
+
/** @deprecated Renamed to {@link LLMConfigurationSettings}; the sections are shared now. */
|
|
204
|
+
export type LLMModelConfigurationSection = LLMConfigurationSettings;
|
|
90
205
|
/**
|
|
91
206
|
* TOLERANTLY parses one `ModelConfiguration` column value. Returns `null` — never throws — for
|
|
92
207
|
* absent, blank, malformed, or non-object payloads, so a bad catalog row contributes nothing to
|