@pipedog/openai 0.0.0 → 0.4.0

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/llm.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * OpenAI LLM service implementation with context aggregators.
3
+ *
4
+ * Porting note: the deprecated `model` and `params` constructor options are
5
+ * not ported (use `settings`), so `serviceTier` is only read from its own
6
+ * option.
7
+ */
8
+ import { BaseOpenAILLMService, type BaseOpenAILLMServiceOptions, type OpenAILLMSettings } from "./base_llm.ts";
9
+ export interface OpenAILLMServiceOptions extends BaseOpenAILLMServiceOptions {
10
+ }
11
+ /**
12
+ * OpenAI LLM service implementation.
13
+ *
14
+ * Provides a complete OpenAI LLM service with context aggregation support.
15
+ * Uses the BaseOpenAILLMService for core functionality and adds
16
+ * OpenAI-specific context aggregator creation.
17
+ */
18
+ export declare class OpenAILLMService extends BaseOpenAILLMService {
19
+ static Settings: typeof OpenAILLMSettings;
20
+ /**
21
+ * Initialize OpenAI LLM service.
22
+ *
23
+ * @param options.serviceTier Service tier to use (e.g., "auto", "flex", "priority").
24
+ * @param options.settings Runtime-updatable settings. Its given fields
25
+ * override the defaults (model "gpt-4.1").
26
+ * Other options are passed to the parent BaseOpenAILLMService.
27
+ */
28
+ constructor(options?: OpenAILLMServiceOptions);
29
+ }
30
+ //# sourceMappingURL=llm.d.ts.map
package/dist/llm.js ADDED
@@ -0,0 +1,50 @@
1
+ // Copyright (c) 2024-2026, Daily
2
+ // Copyright (c) 2026, pipedog contributors
3
+ // SPDX-License-Identifier: BSD-2-Clause
4
+ //
5
+ // Ported from pipecat: src/pipecat/services/openai/llm.py
6
+ /**
7
+ * OpenAI LLM service implementation with context aggregators.
8
+ *
9
+ * Porting note: the deprecated `model` and `params` constructor options are
10
+ * not ported (use `settings`), so `serviceTier` is only read from its own
11
+ * option.
12
+ */
13
+ import { BaseOpenAILLMService, setOpenAINotGiven, } from "./base_llm.js";
14
+ /**
15
+ * OpenAI LLM service implementation.
16
+ *
17
+ * Provides a complete OpenAI LLM service with context aggregation support.
18
+ * Uses the BaseOpenAILLMService for core functionality and adds
19
+ * OpenAI-specific context aggregator creation.
20
+ */
21
+ export class OpenAILLMService extends BaseOpenAILLMService {
22
+ static Settings = BaseOpenAILLMService.Settings;
23
+ /**
24
+ * Initialize OpenAI LLM service.
25
+ *
26
+ * @param options.serviceTier Service tier to use (e.g., "auto", "flex", "priority").
27
+ * @param options.settings Runtime-updatable settings. Its given fields
28
+ * override the defaults (model "gpt-4.1").
29
+ * Other options are passed to the parent BaseOpenAILLMService.
30
+ */
31
+ constructor(options = {}) {
32
+ const cls = new.target;
33
+ // 1. Initialize default_settings with hardcoded defaults
34
+ const defaultSettings = new cls.Settings({
35
+ model: "gpt-4.1",
36
+ systemInstruction: null,
37
+ topK: null,
38
+ filterIncompleteUserTurns: false,
39
+ userTurnCompletionConfig: null,
40
+ extra: {},
41
+ });
42
+ setOpenAINotGiven(defaultSettings);
43
+ // 2. Apply settings delta (canonical API, always wins)
44
+ if (options.settings !== undefined && options.settings !== null) {
45
+ defaultSettings.applyUpdate(options.settings);
46
+ }
47
+ super({ ...options, serviceTier: options.serviceTier ?? null, settings: defaultSettings });
48
+ }
49
+ }
50
+ //# sourceMappingURL=llm.js.map
@@ -0,0 +1,94 @@
1
+ /** OpenAI Live LLM adapter for Pipecat. */
2
+ import { BaseLLMAdapter } from "@pipedog/core/adapters/base_llm_adapter";
3
+ import type { ToolsSchema } from "@pipedog/core/adapters/schemas/tools_schema";
4
+ import { type LLMContext, type NotGiven } from "@pipedog/core/processors/aggregators/llm_context";
5
+ import * as events from "./live/events.ts";
6
+ import { OpenAIResponsesLLMAdapter } from "./open_ai_responses_adapter.ts";
7
+ type Dict = Record<string, any>;
8
+ /**
9
+ * Session configuration derived from a universal `LLMContext`.
10
+ *
11
+ * - `instructions`: System instructions for the live model, or `null`.
12
+ * - `input`: Prior text-only messages to seed the session with.
13
+ * - `tools`: Function tools in Responses API format, for the backend model.
14
+ * - `tool_choice`: Tool choice in Responses API format, or `null`.
15
+ */
16
+ export interface OpenAILiveLLMInvocationParams {
17
+ instructions: string | null;
18
+ input: events.InputItem[];
19
+ tools: Record<string, unknown>[];
20
+ tool_choice: unknown | null;
21
+ }
22
+ /** Options for `OpenAILiveLLMAdapter.getLlmInvocationParams`. */
23
+ export interface OpenAILiveLLMInvocationParamsOptions {
24
+ /** System instruction from the service settings. */
25
+ systemInstruction?: string | null;
26
+ }
27
+ /**
28
+ * Converts a universal `LLMContext` into OpenAI Live session configuration.
29
+ *
30
+ * The live model takes a system instruction and a text-only conversation
31
+ * history at session start; tools belong to the backend (Responses) model
32
+ * and use the Responses API tool format.
33
+ */
34
+ export declare class OpenAILiveLLMAdapter extends BaseLLMAdapter<OpenAILiveLLMInvocationParams> {
35
+ protected _responsesAdapter: OpenAIResponsesLLMAdapter;
36
+ protected _warnedInputTruncated: boolean;
37
+ /** Initialize the adapter. */
38
+ constructor();
39
+ /** The identifier used in LLMSpecificMessage instances for OpenAI Live. */
40
+ get idForLlmSpecificMessages(): string;
41
+ /**
42
+ * Derive session configuration from a universal LLM context.
43
+ *
44
+ * A leading `system` message becomes the live model's instructions
45
+ * (`systemInstruction` from the service settings wins if both are set).
46
+ * The remaining messages become the startup `input` history.
47
+ *
48
+ * @param context The LLM context containing messages, tools, etc.
49
+ * @param options.systemInstruction System instruction from the service settings.
50
+ * @returns The session configuration values.
51
+ */
52
+ getLlmInvocationParams(context: LLMContext, options?: OpenAILiveLLMInvocationParamsOptions): Promise<OpenAILiveLLMInvocationParams>;
53
+ /**
54
+ * Get messages from a universal LLM context in a format ready for logging.
55
+ *
56
+ * Binary data (images, audio) is replaced with short placeholders.
57
+ *
58
+ * @param context The LLM context containing messages.
59
+ * @returns List of messages in a format ready for logging.
60
+ */
61
+ getMessagesForLogging(context: LLMContext): Record<string, unknown>[];
62
+ /**
63
+ * Convert tool schemas to the Responses API tool format used by the backend
64
+ * model.
65
+ *
66
+ * The Live session schema rejects the Responses-only `strict` field, so it
67
+ * is dropped from function tools.
68
+ *
69
+ * @param toolsSchema The tools schema containing functions to convert.
70
+ * @returns List of tool definitions.
71
+ */
72
+ toProviderToolsFormat(toolsSchema: ToolsSchema): Record<string, unknown>[];
73
+ /**
74
+ * Convert standard messages to the text-only startup `input` history.
75
+ *
76
+ * Tool calls, tool results and non-text content have no representation
77
+ * there and are skipped. System messages become developer messages, the
78
+ * role the startup history accepts. At most `events.MAX_INPUT_ITEMS` items
79
+ * are kept, dropping the oldest.
80
+ */
81
+ protected _toInputItems(messages: Dict[]): events.InputItem[];
82
+ /** Return a message's text content, joining text parts of list content. */
83
+ protected static _textContent(message: Dict): string;
84
+ /**
85
+ * Convert a context tool choice to the Responses API shape.
86
+ *
87
+ * The context stores the chat-completions form, whose named-function
88
+ * variant nests the name (`{"type": "function", "function": {"name": …}}`);
89
+ * the Responses API takes it flat (`{"type": "function", "name": …}`).
90
+ */
91
+ protected static _toToolChoice(toolChoice: unknown | NotGiven): unknown | null;
92
+ }
93
+ export {};
94
+ //# sourceMappingURL=open_ai_live_adapter.d.ts.map
@@ -0,0 +1,192 @@
1
+ // Copyright (c) 2024-2026, Daily
2
+ // Copyright (c) 2026, pipedog contributors
3
+ // SPDX-License-Identifier: BSD-2-Clause
4
+ //
5
+ // Ported from pipecat: src/pipecat/adapters/services/open_ai_live_adapter.py
6
+ /** OpenAI Live LLM adapter for Pipecat. */
7
+ import { BaseLLMAdapter } from "@pipedog/core/adapters/base_llm_adapter";
8
+ import { LLMSpecificMessage, } from "@pipedog/core/processors/aggregators/llm_context";
9
+ import { logger } from "@pipedog/core/utils/logger";
10
+ import { pyJsonDumps } from "@pipedog/core/utils/py_json";
11
+ import { isGiven } from "@pipedog/core/utils/types";
12
+ import * as events from "./live/events.js";
13
+ import { OpenAIResponsesLLMAdapter } from "./open_ai_responses_adapter.js";
14
+ /**
15
+ * Converts a universal `LLMContext` into OpenAI Live session configuration.
16
+ *
17
+ * The live model takes a system instruction and a text-only conversation
18
+ * history at session start; tools belong to the backend (Responses) model
19
+ * and use the Responses API tool format.
20
+ */
21
+ export class OpenAILiveLLMAdapter extends BaseLLMAdapter {
22
+ _responsesAdapter;
23
+ _warnedInputTruncated;
24
+ /** Initialize the adapter. */
25
+ constructor() {
26
+ super();
27
+ this._responsesAdapter = new OpenAIResponsesLLMAdapter();
28
+ this._warnedInputTruncated = false;
29
+ }
30
+ /** The identifier used in LLMSpecificMessage instances for OpenAI Live. */
31
+ get idForLlmSpecificMessages() {
32
+ return "openai-live";
33
+ }
34
+ /**
35
+ * Derive session configuration from a universal LLM context.
36
+ *
37
+ * A leading `system` message becomes the live model's instructions
38
+ * (`systemInstruction` from the service settings wins if both are set).
39
+ * The remaining messages become the startup `input` history.
40
+ *
41
+ * @param context The LLM context containing messages, tools, etc.
42
+ * @param options.systemInstruction System instruction from the service settings.
43
+ * @returns The session configuration values.
44
+ */
45
+ async getLlmInvocationParams(context, options = {}) {
46
+ // LLMSpecificMessages are opaque provider payloads with no place in a
47
+ // text-only history.
48
+ const messages = this.getMessages(context).filter((m) => !(m instanceof LLMSpecificMessage));
49
+ let systemFromContext = null;
50
+ if (messages.length > 0 && messages[0].role === "system") {
51
+ systemFromContext = OpenAILiveLLMAdapter._textContent(messages.shift());
52
+ }
53
+ const instructions = this._resolveSystemInstruction(systemFromContext, options.systemInstruction ?? null, { discardContextSystem: true });
54
+ // NOTE: LLMContext's tools are guaranteed to be a ToolsSchema (or NOT_GIVEN)
55
+ const tools = this.fromStandardTools(context.tools);
56
+ return {
57
+ instructions,
58
+ input: this._toInputItems(messages),
59
+ // `from_standard_tools(...) or []`: NOT_GIVEN and null are falsy upstream.
60
+ tools: (tools != null && isGiven(tools) && tools.length > 0 ? tools : []),
61
+ tool_choice: OpenAILiveLLMAdapter._toToolChoice(context.toolChoice),
62
+ };
63
+ }
64
+ /**
65
+ * Get messages from a universal LLM context in a format ready for logging.
66
+ *
67
+ * Binary data (images, audio) is replaced with short placeholders.
68
+ *
69
+ * @param context The LLM context containing messages.
70
+ * @returns List of messages in a format ready for logging.
71
+ */
72
+ getMessagesForLogging(context) {
73
+ return this.getMessages(context, { truncateLargeValues: true });
74
+ }
75
+ /**
76
+ * Convert tool schemas to the Responses API tool format used by the backend
77
+ * model.
78
+ *
79
+ * The Live session schema rejects the Responses-only `strict` field, so it
80
+ * is dropped from function tools.
81
+ *
82
+ * @param toolsSchema The tools schema containing functions to convert.
83
+ * @returns List of tool definitions.
84
+ */
85
+ toProviderToolsFormat(toolsSchema) {
86
+ const tools = [];
87
+ for (const original of this._responsesAdapter.toProviderToolsFormat(toolsSchema)) {
88
+ const tool = { ...original };
89
+ if (tool.type === "function") {
90
+ delete tool.strict;
91
+ }
92
+ tools.push(tool);
93
+ }
94
+ return tools;
95
+ }
96
+ /**
97
+ * Convert standard messages to the text-only startup `input` history.
98
+ *
99
+ * Tool calls, tool results and non-text content have no representation
100
+ * there and are skipped. System messages become developer messages, the
101
+ * role the startup history accepts. At most `events.MAX_INPUT_ITEMS` items
102
+ * are kept, dropping the oldest.
103
+ */
104
+ _toInputItems(messages) {
105
+ let items = [];
106
+ for (const message of messages) {
107
+ const role = message.role;
108
+ const text = OpenAILiveLLMAdapter._textContent(message);
109
+ if ((role === "system" || role === "developer") && text) {
110
+ items.push(new events.InputItem({
111
+ role: "developer",
112
+ content: [new events.InputTextContent({ text })],
113
+ }));
114
+ }
115
+ else if (role === "user" && text) {
116
+ items.push(new events.InputItem({ role: "user", content: [new events.InputTextContent({ text })] }));
117
+ }
118
+ else if (role === "assistant" &&
119
+ text &&
120
+ !(message.tool_calls && message.tool_calls.length > 0)) {
121
+ items.push(new events.InputItem({
122
+ role: "assistant",
123
+ content: [new events.OutputTextContent({ text })],
124
+ }));
125
+ }
126
+ else {
127
+ logger.debug(`Skipping context message with no startup-history representation: role=${pyRepr(role)}`);
128
+ }
129
+ }
130
+ if (items.length > events.MAX_INPUT_ITEMS) {
131
+ if (!this._warnedInputTruncated) {
132
+ this._warnedInputTruncated = true;
133
+ logger.warning(`Context has ${items.length} text messages but the OpenAI Live API accepts ` +
134
+ `at most ${events.MAX_INPUT_ITEMS} startup messages; keeping the most recent.`);
135
+ }
136
+ items = items.slice(-events.MAX_INPUT_ITEMS);
137
+ }
138
+ return items;
139
+ }
140
+ /** Return a message's text content, joining text parts of list content. */
141
+ static _textContent(message) {
142
+ const content = message.content;
143
+ if (typeof content === "string") {
144
+ return content;
145
+ }
146
+ if (Array.isArray(content)) {
147
+ return content
148
+ .filter((part) => part !== null &&
149
+ typeof part === "object" &&
150
+ !Array.isArray(part) &&
151
+ part.type === "text" &&
152
+ part.text)
153
+ .map((part) => part.text ?? "")
154
+ .join(" ");
155
+ }
156
+ return "";
157
+ }
158
+ /**
159
+ * Convert a context tool choice to the Responses API shape.
160
+ *
161
+ * The context stores the chat-completions form, whose named-function
162
+ * variant nests the name (`{"type": "function", "function": {"name": …}}`);
163
+ * the Responses API takes it flat (`{"type": "function", "name": …}`).
164
+ */
165
+ static _toToolChoice(toolChoice) {
166
+ if (!isGiven(toolChoice) || toolChoice == null) {
167
+ return null;
168
+ }
169
+ if (typeof toolChoice === "object" &&
170
+ !Array.isArray(toolChoice) &&
171
+ toolChoice.function !== null &&
172
+ typeof toolChoice.function === "object" &&
173
+ !Array.isArray(toolChoice.function)) {
174
+ return { type: "function", name: toolChoice.function.name ?? null };
175
+ }
176
+ return toolChoice;
177
+ }
178
+ }
179
+ /** Python's `repr()` for the values a message role can hold (a string or None). */
180
+ function pyRepr(value) {
181
+ if (value === undefined || value === null)
182
+ return "None";
183
+ if (typeof value === "string") {
184
+ // Python picks double quotes when the string has a ' and no ".
185
+ const escaped = value.replace(/\\/g, "\\\\");
186
+ if (value.includes("'") && !value.includes('"'))
187
+ return `"${escaped}"`;
188
+ return `'${escaped.replace(/'/g, "\\'")}'`;
189
+ }
190
+ return pyJsonDumps(value);
191
+ }
192
+ //# sourceMappingURL=open_ai_live_adapter.js.map
@@ -0,0 +1,95 @@
1
+ /** OpenAI Realtime LLM adapter for Pipecat. */
2
+ import { BaseLLMAdapter } from "@pipedog/core/adapters/base_llm_adapter";
3
+ import type { FunctionSchema } from "@pipedog/core/adapters/schemas/function_schema";
4
+ import { type ToolsSchema } from "@pipedog/core/adapters/schemas/tools_schema";
5
+ import { type LLMContext, type LLMContextMessage } from "@pipedog/core/processors/aggregators/llm_context";
6
+ import * as events from "./realtime/events.ts";
7
+ /**
8
+ * Context-based parameters for invoking OpenAI Realtime API.
9
+ *
10
+ * This is a placeholder until support for universal LLMContext machinery is
11
+ * added for OpenAI Realtime.
12
+ */
13
+ export interface OpenAIRealtimeLLMInvocationParams {
14
+ system_instruction: string | null;
15
+ messages: events.ConversationItem[];
16
+ tools: Record<string, unknown>[];
17
+ }
18
+ /** Options for `OpenAIRealtimeLLMAdapter.getLlmInvocationParams`. */
19
+ export interface OpenAIRealtimeLLMInvocationParamsOptions {
20
+ /** Optional system instruction from service settings. */
21
+ systemInstruction?: string | null;
22
+ /**
23
+ * The service's init-provided tools, as `_serviceTools()` returns them: a
24
+ * `ToolsSchema` or a provider-native tool list, or `null`.
25
+ */
26
+ serviceTools?: unknown;
27
+ }
28
+ /** Container for OpenAI-formatted messages converted from universal context. */
29
+ export declare class ConvertedMessages {
30
+ messages: events.ConversationItem[];
31
+ systemInstruction: string | null;
32
+ constructor(options: {
33
+ messages: events.ConversationItem[];
34
+ systemInstruction?: string | null;
35
+ });
36
+ }
37
+ /**
38
+ * LLM adapter for OpenAI Realtime API function calling.
39
+ *
40
+ * Converts Pipecat's tool schemas into the specific format required by
41
+ * OpenAI's Realtime API for function calling capabilities.
42
+ */
43
+ export declare class OpenAIRealtimeLLMAdapter extends BaseLLMAdapter<OpenAIRealtimeLLMInvocationParams> {
44
+ /** Container for OpenAI-formatted messages converted from universal context. */
45
+ static ConvertedMessages: typeof ConvertedMessages;
46
+ /** The identifier used in LLMSpecificMessage instances for OpenAI Realtime. */
47
+ get idForLlmSpecificMessages(): string;
48
+ /**
49
+ * Get OpenAI Realtime-specific LLM invocation parameters from a universal
50
+ * LLM context.
51
+ *
52
+ * The `tools` returned are the set the session should carry: the context's
53
+ * own when it has any, else the init-provided ones. Built-in tools ride
54
+ * along with whichever set is in use, and are the set when there is
55
+ * neither.
56
+ *
57
+ * @param context The LLM context containing messages, tools, etc.
58
+ * @param options.systemInstruction Optional system instruction from service settings.
59
+ * @param options.serviceTools The service's init-provided tools, as
60
+ * `_serviceTools()` returns them: a `ToolsSchema` or a provider-native
61
+ * tool list, or `null`.
62
+ * @returns Dictionary of parameters for invoking OpenAI Realtime's API.
63
+ */
64
+ getLlmInvocationParams(context: LLMContext, options?: OpenAIRealtimeLLMInvocationParamsOptions): Promise<OpenAIRealtimeLLMInvocationParams>;
65
+ /**
66
+ * Get messages from a universal LLM context in a format ready for logging
67
+ * about OpenAI Realtime.
68
+ *
69
+ * Binary data (images, audio) is replaced with short placeholders.
70
+ *
71
+ * This is a placeholder until support for universal LLMContext machinery is
72
+ * added for OpenAI Realtime.
73
+ *
74
+ * @param context The LLM context containing messages.
75
+ * @returns List of messages in a format ready for logging about OpenAI Realtime.
76
+ */
77
+ getMessagesForLogging(context: LLMContext): Record<string, unknown>[];
78
+ protected _fromUniversalContextMessages(universalContextMessages: LLMContextMessage[]): ConvertedMessages;
79
+ protected _fromUniversalContextMessage(message: LLMContextMessage): events.ConversationItem;
80
+ /**
81
+ * Convert a function schema to OpenAI Realtime format.
82
+ *
83
+ * @param func The function schema to convert.
84
+ * @returns Dictionary in OpenAI Realtime function format.
85
+ */
86
+ protected static _toOpenaiRealtimeFunctionFormat(func: FunctionSchema): Record<string, unknown>;
87
+ /**
88
+ * Convert tool schemas to OpenAI Realtime function-calling format.
89
+ *
90
+ * @param toolsSchema The tools schema containing functions to convert.
91
+ * @returns List of function definitions in OpenAI Realtime format.
92
+ */
93
+ toProviderToolsFormat(toolsSchema: ToolsSchema): Record<string, unknown>[];
94
+ }
95
+ //# sourceMappingURL=open_ai_realtime_adapter.d.ts.map