openai-harmony-js
Version:
TypeScript/JavaScript utilities for the GPT‑OSS Harmony format: renderers, parsers, tokenizers, and streaming helpers
226 lines • 8.08 kB
TypeScript
/**
* Marker strings used to delimit roles and message payloads in a Harmony-encoded stream.
* - start: marks the beginning of a message and is immediately followed by the role name
* - message: separates metadata from the following payload token
* - end: marks the end of the current message
*/
export type HarmonyDelimiters = {
start: string;
message: string;
end: string;
};
/**
* Supported message roles in a Harmony conversation.
*/
export type HarmonyRole = "system" | "developer" | "user" | "assistant" | "tool";
/**
* Supported channels for message content chunks.
* "tool" is reserved for tool call chunks; others are free-form text channels.
*/
export type HarmonyChannel = "message" | "reasoning" | "tool" | "function" | "error";
/**
* A structured tool call emitted by the assistant.
*/
export type HarmonyToolCall = {
namespace: string;
name: string;
arguments: unknown;
};
/**
* A single content chunk within a message.
* - text: free-form text routed to a specific channel
* - tool_call: a structured invocation routed to the tool channel
*/
export type HarmonyContentChunk = {
type: "text";
text: string;
channel: HarmonyChannel;
} | {
type: "tool_call";
call: HarmonyToolCall;
channel: "tool";
};
/**
* A single message in a Harmony conversation.
*/
export type HarmonyMessage = {
role: HarmonyRole;
content: HarmonyContentChunk[];
};
/**
* A complete Harmony conversation.
*/
export type HarmonyConversation = {
messages: HarmonyMessage[];
};
/**
* Options that influence rendering of a conversation into tokens.
*/
export type RenderOptions = {
delimiters?: HarmonyDelimiters;
};
export declare class HarmonyError extends Error {
code: string;
details: Record<string, unknown> | undefined;
constructor(code: string, message: string, details?: Record<string, unknown>);
}
/**
* Renders a conversation into an array of Harmony tokens suitable for completion models.
*
* @param conversation The conversation to render.
* @param options Optional rendering options, including custom delimiters.
* @returns The list of tokens representing the conversation.
*/
export declare function renderConversation(conversation: HarmonyConversation, options?: RenderOptions): string[];
/**
* Internal parser state used by the streaming parser.
*/
export type ParseState = {
messages: HarmonyMessage[];
current: HarmonyMessage | undefined;
/** Tracks last seen channel name from streaming-style tokens */
lastStreamingChannel?: string;
/** True if we just saw a <|message|> marker and are expecting a payload */
expectingPayload?: boolean;
};
/**
* Creates a stateful parser for Harmony tokens.
*
* The returned object exposes two methods:
* - push(token, delimiters?): feed one token at a time
* - finish(): finalize parsing and return the accumulated conversation
*/
export declare function createParser(): {
push: (token: string, delimiters?: HarmonyDelimiters) => void;
finish: () => HarmonyConversation;
};
/**
* Parses a list of tokens into a Harmony conversation.
*
* @param tokens The tokens to parse.
* @param delimiters Optional custom delimiters if tokens were produced with non-default markers.
* @returns The parsed conversation.
*/
export declare function parseTokens(tokens: string[], delimiters?: HarmonyDelimiters): HarmonyConversation;
/**
* Safe parse variant that does not throw on errors. Instead, returns a discriminated result.
*/
export declare function tryParseTokens(tokens: string[], delimiters?: HarmonyDelimiters): {
ok: true;
value: HarmonyConversation;
} | {
ok: false;
error: HarmonyError;
};
/**
* Tokenizes a raw completion string containing Harmony markers into token units.
*
* The tokenizer is resilient to partial streams and custom delimiters.
*
* @param input The raw completion string.
* @param delimiters Optional custom delimiters.
* @returns An array of tokens.
*/
export declare function tokenizeCompletionString(input: string, delimiters?: HarmonyDelimiters): string[];
/**
* Convenience helper that tokenizes and then parses a Harmony-formatted string.
*
* @param input The raw completion string.
* @param delimiters Optional custom delimiters.
* @returns The parsed conversation.
*/
export declare function parseConversationFromString(input: string, delimiters?: HarmonyDelimiters): HarmonyConversation;
/**
* Detects whether the given input likely uses Harmony formatting.
*
* Accepts both complete and streaming (partial) strings.
*
* @param input The string to inspect.
* @param delimiters Optional custom delimiters.
* @returns True if the string appears to be Harmony-formatted.
*/
export declare function isHarmonyFormat(input?: string, delimiters?: HarmonyDelimiters): boolean;
/**
* Extracts the latest text for the `analysis` channel from a Harmony-formatted string.
* Returns an empty string if the input is not Harmony-formatted or lacks analysis content.
*/
export declare function extractReasoningContent(input: string): string;
/**
* Extracts the latest text for the `final` channel from a Harmony-formatted string.
* Falls back to `commentary` if `final` is not present.
* For non-Harmony content, returns the original input unchanged.
*/
export declare function extractFinalContent(input: string): string;
/**
* Extracts the latest text for the `commentary` channel from a Harmony-formatted string.
* Returns an empty string if the input is not Harmony-formatted or lacks commentary content.
*/
export declare function extractCommentaryContent(input: string): string;
/** A readonly list of all supported roles. */
export declare const AllRoles: readonly HarmonyRole[];
export declare const Message: {
/**
* Builds a `HarmonyMessage` from a role and content.
*
* @param role The message role.
* @param content Either a raw string, a single content chunk, or an array of chunks.
* @returns A `HarmonyMessage` instance.
*/
fromRoleAndContent(role: HarmonyRole, content: string | HarmonyContentChunk | HarmonyContentChunk[]): HarmonyMessage;
};
export declare const Conversation: {
/**
* Builds a `HarmonyConversation` from an array of messages.
*/
fromMessages(messages: HarmonyMessage[]): HarmonyConversation;
};
/**
* Identifier for supported Harmony encodings.
*/
export type HarmonyEncodingName = "HARMONY_GPT_OSS";
/**
* Functions that encode/decode a Harmony conversation for a particular target.
*/
export type HarmonyEncoding = {
renderConversationForCompletion: (conversation: HarmonyConversation, role: HarmonyRole) => string[];
parseMessagesFromCompletionTokens: (tokens: string[], role: HarmonyRole) => HarmonyConversation;
};
/**
* Loads an encoder/decoder implementation for the given encoding name.
*
* Currently only `HARMONY_GPT_OSS` is supported.
*/
export declare function loadHarmonyEncoding(name: HarmonyEncodingName): HarmonyEncoding;
/**
* Result of incrementally parsing a Harmony stream buffer.
*/
export type StreamParseResult = {
isComplete: boolean;
currentAnalysis: string;
currentFinal: string;
currentCommentary: string;
lastChannelDetected?: string;
bufferContent: string;
};
/**
* Incremental parser for Harmony-formatted streaming content.
*
* Feed content chunks with `addContent`, inspect the latest state, and call `reset` to reuse.
*/
export declare class HarmonyStreamParser {
private buffer;
private currentChannel;
/** Adds content to the internal buffer and returns the latest parse state. */
addContent(content: string): StreamParseResult;
/** Resets internal state and clears the buffer. */
reset(): void;
/** Returns the full raw buffer accumulated so far. */
getBuffer(): string;
private parseCurrentBuffer;
private detectCurrentChannel;
private extractCompleteMessages;
private extractIncompleteContentFromWindow;
private collectChannelText;
private collectLastChannelText;
}
//# sourceMappingURL=index.d.ts.map