diff --git a/app/L0/_all/mod/_core/admin/views/agent/storage.js b/app/L0/_all/mod/_core/admin/views/agent/storage.js
index 2dbeb99d..ebab0493 100644
--- a/app/L0/_all/mod/_core/admin/views/agent/storage.js
+++ b/app/L0/_all/mod/_core/admin/views/agent/storage.js
@@ -138,11 +138,16 @@ async function normalizeStoredConfig(runtime, parsedConfig) {
runtime,
storedConfig.api_key || storedConfig.apiKey || config.DEFAULT_ADMIN_CHAT_SETTINGS.apiKey || ""
);
+ const storedBearerToken = await decodeStoredApiKey(
+ runtime,
+ storedConfig.bearer_token || storedConfig.bearerToken || config.DEFAULT_ADMIN_CHAT_SETTINGS.bearerToken || ""
+ );
return {
settings: {
apiEndpoint: String(storedConfig.api_endpoint || storedConfig.apiEndpoint || config.DEFAULT_ADMIN_CHAT_SETTINGS.apiEndpoint || "").trim(),
apiKey: storedApiKey.value,
+ bearerToken: storedBearerToken.value,
huggingfaceDtype: String(
storedConfig.huggingface_dtype || storedConfig.huggingfaceDtype || config.DEFAULT_ADMIN_CHAT_SETTINGS.huggingfaceDtype || ""
).trim(),
@@ -156,7 +161,9 @@ async function normalizeStoredConfig(runtime, parsedConfig) {
promptBudgetRatios: normalizeStoredPromptBudgetRatios(storedConfig),
provider,
storedApiKeyLocked: storedApiKey.locked,
- storedApiKeyValue: storedApiKey.storedValue
+ storedApiKeyValue: storedApiKey.storedValue,
+ storedBearerTokenLocked: storedBearerToken.locked,
+ storedBearerTokenValue: storedBearerToken.storedValue
},
systemPrompt: String(
storedConfig.custom_system_prompt ||
@@ -173,6 +180,11 @@ async function buildStoredConfigPayload(runtime, { settings, systemPrompt }) {
const payload = {
api_endpoint: String(settings?.apiEndpoint || config.DEFAULT_ADMIN_CHAT_SETTINGS.apiEndpoint || "").trim(),
api_key: await encodeStoredApiKey(runtime, settings),
+ bearer_token: await encodeStoredApiKey(runtime, {
+ apiKey: settings?.bearerToken,
+ storedApiKeyValue: settings?.storedBearerTokenValue,
+ storedApiKeyLocked: settings?.storedBearerTokenLocked
+ }),
huggingface_dtype: String(settings?.huggingfaceDtype || config.DEFAULT_ADMIN_CHAT_SETTINGS.huggingfaceDtype || "").trim(),
huggingface_model: String(settings?.huggingfaceModel || config.DEFAULT_ADMIN_CHAT_SETTINGS.huggingfaceModel || "").trim(),
local_provider: config.normalizeAdminChatLocalProvider(settings?.localProvider),
@@ -220,6 +232,8 @@ export async function saveAdminChatConfig(nextConfig) {
if (nextConfig?.settings && typeof nextConfig.settings === "object") {
nextConfig.settings.storedApiKeyLocked = false;
nextConfig.settings.storedApiKeyValue = String(payload.api_key || "").trim();
+ nextConfig.settings.storedBearerTokenLocked = false;
+ nextConfig.settings.storedBearerTokenValue = String(payload.bearer_token || "").trim();
}
} catch (error) {
throw new Error(`Unable to save admin chat config: ${error.message}`);
diff --git a/app/L0/_all/mod/_core/admin/views/agent/store.js b/app/L0/_all/mod/_core/admin/views/agent/store.js
index 4aacf7b4..1cefa25e 100644
--- a/app/L0/_all/mod/_core/admin/views/agent/store.js
+++ b/app/L0/_all/mod/_core/admin/views/agent/store.js
@@ -1877,6 +1877,7 @@ const model = {
this.settings = {
apiEndpoint: (this.settingsDraft.apiEndpoint || "").trim(),
apiKey: (this.settingsDraft.apiKey || "").trim(),
+ bearerToken: (this.settingsDraft.bearerToken || "").trim(),
huggingfaceDtype: (this.settingsDraft.huggingfaceDtype || "").trim(),
huggingfaceModel: normalizeHuggingFaceModelInput(this.settingsDraft.huggingfaceModel || ""),
localProvider,
@@ -1886,7 +1887,9 @@ const model = {
promptBudgetRatios: clonePromptBudgetRatios(this.settingsDraft.promptBudgetRatios),
provider,
storedApiKeyLocked: this.settings.storedApiKeyLocked === true,
- storedApiKeyValue: String(this.settings.storedApiKeyValue || "")
+ storedApiKeyValue: String(this.settings.storedApiKeyValue || ""),
+ storedBearerTokenLocked: this.settings.storedBearerTokenLocked === true,
+ storedBearerTokenValue: String(this.settings.storedBearerTokenValue || "")
};
try {
diff --git a/app/L0/_all/mod/_core/onscreen_agent/api.js b/app/L0/_all/mod/_core/onscreen_agent/api.js
index 510d23a6..e9367cf0 100644
--- a/app/L0/_all/mod/_core/onscreen_agent/api.js
+++ b/app/L0/_all/mod/_core/onscreen_agent/api.js
@@ -211,12 +211,14 @@ function normalizeCompletionMessagesForLocal(messages) {
.filter(Boolean);
}
-function createApiRequestHeaders(apiKey) {
+function createApiRequestHeaders(apiKey, bearerToken) {
const headers = {
"Content-Type": "application/json"
};
- if (apiKey) {
+ if (bearerToken) {
+ headers.Authorization = `Bearer ${bearerToken}`;
+ } else if (apiKey) {
headers.Authorization = `Bearer ${apiKey}`;
}
@@ -303,8 +305,8 @@ export class OnscreenAgentApiLlmClient extends OnscreenAgentLlmClient {
throw new Error("Set an API endpoint before sending a message.");
}
- if (!settings.apiKey.trim()) {
- throw new Error("Set an API key before sending a message.");
+ if (!settings.apiKey.trim() && !(settings.bearerToken || "").trim()) {
+ throw new Error("Set an API key or authorization bearer token before sending a message.");
}
if (!settings.model.trim()) {
@@ -421,7 +423,10 @@ export const prepareOnscreenAgentApiRequest = globalThis.space.extend(
return {
apiEndpoint,
- headers: createApiRequestHeaders(String(effectiveSettings?.apiKey || "").trim()),
+ headers: createApiRequestHeaders(
+ String(effectiveSettings?.apiKey || "").trim(),
+ String(effectiveSettings?.bearerToken || "").trim()
+ ),
messages: Array.isArray(effectivePreparedRequest?.messages) ? effectivePreparedRequest.messages : [],
method: "POST",
preparedRequest: effectivePreparedRequest,
diff --git a/app/L0/_all/mod/_core/onscreen_agent/config.js b/app/L0/_all/mod/_core/onscreen_agent/config.js
index bcca393a..9d5e92e8 100644
--- a/app/L0/_all/mod/_core/onscreen_agent/config.js
+++ b/app/L0/_all/mod/_core/onscreen_agent/config.js
@@ -21,6 +21,7 @@ export const ONSCREEN_AGENT_HIDDEN_EDGE = Object.freeze({
export const DEFAULT_ONSCREEN_AGENT_SETTINGS = {
apiEndpoint: "https://openrouter.ai/api/v1/chat/completions",
apiKey: "",
+ bearerToken: "",
huggingfaceDtype: "q4",
huggingfaceModel: "",
localProvider: ONSCREEN_AGENT_LOCAL_PROVIDER.HUGGINGFACE,
diff --git a/app/L0/_all/mod/_core/onscreen_agent/panel.html b/app/L0/_all/mod/_core/onscreen_agent/panel.html
index a4510bdc..81f7cbe5 100644
--- a/app/L0/_all/mod/_core/onscreen_agent/panel.html
+++ b/app/L0/_all/mod/_core/onscreen_agent/panel.html
@@ -360,6 +360,13 @@
Model, credentials, params, and instructions
API Key
+
diff --git a/app/L0/_all/mod/_core/onscreen_agent/storage.js b/app/L0/_all/mod/_core/onscreen_agent/storage.js
index 6a9b22f2..185431b5 100644
--- a/app/L0/_all/mod/_core/onscreen_agent/storage.js
+++ b/app/L0/_all/mod/_core/onscreen_agent/storage.js
@@ -202,6 +202,10 @@ async function normalizeStoredConfig(runtime, parsedConfig) {
runtime,
storedConfig.api_key || storedConfig.apiKey || config.DEFAULT_ONSCREEN_AGENT_SETTINGS.apiKey || ""
);
+ const storedBearerToken = await decodeStoredApiKey(
+ runtime,
+ storedConfig.bearer_token || storedConfig.bearerToken || config.DEFAULT_ONSCREEN_AGENT_SETTINGS.bearerToken || ""
+ );
const legacyDisplayMode =
storedConfig.collapsed === true
? DISPLAY_MODE_COMPACT
@@ -213,6 +217,7 @@ async function normalizeStoredConfig(runtime, parsedConfig) {
settings: {
apiEndpoint: String(storedConfig.api_endpoint || storedConfig.apiEndpoint || config.DEFAULT_ONSCREEN_AGENT_SETTINGS.apiEndpoint || "").trim(),
apiKey: storedApiKey.value,
+ bearerToken: storedBearerToken.value,
huggingfaceDtype: String(
storedConfig.huggingface_dtype ||
storedConfig.huggingfaceDtype ||
@@ -232,7 +237,9 @@ async function normalizeStoredConfig(runtime, parsedConfig) {
promptBudgetRatios: normalizeStoredPromptBudgetRatios(storedConfig),
provider,
storedApiKeyLocked: storedApiKey.locked,
- storedApiKeyValue: storedApiKey.storedValue
+ storedApiKeyValue: storedApiKey.storedValue,
+ storedBearerTokenLocked: storedBearerToken.locked,
+ storedBearerTokenValue: storedBearerToken.storedValue
},
systemPrompt: String(
storedConfig.custom_system_prompt ||
@@ -278,6 +285,11 @@ async function buildStoredConfigPayload(runtime, { settings, systemPrompt }) {
const payload = {
api_endpoint: String(settings?.apiEndpoint || config.DEFAULT_ONSCREEN_AGENT_SETTINGS.apiEndpoint || "").trim(),
api_key: await encodeStoredApiKey(runtime, settings),
+ bearer_token: await encodeStoredApiKey(runtime, {
+ apiKey: settings?.bearerToken,
+ storedApiKeyValue: settings?.storedBearerTokenValue,
+ storedApiKeyLocked: settings?.storedBearerTokenLocked
+ }),
huggingface_dtype: String(settings?.huggingfaceDtype || config.DEFAULT_ONSCREEN_AGENT_SETTINGS.huggingfaceDtype || "").trim(),
huggingface_model: String(settings?.huggingfaceModel || config.DEFAULT_ONSCREEN_AGENT_SETTINGS.huggingfaceModel || "").trim(),
local_provider: config.normalizeOnscreenAgentLocalProvider(settings?.localProvider),
@@ -446,6 +458,8 @@ export async function saveOnscreenAgentConfig(nextConfig) {
if (nextConfig?.settings && typeof nextConfig.settings === "object") {
nextConfig.settings.storedApiKeyLocked = false;
nextConfig.settings.storedApiKeyValue = String(payload.api_key || "").trim();
+ nextConfig.settings.storedBearerTokenLocked = false;
+ nextConfig.settings.storedBearerTokenValue = String(payload.bearer_token || "").trim();
}
} catch (error) {
throw new Error(`Unable to save onscreen agent config: ${error.message}`);
diff --git a/app/L0/_all/mod/_core/onscreen_agent/store.js b/app/L0/_all/mod/_core/onscreen_agent/store.js
index ae4fba33..ac4bf281 100644
--- a/app/L0/_all/mod/_core/onscreen_agent/store.js
+++ b/app/L0/_all/mod/_core/onscreen_agent/store.js
@@ -4604,6 +4604,7 @@ const model = {
this.settings = {
apiEndpoint: (this.settingsDraft.apiEndpoint || "").trim(),
apiKey: (this.settingsDraft.apiKey || "").trim(),
+ bearerToken: (this.settingsDraft.bearerToken || "").trim(),
huggingfaceDtype: (this.settingsDraft.huggingfaceDtype || "").trim(),
huggingfaceModel: normalizeHuggingFaceModelInput(this.settingsDraft.huggingfaceModel || ""),
localProvider,
@@ -4613,7 +4614,9 @@ const model = {
promptBudgetRatios: clonePromptBudgetRatios(this.settingsDraft.promptBudgetRatios),
provider,
storedApiKeyLocked: this.settings.storedApiKeyLocked === true,
- storedApiKeyValue: String(this.settings.storedApiKeyValue || "")
+ storedApiKeyValue: String(this.settings.storedApiKeyValue || ""),
+ storedBearerTokenLocked: this.settings.storedBearerTokenLocked === true,
+ storedBearerTokenValue: String(this.settings.storedBearerTokenValue || "")
};
this.systemPrompt = draftPrompt;
this.systemPromptDraft = draftPrompt;