sonex-agent 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +15 -0
- package/bin/sonex.js +235 -0
- package/dist/App.js +1360 -0
- package/dist/activity.js +18 -0
- package/dist/chat-document.js +40 -0
- package/dist/chat-message.js +93 -0
- package/dist/chat-theme.js +18 -0
- package/dist/chat-window.js +104 -0
- package/dist/command-panel.js +45 -0
- package/dist/commands.js +70 -0
- package/dist/components.js +662 -0
- package/dist/confirm-choice.js +65 -0
- package/dist/constants.js +109 -0
- package/dist/conversation-flow.js +21 -0
- package/dist/cover-pattern.js +58 -0
- package/dist/cover-visual.js +158 -0
- package/dist/extension-panel.js +136 -0
- package/dist/format.js +99 -0
- package/dist/hooks.js +216 -0
- package/dist/i18n.js +291 -0
- package/dist/index.js +46 -0
- package/dist/info-banner.js +37 -0
- package/dist/input-cursor.js +6 -0
- package/dist/input-routing.js +41 -0
- package/dist/launch-preparing.js +30 -0
- package/dist/layout.js +134 -0
- package/dist/list.js +3 -0
- package/dist/login-navigation.js +7 -0
- package/dist/mini-progress-writer.js +122 -0
- package/dist/mini-progress.js +77 -0
- package/dist/model-selection.js +20 -0
- package/dist/model-status.js +34 -0
- package/dist/mouse-input.js +173 -0
- package/dist/panel-frame.js +86 -0
- package/dist/panel-lifecycle.js +17 -0
- package/dist/playback-keymap.js +59 -0
- package/dist/provider-state.js +67 -0
- package/dist/runtime-state.js +91 -0
- package/dist/shell-state.js +37 -0
- package/dist/sonex-logo.js +9 -0
- package/dist/terminal-clear.js +10 -0
- package/dist/terminal-frame-writer.js +133 -0
- package/dist/terminal-surface.js +80 -0
- package/dist/text-stream.js +17 -0
- package/dist/track-panel.js +95 -0
- package/dist/transcript.js +92 -0
- package/dist/types.js +1 -0
- package/dist/ui-settings.js +30 -0
- package/dist/usage-animation.js +14 -0
- package/package.json +57 -0
- package/vendor/requirements-linux-py312.txt +2659 -0
- package/vendor/sonex-0.1.0a1-py3-none-any.whl +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export const createTranscriptState = () => ({
|
|
2
|
+
records: [],
|
|
3
|
+
deferredRecords: [],
|
|
4
|
+
nextSequence: 0,
|
|
5
|
+
pendingUserEchoes: {},
|
|
6
|
+
surface: "main",
|
|
7
|
+
});
|
|
8
|
+
const echoKey = (content) => content.trim();
|
|
9
|
+
const appendItems = (state, items, presentation) => {
|
|
10
|
+
if (items.length === 0)
|
|
11
|
+
return state;
|
|
12
|
+
const appended = items.map((item, index) => ({
|
|
13
|
+
sequence: state.nextSequence + index,
|
|
14
|
+
item,
|
|
15
|
+
presentation,
|
|
16
|
+
}));
|
|
17
|
+
const nextSequence = state.nextSequence + appended.length;
|
|
18
|
+
if (state.surface === "alternate") {
|
|
19
|
+
return {
|
|
20
|
+
...state,
|
|
21
|
+
deferredRecords: [...state.deferredRecords, ...appended],
|
|
22
|
+
nextSequence,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
...state,
|
|
27
|
+
records: [...state.records, ...appended],
|
|
28
|
+
nextSequence,
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const consumePendingEcho = (pendingUserEchoes, key) => {
|
|
32
|
+
const count = Object.hasOwn(pendingUserEchoes, key) ? pendingUserEchoes[key] ?? 0 : 0;
|
|
33
|
+
if (count === 0)
|
|
34
|
+
return null;
|
|
35
|
+
const next = { ...pendingUserEchoes };
|
|
36
|
+
if (count === 1) {
|
|
37
|
+
delete next[key];
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
next[key] = count - 1;
|
|
41
|
+
}
|
|
42
|
+
return next;
|
|
43
|
+
};
|
|
44
|
+
export function transcriptReducer(state, action) {
|
|
45
|
+
switch (action.type) {
|
|
46
|
+
case "commit":
|
|
47
|
+
return appendItems(state, action.items, action.presentation);
|
|
48
|
+
case "submitUser": {
|
|
49
|
+
const key = echoKey(action.item.content);
|
|
50
|
+
const count = Object.hasOwn(state.pendingUserEchoes, key)
|
|
51
|
+
? state.pendingUserEchoes[key] ?? 0
|
|
52
|
+
: 0;
|
|
53
|
+
const pendingUserEchoes = {
|
|
54
|
+
...state.pendingUserEchoes,
|
|
55
|
+
[key]: count + 1,
|
|
56
|
+
};
|
|
57
|
+
return appendItems({ ...state, pendingUserEchoes }, [action.item], action.presentation);
|
|
58
|
+
}
|
|
59
|
+
case "receiveUser": {
|
|
60
|
+
const pendingUserEchoes = consumePendingEcho(state.pendingUserEchoes, echoKey(action.item.content));
|
|
61
|
+
return pendingUserEchoes === null
|
|
62
|
+
? appendItems(state, [action.item], action.presentation)
|
|
63
|
+
: { ...state, pendingUserEchoes };
|
|
64
|
+
}
|
|
65
|
+
case "rejectUserSend": {
|
|
66
|
+
const pendingUserEchoes = consumePendingEcho(state.pendingUserEchoes, echoKey(action.content));
|
|
67
|
+
return pendingUserEchoes === null ? state : { ...state, pendingUserEchoes };
|
|
68
|
+
}
|
|
69
|
+
case "setSurface":
|
|
70
|
+
if (action.surface === state.surface)
|
|
71
|
+
return state;
|
|
72
|
+
if (action.surface === "main") {
|
|
73
|
+
return {
|
|
74
|
+
...state,
|
|
75
|
+
records: [...state.records, ...state.deferredRecords],
|
|
76
|
+
deferredRecords: [],
|
|
77
|
+
surface: "main",
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return { ...state, surface: "alternate" };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export const classifyServerEventForTranscript = (event) => {
|
|
84
|
+
if (event.type === "chat")
|
|
85
|
+
return "chat";
|
|
86
|
+
if (event.type === "error")
|
|
87
|
+
return "error";
|
|
88
|
+
return "transient";
|
|
89
|
+
};
|
|
90
|
+
export const allTranscriptItems = (state) => ([...state.records, ...state.deferredRecords]
|
|
91
|
+
.sort((left, right) => left.sequence - right.sequence)
|
|
92
|
+
.map((record) => record.item));
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
const SETTINGS_FILE = "ui-settings.json";
|
|
5
|
+
export function isUiLanguage(value) {
|
|
6
|
+
return value === "en" || value === "zh-CN";
|
|
7
|
+
}
|
|
8
|
+
export function sonexHome() {
|
|
9
|
+
return process.env.SONEX_HOME || join(homedir(), ".sonex");
|
|
10
|
+
}
|
|
11
|
+
function settingsPath() {
|
|
12
|
+
return join(sonexHome(), SETTINGS_FILE);
|
|
13
|
+
}
|
|
14
|
+
export function loadUiLanguage() {
|
|
15
|
+
try {
|
|
16
|
+
const path = settingsPath();
|
|
17
|
+
if (!existsSync(path))
|
|
18
|
+
return "en";
|
|
19
|
+
const settings = JSON.parse(readFileSync(path, "utf8"));
|
|
20
|
+
return isUiLanguage(settings.language) ? settings.language : "en";
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return "en";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function saveUiLanguage(language) {
|
|
27
|
+
const home = sonexHome();
|
|
28
|
+
mkdirSync(home, { recursive: true });
|
|
29
|
+
writeFileSync(settingsPath(), `${JSON.stringify({ language }, null, 2)}\n`);
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const TOKEN_USAGE_ANIMATION_INTERVAL_MS = 16;
|
|
2
|
+
const normalizeTokenCount = (value) => Math.max(0, Math.floor(value));
|
|
3
|
+
export const nextAnimatedTokenCount = (current, target) => {
|
|
4
|
+
const normalizedCurrent = normalizeTokenCount(current);
|
|
5
|
+
const normalizedTarget = normalizeTokenCount(target);
|
|
6
|
+
if (normalizedCurrent >= normalizedTarget)
|
|
7
|
+
return normalizedTarget;
|
|
8
|
+
const remaining = normalizedTarget - normalizedCurrent;
|
|
9
|
+
return Math.min(normalizedTarget, normalizedCurrent + Math.max(1, Math.ceil(remaining / 4)));
|
|
10
|
+
};
|
|
11
|
+
export const nextAnimatedTokenUsage = (current, target) => ({
|
|
12
|
+
inputTokens: nextAnimatedTokenCount(current.inputTokens, target.inputTokens),
|
|
13
|
+
outputTokens: nextAnimatedTokenCount(current.outputTokens, target.outputTokens),
|
|
14
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sonex-agent",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "An AI-powered music agent for the terminal.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/S1LentH3arT/Sonex.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/S1LentH3arT/Sonex/issues"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/S1LentH3arT/Sonex#readme",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"bin": {
|
|
16
|
+
"sonex": "bin/sonex.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"bin/",
|
|
20
|
+
"dist/",
|
|
21
|
+
"vendor/",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"os": ["linux"],
|
|
29
|
+
"cpu": ["x64", "arm64"],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public",
|
|
32
|
+
"tag": "alpha"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "tsc --outDir dist",
|
|
36
|
+
"start": "node dist/index.js",
|
|
37
|
+
"test": "tsx --test test/*.test.ts",
|
|
38
|
+
"verify:pty": "python3 ../../scripts/verify_cli_tui_append.py",
|
|
39
|
+
"pack:release": "bash ../../scripts/build_npm_package.sh"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@openai/codex": "0.146.0",
|
|
43
|
+
"ink": "^5.0.0",
|
|
44
|
+
"ink-text-input": "^6.0.0",
|
|
45
|
+
"react": "^18.3.1",
|
|
46
|
+
"string-width": "^7.2.0",
|
|
47
|
+
"terminal-image": "^5.0.1",
|
|
48
|
+
"ws": "^8.21.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^20.17.10",
|
|
52
|
+
"@types/react": "^18.3.12",
|
|
53
|
+
"@types/ws": "^8.18.1",
|
|
54
|
+
"tsx": "^4.19.2",
|
|
55
|
+
"typescript": "^5.7.3"
|
|
56
|
+
}
|
|
57
|
+
}
|