mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 00:04:49 +00:00
Enable thinking selector in MessageEditor
- Import Select component from mini-lit and Brain icon from lucide - Add thinkingLevel property to track current thinking level (off/minimal/low/medium/high) - Enable showThinkingSelector (was disabled before) - Add onThinkingChange callback for thinking level changes - Render Select component with thinking level options when model supports reasoning - Position thinking selector on left side next to attachment button - Add i18n translations for Off/Minimal/Low/Medium/High in English and German - Rename showThinking → showThinkingSelector in AgentInterface and ChatPanel for consistency - Remove showDebugToggle property from AgentInterface (unused) - Clean up browser-javascript tool output message (remove CSP note)
This commit is contained in:
parent
414a4eb8fd
commit
53e339ddb8
5 changed files with 54 additions and 12 deletions
|
|
@ -309,9 +309,7 @@ This ensures reliable execution.`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
output:
|
output: output.trim() || "Code executed successfully (no output)",
|
||||||
output.trim() ||
|
|
||||||
"Code executed successfully (no output)\n\n⚠️ Note: CSP blocked direct execution. Code ran via JailJS interpreter.",
|
|
||||||
isError: false,
|
isError: false,
|
||||||
details: { files },
|
details: { files },
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ export class ChatPanel extends LitElement {
|
||||||
.session=${this.session}
|
.session=${this.session}
|
||||||
.enableAttachments=${true}
|
.enableAttachments=${true}
|
||||||
.enableModelSelector=${true}
|
.enableModelSelector=${true}
|
||||||
.enableThinking=${true}
|
.showThinkingSelector=${true}
|
||||||
.showThemeToggle=${false}
|
.showThemeToggle=${false}
|
||||||
.showDebugToggle=${false}
|
.showDebugToggle=${false}
|
||||||
.onApiKeyRequired=${this.onApiKeyRequired}
|
.onApiKeyRequired=${this.onApiKeyRequired}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,8 @@ export class AgentInterface extends LitElement {
|
||||||
@property({ attribute: false }) session?: AgentSession;
|
@property({ attribute: false }) session?: AgentSession;
|
||||||
@property() enableAttachments = true;
|
@property() enableAttachments = true;
|
||||||
@property() enableModelSelector = true;
|
@property() enableModelSelector = true;
|
||||||
@property() enableThinking = true;
|
@property() enableThinkingSelector = true;
|
||||||
@property() showThemeToggle = false;
|
@property() showThemeToggle = false;
|
||||||
@property() showDebugToggle = false;
|
|
||||||
// Optional custom API key prompt handler - if not provided, uses default dialog
|
// Optional custom API key prompt handler - if not provided, uses default dialog
|
||||||
@property({ attribute: false }) onApiKeyRequired?: (provider: string) => Promise<boolean>;
|
@property({ attribute: false }) onApiKeyRequired?: (provider: string) => Promise<boolean>;
|
||||||
|
|
||||||
|
|
@ -286,7 +285,7 @@ export class AgentInterface extends LitElement {
|
||||||
.thinkingLevel=${state.thinkingLevel}
|
.thinkingLevel=${state.thinkingLevel}
|
||||||
.showAttachmentButton=${this.enableAttachments}
|
.showAttachmentButton=${this.enableAttachments}
|
||||||
.showModelSelector=${this.enableModelSelector}
|
.showModelSelector=${this.enableModelSelector}
|
||||||
.showThinking=${this.enableThinking}
|
.showThinkingSelector=${this.enableThinkingSelector}
|
||||||
.onSend=${(input: string, attachments: Attachment[]) => {
|
.onSend=${(input: string, attachments: Attachment[]) => {
|
||||||
this.sendMessage(input, attachments);
|
this.sendMessage(input, attachments);
|
||||||
}}
|
}}
|
||||||
|
|
@ -295,7 +294,7 @@ export class AgentInterface extends LitElement {
|
||||||
ModelSelector.open(state.model, (model) => session.setModel(model));
|
ModelSelector.open(state.model, (model) => session.setModel(model));
|
||||||
}}
|
}}
|
||||||
.onThinkingChange=${
|
.onThinkingChange=${
|
||||||
this.enableThinking
|
this.enableThinkingSelector
|
||||||
? (level: "off" | "minimal" | "low" | "medium" | "high") => {
|
? (level: "off" | "minimal" | "low" | "medium" | "high") => {
|
||||||
session.setThinkingLevel(level);
|
session.setThinkingLevel(level);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { Button, html, icon } from "@mariozechner/mini-lit";
|
import { Button, html, icon, Select, type SelectOption } from "@mariozechner/mini-lit";
|
||||||
import type { Model } from "@mariozechner/pi-ai";
|
import type { Model } from "@mariozechner/pi-ai";
|
||||||
import { LitElement } from "lit";
|
import { LitElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
import { createRef, ref } from "lit/directives/ref.js";
|
import { createRef, ref } from "lit/directives/ref.js";
|
||||||
import { Loader2, Paperclip, Send, Sparkles, Square } from "lucide";
|
import { Brain, Loader2, Paperclip, Send, Sparkles, Square } from "lucide";
|
||||||
import "./AttachmentTile.js";
|
import "./AttachmentTile.js";
|
||||||
import { type Attachment, loadAttachment } from "../utils/attachment-utils.js";
|
import { type Attachment, loadAttachment } from "../utils/attachment-utils.js";
|
||||||
import { i18n } from "../utils/i18n.js";
|
import { i18n } from "../utils/i18n.js";
|
||||||
|
|
@ -33,13 +33,15 @@ export class MessageEditor extends LitElement {
|
||||||
|
|
||||||
@property() isStreaming = false;
|
@property() isStreaming = false;
|
||||||
@property() currentModel?: Model<any>;
|
@property() currentModel?: Model<any>;
|
||||||
|
@property() thinkingLevel: "off" | "minimal" | "low" | "medium" | "high" = "off";
|
||||||
@property() showAttachmentButton = true;
|
@property() showAttachmentButton = true;
|
||||||
@property() showModelSelector = true;
|
@property() showModelSelector = true;
|
||||||
@property() showThinking = false; // Disabled for now
|
@property() showThinkingSelector = true;
|
||||||
@property() onInput?: (value: string) => void;
|
@property() onInput?: (value: string) => void;
|
||||||
@property() onSend?: (input: string, attachments: Attachment[]) => void;
|
@property() onSend?: (input: string, attachments: Attachment[]) => void;
|
||||||
@property() onAbort?: () => void;
|
@property() onAbort?: () => void;
|
||||||
@property() onModelSelect?: () => void;
|
@property() onModelSelect?: () => void;
|
||||||
|
@property() onThinkingChange?: (level: "off" | "minimal" | "low" | "medium" | "high") => void;
|
||||||
@property() onFilesChange?: (files: Attachment[]) => void;
|
@property() onFilesChange?: (files: Attachment[]) => void;
|
||||||
@property() attachments: Attachment[] = [];
|
@property() attachments: Attachment[] = [];
|
||||||
@property() maxFiles = 10;
|
@property() maxFiles = 10;
|
||||||
|
|
@ -150,6 +152,10 @@ export class MessageEditor extends LitElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
|
// Check if current model supports thinking/reasoning
|
||||||
|
const model = this.currentModel;
|
||||||
|
const supportsThinking = model?.reasoning === true; // Models with reasoning:true support thinking
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="bg-card rounded-xl border border-border shadow-sm">
|
<div class="bg-card rounded-xl border border-border shadow-sm">
|
||||||
<!-- Attachments -->
|
<!-- Attachments -->
|
||||||
|
|
@ -194,7 +200,7 @@ export class MessageEditor extends LitElement {
|
||||||
|
|
||||||
<!-- Button Row -->
|
<!-- Button Row -->
|
||||||
<div class="px-2 pb-2 flex items-center justify-between">
|
<div class="px-2 pb-2 flex items-center justify-between">
|
||||||
<!-- Left side - attachment and quick action buttons -->
|
<!-- Left side - attachment and thinking selector -->
|
||||||
<div class="flex gap-2 items-center">
|
<div class="flex gap-2 items-center">
|
||||||
${
|
${
|
||||||
this.showAttachmentButton
|
this.showAttachmentButton
|
||||||
|
|
@ -215,6 +221,30 @@ export class MessageEditor extends LitElement {
|
||||||
`
|
`
|
||||||
: ""
|
: ""
|
||||||
}
|
}
|
||||||
|
${
|
||||||
|
supportsThinking && this.showThinkingSelector
|
||||||
|
? html`
|
||||||
|
${Select({
|
||||||
|
value: this.thinkingLevel,
|
||||||
|
placeholder: i18n("Off"),
|
||||||
|
options: [
|
||||||
|
{ value: "off", label: i18n("Off"), icon: icon(Brain, "sm") },
|
||||||
|
{ value: "minimal", label: i18n("Minimal"), icon: icon(Brain, "sm") },
|
||||||
|
{ value: "low", label: i18n("Low"), icon: icon(Brain, "sm") },
|
||||||
|
{ value: "medium", label: i18n("Medium"), icon: icon(Brain, "sm") },
|
||||||
|
{ value: "high", label: i18n("High"), icon: icon(Brain, "sm") },
|
||||||
|
] as SelectOption[],
|
||||||
|
onChange: (value: string) => {
|
||||||
|
this.onThinkingChange?.(value as "off" | "minimal" | "low" | "medium" | "high");
|
||||||
|
},
|
||||||
|
width: "80px",
|
||||||
|
size: "sm",
|
||||||
|
variant: "ghost",
|
||||||
|
fitContent: true,
|
||||||
|
})}
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Model selector and send on the right -->
|
<!-- Model selector and send on the right -->
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,11 @@ declare module "@mariozechner/mini-lit" {
|
||||||
"API Key Required": string;
|
"API Key Required": string;
|
||||||
"Enter your API key for {provider}": string;
|
"Enter your API key for {provider}": string;
|
||||||
"The CORS proxy strips CORS headers from API responses, allowing browser-based apps to make direct calls to LLM providers without CORS restrictions. It forwards requests to providers while removing headers that would otherwise block cross-origin requests.": string;
|
"The CORS proxy strips CORS headers from API responses, allowing browser-based apps to make direct calls to LLM providers without CORS restrictions. It forwards requests to providers while removing headers that would otherwise block cross-origin requests.": string;
|
||||||
|
Off: string;
|
||||||
|
Minimal: string;
|
||||||
|
Low: string;
|
||||||
|
Medium: string;
|
||||||
|
High: string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,6 +228,11 @@ const translations = {
|
||||||
"Enter your API key for {provider}": "Enter your API key for {provider}",
|
"Enter your API key for {provider}": "Enter your API key for {provider}",
|
||||||
"The CORS proxy strips CORS headers from API responses, allowing browser-based apps to make direct calls to LLM providers without CORS restrictions. It forwards requests to providers while removing headers that would otherwise block cross-origin requests.":
|
"The CORS proxy strips CORS headers from API responses, allowing browser-based apps to make direct calls to LLM providers without CORS restrictions. It forwards requests to providers while removing headers that would otherwise block cross-origin requests.":
|
||||||
"The CORS proxy strips CORS headers from API responses, allowing browser-based apps to make direct calls to LLM providers without CORS restrictions. It forwards requests to providers while removing headers that would otherwise block cross-origin requests.",
|
"The CORS proxy strips CORS headers from API responses, allowing browser-based apps to make direct calls to LLM providers without CORS restrictions. It forwards requests to providers while removing headers that would otherwise block cross-origin requests.",
|
||||||
|
Off: "Off",
|
||||||
|
Minimal: "Minimal",
|
||||||
|
Low: "Low",
|
||||||
|
Medium: "Medium",
|
||||||
|
High: "High",
|
||||||
},
|
},
|
||||||
de: {
|
de: {
|
||||||
...defaultGerman,
|
...defaultGerman,
|
||||||
|
|
@ -335,6 +345,11 @@ const translations = {
|
||||||
"Enter your API key for {provider}": "Geben Sie Ihren API-Schlüssel für {provider} ein",
|
"Enter your API key for {provider}": "Geben Sie Ihren API-Schlüssel für {provider} ein",
|
||||||
"The CORS proxy strips CORS headers from API responses, allowing browser-based apps to make direct calls to LLM providers without CORS restrictions. It forwards requests to providers while removing headers that would otherwise block cross-origin requests.":
|
"The CORS proxy strips CORS headers from API responses, allowing browser-based apps to make direct calls to LLM providers without CORS restrictions. It forwards requests to providers while removing headers that would otherwise block cross-origin requests.":
|
||||||
"Der CORS-Proxy entfernt CORS-Header aus API-Antworten und ermöglicht browserbasierte Anwendungen, direkte Aufrufe an LLM-Anbieter ohne CORS-Einschränkungen durchzuführen. Er leitet Anfragen an Anbieter weiter und entfernt Header, die sonst Cross-Origin-Anfragen blockieren würden.",
|
"Der CORS-Proxy entfernt CORS-Header aus API-Antworten und ermöglicht browserbasierte Anwendungen, direkte Aufrufe an LLM-Anbieter ohne CORS-Einschränkungen durchzuführen. Er leitet Anfragen an Anbieter weiter und entfernt Header, die sonst Cross-Origin-Anfragen blockieren würden.",
|
||||||
|
Off: "Aus",
|
||||||
|
Minimal: "Minimal",
|
||||||
|
Low: "Niedrig",
|
||||||
|
Medium: "Mittel",
|
||||||
|
High: "Hoch",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue