mirror of
https://github.com/mudler/LocalAI.git
synced 2026-11-07 21:13:27 -05:00
Chats and agents can check a PiKVM (kvmd) device and, when a person confirms each call, press the power buttons of the machine it controls and use its keyboard. Read tools: get-info (model, versions, no serial or host name), get-power-state (ATX LEDs) and get-keyboard-state. Write tools: power-action (on, off, reset; off_hard, reset_hard and long_press only with a per-device switch), type-text (bounded, no control characters, refuses key, token and password-list shapes) and send-key (a short allowlist, no Windows or Meta chords). All three declare approval always. The preview reads the power state; apply reads it again and rejects a stale operation. The add-on journals before it sends, never retries and reports unknown when the connection drops. One connection is one device: the address is the single resource of the connection and the one sealed credential holds user:password, split at the first colon. A one-time code is not supported. The add-on speaks only to that address, refuses redirects, uses no proxy and accepts a self-signed certificate only through a #sha256= pin in the address. Typing, the text length and hard power actions are per-device switches that an administrator sets on the add-on page; all start off. Snapshots, mass storage, GPIO and the mouse are left out. The add-on ships a skill, a connection page with a Test button and approval cards, the package files, the library entry and the docs, and joins the package workflow and the case inventory. PiKVM API reference: https://docs.pikvm.org/api/ Assisted-by: Claude:claude-sonnet-5-5 go node
21 lines
1.2 KiB
JavaScript
21 lines
1.2 KiB
JavaScript
import test from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { draftOf, draftProblem, same, valuesOf, DEFAULT_CHARS } from '../src/settings.js'
|
|
|
|
test('pikvm settings: a device with no saved switches is off and short', () => {
|
|
assert.deepEqual(draftOf(undefined), { allowTyping: false, allowHardPower: false, maxTypeChars: String(DEFAULT_CHARS) })
|
|
assert.deepEqual(draftOf({ allowTyping: true, allowHardPower: 'yes', maxTypeChars: 300 }), { allowTyping: true, allowHardPower: false, maxTypeChars: '300' })
|
|
})
|
|
|
|
test('pikvm settings: the length is a whole number from 1 to 1000', () => {
|
|
for (const ok of ['1', '200', '1000']) assert.equal(draftProblem({ maxTypeChars: ok }), '')
|
|
for (const bad of ['0', '1001', '-3', '1.5', '', 'abc']) assert.equal(draftProblem({ maxTypeChars: bad }), 'settings.maxCharsShape', bad)
|
|
})
|
|
|
|
test('pikvm settings: a draft is dirty only when something differs, and sends numbers', () => {
|
|
const a = draftOf({ allowTyping: true, maxTypeChars: 200 })
|
|
assert.equal(same(a, draftOf({ allowTyping: true, maxTypeChars: 200 })), true)
|
|
assert.equal(same(a, { ...a, allowHardPower: true }), false)
|
|
assert.deepEqual(valuesOf({ ...a, maxTypeChars: '350' }), { allowTyping: true, allowHardPower: false, maxTypeChars: 350 })
|
|
})
|