Spaces:
Sleeping
Sleeping
Download runtime-dist/runtime/agentProvider.js from kenken999/gemikenwork: direct link, hf CLI and curl.
- Browser
- Download file 8.23 kB
-
https://huggingface.co/spaces/kenken999/gemikenwork/resolve/main/runtime-dist/runtime/agentProvider.js
- Command line
-
hf download hf://spaces/kenken999/gemikenwork/runtime-dist/runtime/agentProvider.js
-
curl -L -o agentProvider.js https://huggingface.co/spaces/kenken999/gemikenwork/resolve/main/runtime-dist/runtime/agentProvider.js
8.23 kB
| const DEFAULT_MAX_ACTIONS = 20; | |
| const DEFAULT_MAX_TEXT_LENGTH = 2000; | |
| export const availableProviderActions = [ | |
| "say", | |
| "startTyping", | |
| "stopTyping", | |
| "moveTo", | |
| "teleport", | |
| "setStatus", | |
| "emitEvent", | |
| "interruptAudioStream", | |
| ]; | |
| export function normalizeProviderActions(value, options = {}) { | |
| const maxActions = options.maxActions ?? DEFAULT_MAX_ACTIONS; | |
| if (Array.isArray(value)) { | |
| const actions = []; | |
| for (const entry of value.slice(0, maxActions)) { | |
| const action = normalizeProviderAction(entry, options); | |
| if (action) { | |
| actions.push(action); | |
| } | |
| } | |
| return actions; | |
| } | |
| if (isRecord(value)) { | |
| if (Array.isArray(value.actions)) { | |
| return normalizeProviderActions(value.actions, options); | |
| } | |
| const action = normalizeProviderAction(value, options); | |
| return action ? [action] : []; | |
| } | |
| return []; | |
| } | |
| export function actionsFromProviderResponse(value, options = {}) { | |
| const normalized = normalizeProviderActions(value, options); | |
| if (normalized.length > 0) { | |
| return normalized; | |
| } | |
| const responseText = extractResponseText(value); | |
| if (!responseText) { | |
| return []; | |
| } | |
| const actionsFromText = extractActionsFromText(responseText, options); | |
| if (actionsFromText.length > 0) { | |
| return actionsFromText; | |
| } | |
| return [ | |
| { | |
| type: "say", | |
| channel: options.defaultChannel ?? "bubble", | |
| text: truncateText(responseText, options.maxTextLength ?? DEFAULT_MAX_TEXT_LENGTH), | |
| }, | |
| ]; | |
| } | |
| export function extractActionsFromText(text, options = {}) { | |
| const candidates = jsonCandidatesFromText(text); | |
| for (const candidate of candidates) { | |
| try { | |
| const parsed = JSON.parse(candidate); | |
| const actions = normalizeProviderActions(parsed, options); | |
| if (actions.length > 0) { | |
| return actions; | |
| } | |
| } | |
| catch (_error) { | |
| // Try the next candidate. | |
| } | |
| } | |
| return []; | |
| } | |
| export function shouldRespondToChat(observation, names, respondToAllBubbleMessages) { | |
| if (observation.type !== "chatMessage" || observation.scope !== "bubble") { | |
| return false; | |
| } | |
| if (respondToAllBubbleMessages) { | |
| return true; | |
| } | |
| const normalized = observation.message.toLowerCase(); | |
| return names | |
| .filter((name) => name.trim().length > 0) | |
| .some((name) => normalized.includes(name.toLowerCase()) || normalized.includes(`@${name.toLowerCase()}`)); | |
| } | |
| function normalizeProviderAction(value, options) { | |
| if (!isRecord(value) || typeof value.type !== "string") { | |
| return undefined; | |
| } | |
| const maxTextLength = options.maxTextLength ?? DEFAULT_MAX_TEXT_LENGTH; | |
| switch (value.type) { | |
| case "say": { | |
| if (typeof value.text !== "string" || value.text.trim().length === 0) { | |
| return undefined; | |
| } | |
| const channel = value.channel === "local" || value.channel === "bubble" ? value.channel : options.defaultChannel ?? "bubble"; | |
| const action = { | |
| type: "say", | |
| channel, | |
| text: truncateText(value.text, maxTextLength), | |
| }; | |
| if (typeof value.author === "string") { | |
| action.author = truncateText(value.author, 100); | |
| } | |
| return action; | |
| } | |
| case "startTyping": { | |
| const channel = value.channel === "local" || value.channel === "bubble" ? value.channel : options.defaultChannel ?? "bubble"; | |
| const action = { | |
| type: "startTyping", | |
| channel, | |
| }; | |
| if (typeof value.author === "string") { | |
| action.author = truncateText(value.author, 100); | |
| } | |
| return action; | |
| } | |
| case "stopTyping": { | |
| const channel = value.channel === "local" || value.channel === "bubble" ? value.channel : options.defaultChannel ?? "bubble"; | |
| const action = { | |
| type: "stopTyping", | |
| channel, | |
| }; | |
| if (typeof value.author === "string") { | |
| action.author = truncateText(value.author, 100); | |
| } | |
| return action; | |
| } | |
| case "moveTo": { | |
| if (!isFiniteNumber(value.x) || !isFiniteNumber(value.y)) { | |
| return undefined; | |
| } | |
| const action = { | |
| type: "moveTo", | |
| x: value.x, | |
| y: value.y, | |
| }; | |
| if (isFiniteNumber(value.speed) && value.speed > 0) { | |
| action.speed = value.speed; | |
| } | |
| return action; | |
| } | |
| case "teleport": { | |
| if (!isFiniteNumber(value.x) || !isFiniteNumber(value.y)) { | |
| return undefined; | |
| } | |
| return { type: "teleport", x: value.x, y: value.y }; | |
| } | |
| case "setStatus": { | |
| if (value.status !== "ONLINE" && | |
| value.status !== "BUSY" && | |
| value.status !== "DO_NOT_DISTURB" && | |
| value.status !== "BACK_IN_A_MOMENT") { | |
| return undefined; | |
| } | |
| return { type: "setStatus", status: value.status }; | |
| } | |
| case "emitEvent": { | |
| if (typeof value.name !== "string" || value.name.trim().length === 0) { | |
| return undefined; | |
| } | |
| return { | |
| type: "emitEvent", | |
| name: truncateText(value.name, 200), | |
| data: toJsonValue(value.data), | |
| }; | |
| } | |
| case "speakPcm": { | |
| if (!isFiniteNumber(value.sampleRate) || typeof value.pcm16Base64 !== "string" || value.pcm16Base64.length === 0) { | |
| return undefined; | |
| } | |
| return { | |
| type: "speakPcm", | |
| sampleRate: value.sampleRate, | |
| pcm16Base64: value.pcm16Base64, | |
| }; | |
| } | |
| case "closeAudioStream": { | |
| return { type: "closeAudioStream" }; | |
| } | |
| case "interruptAudioStream": { | |
| return { type: "interruptAudioStream" }; | |
| } | |
| default: | |
| return undefined; | |
| } | |
| } | |
| function extractResponseText(value) { | |
| if (typeof value === "string") { | |
| return value.trim() || undefined; | |
| } | |
| if (!isRecord(value)) { | |
| return undefined; | |
| } | |
| for (const key of ["text", "reply", "message", "content", "response", "output", "result"]) { | |
| const entry = value[key]; | |
| if (typeof entry === "string" && entry.trim().length > 0) { | |
| return entry.trim(); | |
| } | |
| const nested = extractResponseText(entry); | |
| if (nested) { | |
| return nested; | |
| } | |
| } | |
| return undefined; | |
| } | |
| function jsonCandidatesFromText(text) { | |
| const trimmed = text.trim(); | |
| const candidates = [trimmed]; | |
| for (const match of trimmed.matchAll(/```(?:json)?\s*([\s\S]*?)```/gi)) { | |
| if (match[1]) { | |
| candidates.push(match[1].trim()); | |
| } | |
| } | |
| const objectStart = trimmed.indexOf("{"); | |
| const objectEnd = trimmed.lastIndexOf("}"); | |
| if (objectStart >= 0 && objectEnd > objectStart) { | |
| candidates.push(trimmed.slice(objectStart, objectEnd + 1)); | |
| } | |
| const arrayStart = trimmed.indexOf("["); | |
| const arrayEnd = trimmed.lastIndexOf("]"); | |
| if (arrayStart >= 0 && arrayEnd > arrayStart) { | |
| candidates.push(trimmed.slice(arrayStart, arrayEnd + 1)); | |
| } | |
| return Array.from(new Set(candidates)); | |
| } | |
| function truncateText(value, maxLength) { | |
| if (value.length <= maxLength) { | |
| return value; | |
| } | |
| return `${value.slice(0, Math.max(0, maxLength - 3))}...`; | |
| } | |
| function toJsonValue(value) { | |
| if (value === undefined) { | |
| return null; | |
| } | |
| return JSON.parse(JSON.stringify(value)); | |
| } | |
| function isRecord(value) { | |
| return typeof value === "object" && value !== null && !Array.isArray(value); | |
| } | |
| function isFiniteNumber(value) { | |
| return typeof value === "number" && Number.isFinite(value); | |
| } | |
| //# sourceMappingURL=agentProvider.js.map |