forked from Shinonome/dots-hyprland
Merge branch 'main' into ii-qs
This commit is contained in:
@@ -90,27 +90,44 @@ class BrightnessDdcService extends BrightnessServiceBase {
|
||||
async function listDdcMonitorsSnBus() {
|
||||
let ddcSnBus = {};
|
||||
try {
|
||||
const out = await Utils.execAsync('ddcutil detect --brief');
|
||||
// Its' better not to use --brief. This way if a serial number is not
|
||||
// found we can still use the binary serial number as an alternative
|
||||
const out = await Utils.execAsync('ddcutil detect');
|
||||
const displays = out.split('\n\n');
|
||||
displays.forEach(display => {
|
||||
const reg = /^Display \d+/;
|
||||
if (!reg.test(display))
|
||||
const reg = /[Dd]isplay/;
|
||||
if (!reg.test(display)) {
|
||||
return;
|
||||
}
|
||||
const lines = display.split('\n');
|
||||
let sn, busNum;
|
||||
let unresponsive = false;
|
||||
for (let line of lines) {
|
||||
line = line.trim()
|
||||
if (line.startsWith('Monitor:')) {
|
||||
sn = line.split(':')[3];
|
||||
|
||||
// Sometimes ddcutils will report a DP monitor twice, one of the
|
||||
// two copies of the monitor will "not support DDC/CI". Just ignore it
|
||||
// See https://www.ddcutil.com/faq/#duplicate_displayport
|
||||
if (line.includes('unresponsive')) {
|
||||
unresponsive = true;
|
||||
}
|
||||
if (line.startsWith('Serial')) {
|
||||
sn = line.split(':')[1].trim();
|
||||
// Sometimes sn can be empty. In this cases let's relay on binary sn
|
||||
} else if (line.startsWith('Binary') && !sn) {
|
||||
// Make the serial number upper case except for the leading '0x' since Hyprland
|
||||
// seems to use upper case for the rest of the string and ddcutil uses
|
||||
// lower case for all the binary sn
|
||||
sn = '0x'+line.split('(')[1].slice(2,-1).toUpperCase();
|
||||
} else if (line.startsWith('I2C bus:')) {
|
||||
busNum = line.split('/dev/i2c-')[1];
|
||||
}
|
||||
}
|
||||
if (sn && busNum)
|
||||
if (sn && busNum && !unresponsive){
|
||||
ddcSnBus[sn] = busNum;
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
print(err);
|
||||
}
|
||||
return ddcSnBus;
|
||||
}
|
||||
@@ -133,10 +150,12 @@ for (let i = 0; i < service.length; i++) {
|
||||
service[i] = new BrightnessDdcService(ddcSnBus[monitorSn]);
|
||||
break;
|
||||
case "auto":
|
||||
if (monitorSn in ddcSnBus && !!exec(`bash -c 'command -v ddcutil'`))
|
||||
if (monitorSn in ddcSnBus && !!exec(`bash -c 'command -v ddcutil'`)){
|
||||
service[i] = new BrightnessDdcService(ddcSnBus[monitorSn]);
|
||||
else
|
||||
}
|
||||
else {
|
||||
service[i] = new BrightnessCtlService();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown brightness controller ${preferredController}`);
|
||||
|
||||
+48
-27
@@ -44,16 +44,6 @@ const PROVIDERS = Object.assign({
|
||||
"key_file": "openrouter_key.txt",
|
||||
"model": "meta-llama/llama-3-70b-instruct",
|
||||
},
|
||||
"openai": {
|
||||
"name": "OpenAI - GPT-3.5",
|
||||
"logo_name": "openai-symbolic",
|
||||
"description": getString('Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.'),
|
||||
"base_url": "https://api.openai.com/v1/chat/completions",
|
||||
"key_get_url": "https://platform.openai.com/api-keys",
|
||||
"requires_key": true,
|
||||
"key_file": "openai_key.txt",
|
||||
"model": "gpt-3.5-turbo",
|
||||
},
|
||||
}, userOptions.ai.extraGptModels)
|
||||
|
||||
const installedOllamaModels = JSON.parse(
|
||||
@@ -76,7 +66,7 @@ installedOllamaModels.forEach(model => {
|
||||
// Custom prompt
|
||||
const initMessages =
|
||||
[
|
||||
{ role: "user", content: getString("You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!"), },
|
||||
{ role: "user", content: getString("You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don't have enough information to provide a confident answer, simply say \"I don't know\" or \"I'm not sure.\". \nThanks!") },
|
||||
{ role: "assistant", content: "- Got it!", },
|
||||
{ role: "user", content: "\"He rushed to where the event was supposed to be hold, he didn't know it got canceled\"", },
|
||||
{ role: "assistant", content: "## Grammar correction\nErrors:\n\"He rushed to where the event was supposed to be __hold____,__ he didn't know it got canceled\"\nCorrection + minor improvements:\n\"He rushed to the place where the event was supposed to be __held____, but__ he didn't know that it got canceled\"", },
|
||||
@@ -105,6 +95,8 @@ class GPTMessage extends Service {
|
||||
|
||||
_role = '';
|
||||
_content = '';
|
||||
_hasReasoningContent = false;
|
||||
_parsedReasoningContent = false;
|
||||
_lastContentLength = 0;
|
||||
_thinking;
|
||||
_done = false;
|
||||
@@ -112,6 +104,8 @@ class GPTMessage extends Service {
|
||||
constructor(role, content, thinking = true, done = false) {
|
||||
super();
|
||||
this._role = role;
|
||||
this._hasReasoningContent = false;
|
||||
this._parsedReasoningContent = false;
|
||||
this._content = content;
|
||||
this._thinking = thinking;
|
||||
this._done = done;
|
||||
@@ -123,6 +117,18 @@ class GPTMessage extends Service {
|
||||
get role() { return this._role }
|
||||
set role(role) { this._role = role; this.emit('changed') }
|
||||
|
||||
get hasReasoningContent() { return this._hasReasoningContent }
|
||||
set hasReasoningContent(value) {
|
||||
this._hasReasoningContent = value;
|
||||
this.emit('changed')
|
||||
}
|
||||
|
||||
get parsedReasoningContent() { return this._parsedReasoningContent }
|
||||
set parsedReasoningContent(value) {
|
||||
this._parsedReasoningContent = value;
|
||||
this.emit('changed')
|
||||
}
|
||||
|
||||
get content() { return this._content }
|
||||
set content(content) {
|
||||
this._content = content;
|
||||
@@ -143,6 +149,7 @@ class GPTMessage extends Service {
|
||||
}
|
||||
|
||||
addDelta(delta) {
|
||||
if (delta == null) return;
|
||||
if (this.thinking) {
|
||||
this.thinking = false;
|
||||
this.content = delta;
|
||||
@@ -242,16 +249,43 @@ class GPTService extends Service {
|
||||
const [bytes] = stream.read_line_finish(res);
|
||||
const line = this._decoder.decode(bytes);
|
||||
if (line && line != '') {
|
||||
|
||||
// Ignore SSE comments (lines starting with ":")
|
||||
if (line.startsWith(':')) {
|
||||
this.readResponse(stream, aiResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = line.substr(6);
|
||||
if (data == '[DONE]') return;
|
||||
try {
|
||||
const result = JSON.parse(data);
|
||||
if (result.choices[0].finish_reason === 'stop') {
|
||||
// If the stop payload has content, add it to the response
|
||||
if (result.choices[0].delta.content) {
|
||||
aiResponse.addDelta(result.choices[0].delta.content);
|
||||
}
|
||||
aiResponse.done = true;
|
||||
return;
|
||||
}
|
||||
aiResponse.addDelta(result.choices[0].delta.content);
|
||||
// print(result.choices[0])
|
||||
|
||||
// aiResponse.addDelta(result.choices[0].delta.content);
|
||||
if (!result.choices[0].delta.content && result.choices[0].delta.reasoning_content) {
|
||||
if (!aiResponse.hasReasoningContent) {
|
||||
aiResponse.hasReasoningContent = true;
|
||||
aiResponse.addDelta(`<think>\n${result.choices[0].delta.reasoning_content}`);
|
||||
}
|
||||
else {
|
||||
aiResponse.addDelta(`${result.choices[0].delta.reasoning_content}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (aiResponse.hasReasoningContent) {
|
||||
aiResponse.parsedReasoningContent = true;
|
||||
aiResponse.addDelta(`\n</think>\n`);
|
||||
}
|
||||
aiResponse.addDelta(result.choices[0].delta.content);
|
||||
}
|
||||
}
|
||||
catch {
|
||||
aiResponse.addDelta(line + '\n');
|
||||
@@ -300,17 +334,4 @@ class GPTService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
export default new GPTService();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default new GPTService();
|
||||
Reference in New Issue
Block a user