311 lines
12 KiB
JavaScript
311 lines
12 KiB
JavaScript
(function(global, factory) {
|
||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('uuid'), require('partial-json'), require('@ag-ui/client')) :
|
||
typeof define === 'function' && define.amd ? define(['exports', 'uuid', 'partial-json', '@ag-ui/client'], factory) :
|
||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitNextShared = {}), global.uuid,global.partialJson,global.AgUIClient));
|
||
})(this, function(exports, uuid, partial_json, _ag_ui_client) {
|
||
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||
//#region \0rolldown/runtime.js
|
||
var __create = Object.create;
|
||
var __defProp = Object.defineProperty;
|
||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||
var __getProtoOf = Object.getPrototypeOf;
|
||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||
var __copyProps = (to, from, except, desc) => {
|
||
if (from && typeof from === "object" || typeof from === "function") {
|
||
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
||
key = keys[i];
|
||
if (!__hasOwnProp.call(to, key) && key !== except) {
|
||
__defProp(to, key, {
|
||
get: ((k) => from[k]).bind(null, key),
|
||
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
||
});
|
||
}
|
||
}
|
||
}
|
||
return to;
|
||
};
|
||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
||
value: mod,
|
||
enumerable: true
|
||
}) : target, mod));
|
||
|
||
//#endregion
|
||
partial_json = __toESM(partial_json);
|
||
|
||
//#region src/utils.ts
|
||
function randomUUID() {
|
||
return (0, uuid.v4)();
|
||
}
|
||
function partialJSONParse(json) {
|
||
try {
|
||
const parsed = partial_json.parse(json);
|
||
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) return parsed;
|
||
console.warn(`[CopilotKit] Tool arguments parsed to non-object (${typeof parsed}), falling back to empty object`);
|
||
return {};
|
||
} catch (error) {
|
||
return {};
|
||
}
|
||
}
|
||
/**
|
||
* Safely parses a JSON string into a plain object for tool arguments.
|
||
* Handles two failure modes:
|
||
* 1. Malformed JSON (SyntaxError from JSON.parse)
|
||
* 2. Valid JSON that isn't a plain object (e.g. "", [], null, 42, true)
|
||
* Falls back to an empty object for safety in both cases.
|
||
*/
|
||
function safeParseToolArgs(raw) {
|
||
try {
|
||
const parsed = JSON.parse(raw);
|
||
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) return parsed;
|
||
console.warn(`[CopilotKit] Tool arguments parsed to non-object (${typeof parsed}), falling back to empty object`);
|
||
return {};
|
||
} catch (_unused) {
|
||
console.warn("[CopilotKit] Failed to parse tool arguments, falling back to empty object");
|
||
return {};
|
||
}
|
||
}
|
||
/**
|
||
* Returns an exponential backoff function suitable for Phoenix.js
|
||
* `reconnectAfterMs` and `rejoinAfterMs` options.
|
||
*
|
||
* @param baseMs - Initial delay for the first retry attempt.
|
||
* @param maxMs - Upper bound — delays are capped at this value.
|
||
*
|
||
* Phoenix calls the returned function with a 1-based `tries` count.
|
||
* The delay doubles on each attempt: baseMs, 2×baseMs, 4×baseMs, …, maxMs.
|
||
*/
|
||
function phoenixExponentialBackoff(baseMs, maxMs) {
|
||
return (tries) => Math.min(baseMs * 2 ** (tries - 1), maxMs);
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/logger.ts
|
||
const logger = console;
|
||
|
||
//#endregion
|
||
//#region src/constants.ts
|
||
const DEFAULT_AGENT_ID = "default";
|
||
/** Phoenix channel event name used for all AG-UI events. */
|
||
const AG_UI_CHANNEL_EVENT = "ag-ui";
|
||
|
||
//#endregion
|
||
//#region src/finalize-events.ts
|
||
const defaultStopMessage = "Run stopped by user";
|
||
const defaultAbruptEndMessage = "Run ended without emitting a terminal event";
|
||
function finalizeRunEvents(events, options = {}) {
|
||
const { stopRequested = false, interruptionMessage } = options;
|
||
const resolvedStopMessage = interruptionMessage !== null && interruptionMessage !== void 0 ? interruptionMessage : defaultStopMessage;
|
||
const resolvedAbruptMessage = interruptionMessage && interruptionMessage !== defaultStopMessage ? interruptionMessage : defaultAbruptEndMessage;
|
||
const appended = [];
|
||
const openMessageIds = /* @__PURE__ */ new Set();
|
||
const openToolCalls = /* @__PURE__ */ new Map();
|
||
for (const event of events) switch (event.type) {
|
||
case _ag_ui_client.EventType.TEXT_MESSAGE_START: {
|
||
const messageId = event.messageId;
|
||
if (typeof messageId === "string") openMessageIds.add(messageId);
|
||
break;
|
||
}
|
||
case _ag_ui_client.EventType.TEXT_MESSAGE_END: {
|
||
const messageId = event.messageId;
|
||
if (typeof messageId === "string") openMessageIds.delete(messageId);
|
||
break;
|
||
}
|
||
case _ag_ui_client.EventType.TOOL_CALL_START: {
|
||
const toolCallId = event.toolCallId;
|
||
if (typeof toolCallId === "string") openToolCalls.set(toolCallId, {
|
||
hasEnd: false,
|
||
hasResult: false
|
||
});
|
||
break;
|
||
}
|
||
case _ag_ui_client.EventType.TOOL_CALL_END: {
|
||
const toolCallId = event.toolCallId;
|
||
const info = toolCallId ? openToolCalls.get(toolCallId) : void 0;
|
||
if (info) info.hasEnd = true;
|
||
break;
|
||
}
|
||
case _ag_ui_client.EventType.TOOL_CALL_RESULT: {
|
||
const toolCallId = event.toolCallId;
|
||
const info = toolCallId ? openToolCalls.get(toolCallId) : void 0;
|
||
if (info) info.hasResult = true;
|
||
break;
|
||
}
|
||
default: break;
|
||
}
|
||
const hasRunFinished = events.some((event) => event.type === _ag_ui_client.EventType.RUN_FINISHED);
|
||
const hasRunError = events.some((event) => event.type === _ag_ui_client.EventType.RUN_ERROR);
|
||
const terminalEventMissing = !(hasRunFinished || hasRunError);
|
||
for (const messageId of openMessageIds) {
|
||
const endEvent = {
|
||
type: _ag_ui_client.EventType.TEXT_MESSAGE_END,
|
||
messageId
|
||
};
|
||
events.push(endEvent);
|
||
appended.push(endEvent);
|
||
}
|
||
for (const [toolCallId, info] of openToolCalls) {
|
||
if (!info.hasEnd) {
|
||
const endEvent = {
|
||
type: _ag_ui_client.EventType.TOOL_CALL_END,
|
||
toolCallId
|
||
};
|
||
events.push(endEvent);
|
||
appended.push(endEvent);
|
||
}
|
||
if (terminalEventMissing && !info.hasResult) {
|
||
const resultEvent = {
|
||
type: _ag_ui_client.EventType.TOOL_CALL_RESULT,
|
||
toolCallId,
|
||
messageId: `${toolCallId !== null && toolCallId !== void 0 ? toolCallId : randomUUID()}-result`,
|
||
role: "tool",
|
||
content: JSON.stringify(stopRequested ? {
|
||
status: "stopped",
|
||
reason: "stop_requested",
|
||
message: resolvedStopMessage
|
||
} : {
|
||
status: "error",
|
||
reason: "missing_terminal_event",
|
||
message: resolvedAbruptMessage
|
||
})
|
||
};
|
||
events.push(resultEvent);
|
||
appended.push(resultEvent);
|
||
}
|
||
}
|
||
if (terminalEventMissing) if (stopRequested) {
|
||
const finishedEvent = { type: _ag_ui_client.EventType.RUN_FINISHED };
|
||
events.push(finishedEvent);
|
||
appended.push(finishedEvent);
|
||
} else {
|
||
const errorEvent = {
|
||
type: _ag_ui_client.EventType.RUN_ERROR,
|
||
message: resolvedAbruptMessage,
|
||
code: "INCOMPLETE_STREAM"
|
||
};
|
||
events.push(errorEvent);
|
||
appended.push(errorEvent);
|
||
}
|
||
return appended;
|
||
}
|
||
|
||
//#endregion
|
||
//#region src/transcription-errors.ts
|
||
/**
|
||
* Error codes for transcription HTTP responses.
|
||
* Uses snake_case to align with existing CopilotKitCoreErrorCode pattern.
|
||
* These codes are returned by the runtime and parsed by the client.
|
||
*/
|
||
let TranscriptionErrorCode = /* @__PURE__ */ function(TranscriptionErrorCode) {
|
||
/** Transcription service not configured in runtime */
|
||
TranscriptionErrorCode["SERVICE_NOT_CONFIGURED"] = "service_not_configured";
|
||
/** Audio format not supported */
|
||
TranscriptionErrorCode["INVALID_AUDIO_FORMAT"] = "invalid_audio_format";
|
||
/** Audio file is too long */
|
||
TranscriptionErrorCode["AUDIO_TOO_LONG"] = "audio_too_long";
|
||
/** Audio file is empty or too short */
|
||
TranscriptionErrorCode["AUDIO_TOO_SHORT"] = "audio_too_short";
|
||
/** Rate limited by transcription provider */
|
||
TranscriptionErrorCode["RATE_LIMITED"] = "rate_limited";
|
||
/** Authentication failed with transcription provider */
|
||
TranscriptionErrorCode["AUTH_FAILED"] = "auth_failed";
|
||
/** Transcription provider returned an error */
|
||
TranscriptionErrorCode["PROVIDER_ERROR"] = "provider_error";
|
||
/** Network error during transcription */
|
||
TranscriptionErrorCode["NETWORK_ERROR"] = "network_error";
|
||
/** Invalid request format */
|
||
TranscriptionErrorCode["INVALID_REQUEST"] = "invalid_request";
|
||
return TranscriptionErrorCode;
|
||
}({});
|
||
/**
|
||
* Helper functions to create transcription error responses.
|
||
* Used by the runtime to return consistent error responses.
|
||
*/
|
||
const TranscriptionErrors = {
|
||
serviceNotConfigured: () => ({
|
||
error: TranscriptionErrorCode.SERVICE_NOT_CONFIGURED,
|
||
message: "Transcription service is not configured",
|
||
retryable: false
|
||
}),
|
||
invalidAudioFormat: (format, supported) => ({
|
||
error: TranscriptionErrorCode.INVALID_AUDIO_FORMAT,
|
||
message: `Unsupported audio format: ${format}. Supported: ${supported.join(", ")}`,
|
||
retryable: false
|
||
}),
|
||
invalidRequest: (details) => ({
|
||
error: TranscriptionErrorCode.INVALID_REQUEST,
|
||
message: details,
|
||
retryable: false
|
||
}),
|
||
rateLimited: () => ({
|
||
error: TranscriptionErrorCode.RATE_LIMITED,
|
||
message: "Rate limited. Please try again later.",
|
||
retryable: true
|
||
}),
|
||
authFailed: () => ({
|
||
error: TranscriptionErrorCode.AUTH_FAILED,
|
||
message: "Authentication failed with transcription provider",
|
||
retryable: false
|
||
}),
|
||
providerError: (message) => ({
|
||
error: TranscriptionErrorCode.PROVIDER_ERROR,
|
||
message,
|
||
retryable: true
|
||
}),
|
||
networkError: (message = "Network error during transcription") => ({
|
||
error: TranscriptionErrorCode.NETWORK_ERROR,
|
||
message,
|
||
retryable: true
|
||
}),
|
||
audioTooLong: () => ({
|
||
error: TranscriptionErrorCode.AUDIO_TOO_LONG,
|
||
message: "Audio file is too long",
|
||
retryable: false
|
||
}),
|
||
audioTooShort: () => ({
|
||
error: TranscriptionErrorCode.AUDIO_TOO_SHORT,
|
||
message: "Audio is too short to transcribe",
|
||
retryable: false
|
||
})
|
||
};
|
||
|
||
//#endregion
|
||
//#region src/standard-schema.ts
|
||
/**
|
||
* Check whether a schema implements the Standard JSON Schema V1 protocol.
|
||
*/
|
||
function hasStandardJsonSchema(schema) {
|
||
const props = schema["~standard"];
|
||
return props != null && typeof props === "object" && "jsonSchema" in props && props.jsonSchema != null && typeof props.jsonSchema === "object" && "input" in props.jsonSchema && typeof props.jsonSchema.input === "function";
|
||
}
|
||
/**
|
||
* Convert any StandardSchemaV1-compatible schema to a JSON Schema object.
|
||
*
|
||
* Strategy:
|
||
* 1. If the schema implements Standard JSON Schema V1 (`~standard.jsonSchema`),
|
||
* call `schema['~standard'].jsonSchema.input({ target: 'draft-07' })`.
|
||
* 2. If the schema is a Zod v3 schema (`~standard.vendor === 'zod'`), use the
|
||
* injected `zodToJsonSchema()` function.
|
||
* 3. Otherwise throw a descriptive error.
|
||
*/
|
||
function schemaToJsonSchema(schema, options) {
|
||
if (hasStandardJsonSchema(schema)) return schema["~standard"].jsonSchema.input({ target: "draft-07" });
|
||
const vendor = schema["~standard"].vendor;
|
||
if (vendor === "zod" && (options === null || options === void 0 ? void 0 : options.zodToJsonSchema)) return options.zodToJsonSchema(schema, { $refStrategy: "none" });
|
||
throw new Error(`Cannot convert schema to JSON Schema. The schema (vendor: "${vendor}") does not implement Standard JSON Schema V1 and no zodToJsonSchema fallback is available. Use a library that supports Standard JSON Schema (e.g., Zod 3.24+, Valibot v1+, ArkType v2+) or pass a zodToJsonSchema function in options.`);
|
||
}
|
||
|
||
//#endregion
|
||
exports.AG_UI_CHANNEL_EVENT = AG_UI_CHANNEL_EVENT;
|
||
exports.DEFAULT_AGENT_ID = DEFAULT_AGENT_ID;
|
||
exports.TranscriptionErrorCode = TranscriptionErrorCode;
|
||
exports.TranscriptionErrors = TranscriptionErrors;
|
||
exports.finalizeRunEvents = finalizeRunEvents;
|
||
exports.logger = logger;
|
||
exports.partialJSONParse = partialJSONParse;
|
||
exports.phoenixExponentialBackoff = phoenixExponentialBackoff;
|
||
exports.randomUUID = randomUUID;
|
||
exports.safeParseToolArgs = safeParseToolArgs;
|
||
exports.schemaToJsonSchema = schemaToJsonSchema;
|
||
});
|
||
//# sourceMappingURL=index.umd.js.map
|