@zds-ai/cli 0.1.7 → 0.1.10
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/README.md +387 -34
- package/dist/agent/context-manager.d.ts +70 -0
- package/dist/agent/context-manager.js +138 -0
- package/dist/agent/context-manager.js.map +1 -0
- package/dist/agent/hook-manager.d.ts +194 -0
- package/dist/agent/hook-manager.js +676 -0
- package/dist/agent/hook-manager.js.map +1 -0
- package/dist/agent/llm-agent.d.ts +470 -100
- package/dist/agent/llm-agent.js +788 -1576
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/agent/message-processor.d.ts +103 -0
- package/dist/agent/message-processor.js +225 -0
- package/dist/agent/message-processor.js.map +1 -0
- package/dist/agent/prompt-variables.d.ts +113 -40
- package/dist/agent/prompt-variables.js +272 -81
- package/dist/agent/prompt-variables.js.map +1 -1
- package/dist/agent/session-manager.d.ts +75 -0
- package/dist/agent/session-manager.js +194 -0
- package/dist/agent/session-manager.js.map +1 -0
- package/dist/agent/streaming-agent.d.ts +33 -0
- package/dist/agent/streaming-agent.js +629 -0
- package/dist/agent/streaming-agent.js.map +1 -0
- package/dist/agent/tool-executor.d.ts +111 -0
- package/dist/agent/tool-executor.js +397 -0
- package/dist/agent/tool-executor.js.map +1 -0
- package/dist/bin/encode-speech.sh +64 -0
- package/dist/bin/extract-text.sh +66 -0
- package/dist/bin/generate_image_sd.sh +23 -12
- package/dist/bin/joycaption.sh +37 -0
- package/dist/bin/talking-agents.sh +291 -0
- package/dist/grok/client.d.ts +54 -0
- package/dist/grok/client.js +173 -20
- package/dist/grok/client.js.map +1 -1
- package/dist/grok/tools.js +98 -11
- package/dist/grok/tools.js.map +1 -1
- package/dist/hooks/use-enhanced-input.js +3 -1
- package/dist/hooks/use-enhanced-input.js.map +1 -1
- package/dist/hooks/use-input-handler.d.ts +1 -1
- package/dist/hooks/use-input-handler.js +101 -8
- package/dist/hooks/use-input-handler.js.map +1 -1
- package/dist/index.js +25 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp/config.d.ts +1 -0
- package/dist/mcp/config.js +45 -7
- package/dist/mcp/config.js.map +1 -1
- package/dist/tools/audio-tool.d.ts +13 -0
- package/dist/tools/audio-tool.js +55 -0
- package/dist/tools/audio-tool.js.map +1 -0
- package/dist/tools/character-tool.js +13 -1
- package/dist/tools/character-tool.js.map +1 -1
- package/dist/tools/image-tool.d.ts +21 -1
- package/dist/tools/image-tool.js +201 -14
- package/dist/tools/image-tool.js.map +1 -1
- package/dist/tools/index.d.ts +11 -10
- package/dist/tools/index.js +11 -10
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/introspect-tool.js +325 -2
- package/dist/tools/introspect-tool.js.map +1 -1
- package/dist/tools/morph-editor.d.ts +21 -9
- package/dist/tools/morph-editor.js +21 -9
- package/dist/tools/morph-editor.js.map +1 -1
- package/dist/ui/components/active-task-status.d.ts +1 -1
- package/dist/ui/components/api-key-input.d.ts +1 -1
- package/dist/ui/components/backend-status.d.ts +1 -1
- package/dist/ui/components/chat-history.d.ts +1 -1
- package/dist/ui/components/chat-input.js +1 -1
- package/dist/ui/components/chat-input.js.map +1 -1
- package/dist/ui/components/chat-interface.d.ts +1 -1
- package/dist/ui/components/chat-interface.js +2 -2
- package/dist/ui/components/chat-interface.js.map +1 -1
- package/dist/ui/components/context-status.d.ts +1 -1
- package/dist/ui/components/mood-status.d.ts +1 -1
- package/dist/ui/components/persona-status.d.ts +1 -1
- package/dist/ui/utils/markdown-renderer.js +2 -2
- package/dist/utils/chat-history-manager.d.ts +12 -4
- package/dist/utils/chat-history-manager.js +26 -11
- package/dist/utils/chat-history-manager.js.map +1 -1
- package/dist/utils/hook-executor.d.ts +53 -2
- package/dist/utils/hook-executor.js +261 -39
- package/dist/utils/hook-executor.js.map +1 -1
- package/dist/utils/path-utils.d.ts +2 -1
- package/dist/utils/path-utils.js +25 -4
- package/dist/utils/path-utils.js.map +1 -1
- package/dist/utils/rephrase-handler.d.ts +1 -1
- package/dist/utils/settings-manager.d.ts +41 -11
- package/dist/utils/settings-manager.js +172 -40
- package/dist/utils/settings-manager.js.map +1 -1
- package/dist/utils/slash-commands.d.ts +3 -3
- package/dist/utils/slash-commands.js +11 -5
- package/dist/utils/slash-commands.js.map +1 -1
- package/dist/utils/startup-hook.js +9 -2
- package/dist/utils/startup-hook.js.map +1 -1
- package/package.json +29 -24
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
# generate_image_sd.sh - Generate image via SD API, save base64/JSON/PNG
|
|
3
3
|
|
|
4
4
|
# Find config from ZDS_AI_AGENT_CONFIG_FILE
|
|
5
|
-
[[ ! -s "$ZDS_AI_AGENT_CONFIG_FILE" ]] && echo Failed to find config file >&2
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
[[ ! -s "$ZDS_AI_AGENT_CONFIG_FILE" ]] && echo Failed to find config file $ZDS_AI_AGENT_CONFIG_FILE >&2 && exit 1
|
|
6
|
+
[[ ! -s "$ZDS_AI_AGENT_LOG_FILE" ]] && echo Failed to find log file $ZDS_AI_AGENT_LOG_FILE >&2 && exit 1
|
|
7
|
+
[[ -z "$ZDS_AI_AGENT_SESSION" ]] && echo Failed to validate agent session >&2 && exit 1
|
|
8
|
+
[[ -z "$ZDS_AI_AGENT_HOME_DIR" ]] && echo Failed to validate agent home dir >&2 && exit 1
|
|
9
|
+
LOGFILE=${ZDS_AI_AGENT_LOG_FILE}
|
|
9
10
|
|
|
10
11
|
# Load environment variables
|
|
11
12
|
[[ -f ~/.env ]] && source ~/.env
|
|
@@ -45,6 +46,7 @@ if [[ "$1" == --help || "$1" == -h || $# -eq 0 ]]; then
|
|
|
45
46
|
echo " --seed <num> Seed for reproducible generation (default: random)"
|
|
46
47
|
echo " --name <name> Name to call the file (default: based on prompt)"
|
|
47
48
|
echo " --list-models Show checkpoint models installed"
|
|
49
|
+
echo " --get-lora-details <name> Show complete JSON details for specified LoRA"
|
|
48
50
|
echo " --help Show this help message"
|
|
49
51
|
echo
|
|
50
52
|
echo Environment Variables:
|
|
@@ -57,6 +59,7 @@ if [[ "$1" == --help || "$1" == -h || $# -eq 0 ]]; then
|
|
|
57
59
|
echo " ${PROG_NAME} 'sunset' --move --cfg-scale 7.5"
|
|
58
60
|
echo " ${PROG_NAME} 'whistler\'s mother' --steps 50 --cfg-scale 8.0 --name 'whistlers mom'"
|
|
59
61
|
echo " ${PROG_NAME} 'portrait' --seed 12345 --name 'reproducible-portrait'"
|
|
62
|
+
echo " ${PROG_NAME} --get-lora-details 'RealisticSkinv2_ponyv6_loraplus'"
|
|
60
63
|
exit 0
|
|
61
64
|
fi
|
|
62
65
|
|
|
@@ -126,11 +129,24 @@ while [[ $# -gt 0 ]]; do
|
|
|
126
129
|
SEED="$2"
|
|
127
130
|
shift 2 # past argument and value
|
|
128
131
|
;;
|
|
132
|
+
--list-loras)
|
|
133
|
+
curl -s "$ZDS_AI_IMAGE_ENDPOINT"/loras | jq -r '.[].name'
|
|
134
|
+
exit 0
|
|
135
|
+
;;
|
|
129
136
|
--list-models)
|
|
130
137
|
curl -s "$ZDS_AI_IMAGE_ENDPOINT"/sd-models | jq -r '.[].title' | \
|
|
131
138
|
sed -e 's,\.safetensors.*,,gi'
|
|
132
139
|
exit 0
|
|
133
140
|
;;
|
|
141
|
+
--get-lora-details)
|
|
142
|
+
LORA_NAME="$2"
|
|
143
|
+
if [[ -z "$LORA_NAME" ]]; then
|
|
144
|
+
echo "Error: Lora name is required for --get-lora-details" >&2
|
|
145
|
+
exit 1
|
|
146
|
+
fi
|
|
147
|
+
curl -s "$ZDS_AI_IMAGE_ENDPOINT"/loras | jq --arg name "$LORA_NAME" '.[] | select(.name == $name)'
|
|
148
|
+
exit 0
|
|
149
|
+
;;
|
|
134
150
|
-*|--*)
|
|
135
151
|
echo "Unknown option $1"
|
|
136
152
|
exit 1
|
|
@@ -150,13 +166,8 @@ PROMPT="$1"
|
|
|
150
166
|
NEGATIVE_PROMPT="${2:-score_6, score_5, score_4, (worst quality:1.2), (low quality:1.2), (normal quality:1.2), lowres, bad anatomy, bad hands, signature, watermarks, ugly, imperfect eyes, skewed eyes, unnatural face, unnatural body, error, extra limb, missing limbs}"
|
|
151
167
|
|
|
152
168
|
# Override with command line flags if specified
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
fi
|
|
156
|
-
|
|
157
|
-
if [[ -n "$STEPS_OVERRIDE" ]]; then
|
|
158
|
-
STEPS="$STEPS_OVERRIDE"
|
|
159
|
-
fi
|
|
169
|
+
[[ -n "$CFG_SCALE_OVERRIDE" ]] && CFG_SCALE="$CFG_SCALE_OVERRIDE"
|
|
170
|
+
[[ -n "$STEPS_OVERRIDE" ]] && STEPS="$STEPS_OVERRIDE"
|
|
160
171
|
|
|
161
172
|
# Validate that we have at least a prompt
|
|
162
173
|
if [[ -z "$PROMPT" ]]; then
|
|
@@ -185,7 +196,7 @@ NAME=${NAME:-${PROMPT}}
|
|
|
185
196
|
SLUG=$(echo -n $NAME | tr '[:space:]' '_' | sed -e 's/[^a-zA-Z0-9_]/_/g' | cut -c 1-32)
|
|
186
197
|
|
|
187
198
|
# Dirs
|
|
188
|
-
OUTDIR=${ZDS_AI_AGENT_HOME_DIR
|
|
199
|
+
OUTDIR=${ZDS_AI_AGENT_HOME_DIR}/out
|
|
189
200
|
mkdir -p $OUTDIR/photos/tmp
|
|
190
201
|
OUTPUT_B64=$OUTDIR/photos/tmp/${SLUG}.b64
|
|
191
202
|
OUTPUT_PNG=$OUTDIR/photos/${SLUG}.png
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env zsh
|
|
2
|
+
|
|
3
|
+
set -e
|
|
4
|
+
|
|
5
|
+
# Check for help option
|
|
6
|
+
if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
|
|
7
|
+
echo "Usage: joycaption <image_file> [--prompt <prompt_text>]"
|
|
8
|
+
echo
|
|
9
|
+
echo "Generate captions for images using the JoyCaption service."
|
|
10
|
+
echo
|
|
11
|
+
echo "Arguments:"
|
|
12
|
+
echo " <image_file> Path to the image file to caption"
|
|
13
|
+
echo " --prompt Optional prompt to guide the captioning"
|
|
14
|
+
echo
|
|
15
|
+
echo "Examples:"
|
|
16
|
+
echo " joycaption image.jpg"
|
|
17
|
+
echo " joycaption image.png --prompt \"Describe this image in detail\""
|
|
18
|
+
echo
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
IMAGE="$1"
|
|
23
|
+
IMAGE_BASENAME=$(basename "$1" | tr -cs '[:alnum:].' _ | sed -e 's,_+$,,g')
|
|
24
|
+
shift
|
|
25
|
+
|
|
26
|
+
[[ "$2" == --prompt ]] && shift
|
|
27
|
+
[[ -n "$2" ]] && IMAGE_PROMPT="--prompt \"$2\""
|
|
28
|
+
|
|
29
|
+
# send the file to the server
|
|
30
|
+
scp "$IMAGE" asrock:scm/joycaption/images/$IMAGE_BASENAME
|
|
31
|
+
tmp=$(mktemp /tmp/joycaption.XXXXXX)
|
|
32
|
+
ssh asrock "bin/joycaption-receiver $IMAGE_BASENAME $IMAGE_PROMPT" > $tmp 2>/dev/null
|
|
33
|
+
grep -A99 '==========' $tmp | grep -v '==========' > ${tmp}.txt
|
|
34
|
+
[[ -s ${tmp}.txt ]] && cat ${tmp}.txt || cat ${tmp}
|
|
35
|
+
rm -f $tmp
|
|
36
|
+
|
|
37
|
+
exit 0
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#!/usr/bin/env zsh
|
|
2
|
+
|
|
3
|
+
# set -x
|
|
4
|
+
|
|
5
|
+
# Load environment variables
|
|
6
|
+
[[ -f ~/.env ]] && source ~/.env
|
|
7
|
+
|
|
8
|
+
# Find config from ZDS_AI_AGENT_CONFIG_FILE
|
|
9
|
+
[[ ! -s "$ZDS_AI_AGENT_CONFIG_FILE" ]] && echo Failed to find config file $ZDS_AI_AGENT_CONFIG_FILE >&2 && exit 1
|
|
10
|
+
[[ ! -s "$ZDS_AI_AGENT_LOG_FILE" ]] && echo Failed to find log file $ZDS_AI_AGENT_LOG_FILE >&2 && exit 1
|
|
11
|
+
[[ -z "$ZDS_AI_AGENT_SESSION" ]] && echo Failed to validate agent session >&2 && exit 1
|
|
12
|
+
LOGFILE=${ZDS_AI_AGENT_LOG_FILE}
|
|
13
|
+
|
|
14
|
+
# Log the tool invocation
|
|
15
|
+
{
|
|
16
|
+
echo "=== $(basename "$0") Tool Fired: $(date) ==="
|
|
17
|
+
echo Agent bot name: ${ZDS_AI_AGENT_BOT_NAME}
|
|
18
|
+
echo
|
|
19
|
+
set | grep ^ZDS_AI_AGENT_ | grep -vE ^ZDS_AI_AGENT_'(BOT_NAME=)'
|
|
20
|
+
echo
|
|
21
|
+
echo Params: "$@"
|
|
22
|
+
echo
|
|
23
|
+
} >> $LOGFILE
|
|
24
|
+
|
|
25
|
+
_build_voice_strings() {
|
|
26
|
+
local yq_path=$1
|
|
27
|
+
local voice_parts=()
|
|
28
|
+
local voice_remote_parts=()
|
|
29
|
+
local voice_count=$(yq "${yq_path}.kokoro.voices | length" "$ZDS_AI_AGENT_CONFIG_FILE")
|
|
30
|
+
|
|
31
|
+
for ((i=0; i<voice_count; i++)); do
|
|
32
|
+
local name=$(yq "${yq_path}.kokoro.voices[$i].name" "$ZDS_AI_AGENT_CONFIG_FILE")
|
|
33
|
+
local weight=$(yq "${yq_path}.kokoro.voices[$i].weight" "$ZDS_AI_AGENT_CONFIG_FILE")
|
|
34
|
+
voice_parts+=("${name}:${weight}")
|
|
35
|
+
voice_remote_parts+=("${name}(${weight})")
|
|
36
|
+
done
|
|
37
|
+
|
|
38
|
+
echo "$(IFS=',' ; echo "${voice_parts[*]}")|$(IFS='+' ; echo "${voice_remote_parts[*]}")"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
_load_mode_config() {
|
|
42
|
+
local mode=$1
|
|
43
|
+
|
|
44
|
+
SPEED=$(yq ".speech.$mode.kokoro.speed" "$ZDS_AI_AGENT_CONFIG_FILE")
|
|
45
|
+
NORM=$(yq ".speech.$mode.kokoro.norm" "$ZDS_AI_AGENT_CONFIG_FILE")
|
|
46
|
+
PITCH=$(yq ".speech.$mode.kokoro.pitch" "$ZDS_AI_AGENT_CONFIG_FILE")
|
|
47
|
+
|
|
48
|
+
local voices=$(_build_voice_strings ".speech.$mode")
|
|
49
|
+
VOICE="${voices%|*}"
|
|
50
|
+
VOICE_REMOTE="${voices#*|}"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Load default TTS configuration
|
|
54
|
+
_load_mode_config default
|
|
55
|
+
CURRENT_MODE=default
|
|
56
|
+
|
|
57
|
+
SUFFIX=
|
|
58
|
+
MOVE_FLAG=
|
|
59
|
+
EXT=mp3
|
|
60
|
+
|
|
61
|
+
# for var in SPEED NORM PITCH VOICE_REMOTE SUFFIX; do
|
|
62
|
+
# echo $var = ${(P)var} >> $LOGFILE
|
|
63
|
+
# done
|
|
64
|
+
|
|
65
|
+
_tts_fix_audio() {
|
|
66
|
+
ffmpeg -v error -i "$1" -af deesser,haas=side_gain=0.3,\
|
|
67
|
+
arnndn=/usr/local/share/models/cb.rnnn,\
|
|
68
|
+
afftdn=nr=10:nf=-80:tn=1,adynamicsmooth=2,anlmdn=m=99,\
|
|
69
|
+
adynamicsmooth=99:999 -y "$2" | tee -a "$LOGFILE"
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
_tts_postprocess_audio() {
|
|
73
|
+
sox "$1" "$2" pad 0 1 norm ${NORM} pitch ${PITCH} | tee -a "$LOGFILE"
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_tts_render_kokoro() {
|
|
77
|
+
# kokoro -s 0.77 -m af_bella -i "$1" -o "$2" || :
|
|
78
|
+
# cd ~/scm/kokoro-tts
|
|
79
|
+
kokoro-tts "$1" "$2" --speed $SPEED --voice ${VOICE} \
|
|
80
|
+
--model ~/.cache/kokoro-tts/kokoro-v1.0.onnx \
|
|
81
|
+
--voices ~/.cache/kokoro-tts/voices-v1.0.bin
|
|
82
|
+
# ERR=$?
|
|
83
|
+
# cd -
|
|
84
|
+
# return $ERR
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
_tts_get_language() {
|
|
88
|
+
echo $1 | lingua-cli -l en,es,pt | cut -c -2 | \
|
|
89
|
+
sed -e 's,^en$,en-us,gi' -e 's,^pt$,pt-br,gi'
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
# Get voice and speed for a specific language, trying language-specific mode variant first
|
|
93
|
+
_get_language_voice_config() {
|
|
94
|
+
local mode=$1
|
|
95
|
+
local language=$2
|
|
96
|
+
local lang_var=$(echo "$language" | sed 's/-/_/g')
|
|
97
|
+
local lang_mode="${mode}_${lang_var}"
|
|
98
|
+
|
|
99
|
+
# Try language-specific variant first (e.g., loving_es for Spanish)
|
|
100
|
+
if [[ $(yq ".speech.$lang_mode" "$ZDS_AI_AGENT_CONFIG_FILE") != null ]]; then
|
|
101
|
+
local voices=$(_build_voice_strings ".speech.$lang_mode")
|
|
102
|
+
local speed=$(yq ".speech.$lang_mode.kokoro.speed" "$ZDS_AI_AGENT_CONFIG_FILE")
|
|
103
|
+
echo "${voices%|*}|$speed"
|
|
104
|
+
else
|
|
105
|
+
# Fall back to base mode
|
|
106
|
+
echo "$VOICE_REMOTE|$SPEED"
|
|
107
|
+
fi
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# New function to accept content directly instead of reading from file
|
|
111
|
+
_tts_render_kokoro_remote_content() {
|
|
112
|
+
local content="$1"
|
|
113
|
+
local output_file="$2"
|
|
114
|
+
local language=$(_tts_get_language "$1")
|
|
115
|
+
|
|
116
|
+
# Get language-appropriate voice and speed for current mode
|
|
117
|
+
local config=$(_get_language_voice_config "$CURRENT_MODE" "$language")
|
|
118
|
+
local use_voice="${config%|*}"
|
|
119
|
+
local use_speed="${config#*|}"
|
|
120
|
+
|
|
121
|
+
curl -s -X POST "${ZDS_AI_TTS_ENDPOINT}" \
|
|
122
|
+
-u "${ZDS_AI_TTS_USER}:${ZDS_AI_TTS_PASS}" \
|
|
123
|
+
-H "Content-Type: application/json" \
|
|
124
|
+
-H "X-Raw-Response: true" \
|
|
125
|
+
-d '{
|
|
126
|
+
"input": "'"${content}"'",
|
|
127
|
+
"model": "kokoro",
|
|
128
|
+
"voice": "'${use_voice}'",
|
|
129
|
+
"response_format": "wav",
|
|
130
|
+
"speed": '${use_speed}',
|
|
131
|
+
"stream": false,
|
|
132
|
+
"lang_code": "'${language}'",
|
|
133
|
+
"return_download_link": true
|
|
134
|
+
}' > "$output_file" 2>> "$LOGFILE"
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
# en-us, es, pt-br, hi, it, fr-fr, zh
|
|
138
|
+
|
|
139
|
+
# Function to split text into sentences using awk
|
|
140
|
+
_tts_split_text_into_sentences() {
|
|
141
|
+
|
|
142
|
+
# Read file and split into sentences (basic sentence splitting)
|
|
143
|
+
# This splits on periods, exclamation marks, question marks, and ellipsis
|
|
144
|
+
awk '{
|
|
145
|
+
# Split on sentence endings while keeping the punctuation
|
|
146
|
+
gsub(/[\.!?…]/, "&\n")
|
|
147
|
+
print
|
|
148
|
+
}' | \
|
|
149
|
+
awk 'NF > 0 {
|
|
150
|
+
# Clean up whitespace
|
|
151
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, "")
|
|
152
|
+
if (length($0) > 0) {
|
|
153
|
+
print $0
|
|
154
|
+
}
|
|
155
|
+
}'
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
# New function to split text into sentences and process them individually
|
|
159
|
+
_tts_render_kokoro_remote_sentences() {
|
|
160
|
+
local input_file="$1"
|
|
161
|
+
local output_file="$2"
|
|
162
|
+
local temp_dir=$(mktemp -d "${2}.temp.XXXXXX") || return 1
|
|
163
|
+
local pad_amount=$(echo "scale=2; 0.7 / $SPEED" | bc)
|
|
164
|
+
|
|
165
|
+
# Split text into sentences first
|
|
166
|
+
_tts_split_text_into_sentences < "$input_file" > "$temp_dir/sentences.txt"
|
|
167
|
+
|
|
168
|
+
# Process each sentence
|
|
169
|
+
local sentence_num=0
|
|
170
|
+
local all_wav_files=()
|
|
171
|
+
|
|
172
|
+
while IFS= read -r sentence; do
|
|
173
|
+
if [[ -n "$sentence" ]]; then
|
|
174
|
+
sentence_num=$((sentence_num + 1))
|
|
175
|
+
wav_file="$temp_dir/sentence_${sentence_num}.wav"
|
|
176
|
+
|
|
177
|
+
# Process this sentence directly without writing to file
|
|
178
|
+
if _tts_render_kokoro_remote_content "$sentence" "$wav_file"; then
|
|
179
|
+
if [[ ${sentence_num} -eq 1 ]]; then
|
|
180
|
+
all_wav_files+=($wav_file)
|
|
181
|
+
else
|
|
182
|
+
sox $wav_file ${wav_file}.padded.wav pad ${pad_amount} 0
|
|
183
|
+
all_wav_files+=($wav_file.padded.wav)
|
|
184
|
+
fi
|
|
185
|
+
fi
|
|
186
|
+
fi
|
|
187
|
+
done < "$temp_dir/sentences.txt"
|
|
188
|
+
|
|
189
|
+
if [[ ${sentence_num} -eq 0 ]]; then
|
|
190
|
+
rm -rf $temp_dir
|
|
191
|
+
return 1
|
|
192
|
+
fi
|
|
193
|
+
|
|
194
|
+
sox $all_wav_files "$output_file" rate 48k
|
|
195
|
+
rm -rf $temp_dir
|
|
196
|
+
return 0
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
_tts_prep_file() {
|
|
200
|
+
FILE_TYPE=$(file -b "$1")
|
|
201
|
+
echo $FILE_TYPE
|
|
202
|
+
echo $FILE_TYPE | grep -q -s CRLF.\*line.terminators && dos2unix "$1"
|
|
203
|
+
if echo $FILE_TYPE | grep -q -s Non-ISO.extended-ASCII; then
|
|
204
|
+
iconv -c -f macroman -t ascii < "$1" > "$1.ascii"
|
|
205
|
+
cat "$1.ascii" > "$1"
|
|
206
|
+
rm "$1.ascii"
|
|
207
|
+
fi
|
|
208
|
+
# Sanitize text for TTS using pandoc (auto-detect format)
|
|
209
|
+
pandoc -t plain --wrap=none "$1" | \
|
|
210
|
+
tr -cd '[:alnum:][:space:][:punct:]\n' > "$1.tmp" && mv "$1.tmp" "$1"
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
_die() {
|
|
214
|
+
echo $* >&2
|
|
215
|
+
exit 1
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if [[ "$1" == --move ]]; then
|
|
219
|
+
MOVE_FLAG=true
|
|
220
|
+
shift
|
|
221
|
+
fi
|
|
222
|
+
|
|
223
|
+
# Check if a custom mode is defined in config
|
|
224
|
+
if [[ -n "$1" && "$1" != --move && "$1" != slow && "$1" != fast && ! -f "$1" ]]; then
|
|
225
|
+
if [[ $(yq ".speech.$1" "$ZDS_AI_AGENT_CONFIG_FILE") != null ]]; then
|
|
226
|
+
_load_mode_config "$1"
|
|
227
|
+
CURRENT_MODE="$1"
|
|
228
|
+
SUFFIX=-$1
|
|
229
|
+
shift
|
|
230
|
+
fi
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
if [[ "$1" == slow ]]; then
|
|
234
|
+
SPEED=$(echo "$SPEED * 0.9" | bc -S 2 | awk '{printf "%f", $0}')
|
|
235
|
+
NORM=$((NORM - 2))
|
|
236
|
+
PITCH=$((PITCH - 40))
|
|
237
|
+
SUFFIX="${SUFFIX}-slow"
|
|
238
|
+
shift
|
|
239
|
+
fi
|
|
240
|
+
|
|
241
|
+
if [[ "$1" == fast ]]; then
|
|
242
|
+
SPEED=$(echo "$SPEED * 1.2" | bc -S 2 | awk '{printf "%f", $0}')
|
|
243
|
+
NORM=$((NORM + 2))
|
|
244
|
+
PITCH=$((PITCH + 40))
|
|
245
|
+
SUFFIX="${SUFFIX}-fast"
|
|
246
|
+
shift
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
local outdir=${ZDS_AI_AGENT_HOME_DIR:+$ZDS_AI_AGENT_HOME_DIR/}out/Speech/
|
|
250
|
+
mkdir -p ${outdir} || _die could not create ${outdir}
|
|
251
|
+
[[ -d "$ZDS_AI_TTS_MOVE_DIR" ]] && MOVE_DIR="$ZDS_AI_TTS_MOVE_DIR" || \
|
|
252
|
+
MOVE_DIR="$outdir"
|
|
253
|
+
|
|
254
|
+
# for var in SPEED NORM PITCH VOICE_REMOTE SUFFIX MOVE_DIR; do
|
|
255
|
+
# echo $var = ${(P)var} >> $LOGFILE
|
|
256
|
+
# done
|
|
257
|
+
|
|
258
|
+
# for a in pre/*(N); do
|
|
259
|
+
for a in "$@"; do
|
|
260
|
+
[[ "$a" == --move ]] && MOVE_FLAG=true && continue
|
|
261
|
+
|
|
262
|
+
b=${outdir}$(basename "$a" .txt)$SUFFIX.$$
|
|
263
|
+
(
|
|
264
|
+
_tts_prep_file "$a"
|
|
265
|
+
# _tts_render_kokoro "$a" "${b}-temp1.wav" || continue
|
|
266
|
+
_tts_render_kokoro_remote_sentences "$a" "${b}-temp1.wav" || continue
|
|
267
|
+
_tts_fix_audio "${b}-temp1.wav" "${b}-temp2.wav" || continue
|
|
268
|
+
_tts_postprocess_audio "${b}-temp2.wav" "${b}.wav" || continue
|
|
269
|
+
rm -f "${b}-temp1.wav" "${b}-temp2.wav"
|
|
270
|
+
echo "${b}.wav"
|
|
271
|
+
soxi "${b}.wav"
|
|
272
|
+
sox "${b}.wav" "${b}.$EXT"
|
|
273
|
+
) > ${b}.stdout.txt 2> ${b}.stderr.txt
|
|
274
|
+
if [[ -s "${b}.$EXT" ]]; then
|
|
275
|
+
rm "${b}.stdout.txt"
|
|
276
|
+
rm "${b}.stderr.txt"
|
|
277
|
+
if [[ $MOVE_FLAG == true ]]; then
|
|
278
|
+
mv -v "${b}.$EXT" "$MOVE_DIR"
|
|
279
|
+
rm "${b}.wav"
|
|
280
|
+
echo "$MOVE_DIR"/$(basename "${b}.$EXT")
|
|
281
|
+
else
|
|
282
|
+
echo "${b}.$EXT"
|
|
283
|
+
fi
|
|
284
|
+
else
|
|
285
|
+
cat "${b}.stdout.txt"
|
|
286
|
+
cat "${b}.stderr.txt" >&2
|
|
287
|
+
exit 1
|
|
288
|
+
fi
|
|
289
|
+
done
|
|
290
|
+
|
|
291
|
+
exit 0
|
package/dist/grok/client.d.ts
CHANGED
|
@@ -20,11 +20,42 @@ export interface LLMToolCall {
|
|
|
20
20
|
arguments: string;
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* @deprecated Use WebSearchTool with the Agent Tools API instead.
|
|
25
|
+
* The search_parameters field is deprecated as of December 15, 2025.
|
|
26
|
+
*/
|
|
23
27
|
export interface SearchParameters {
|
|
24
28
|
mode?: "auto" | "on" | "off";
|
|
25
29
|
}
|
|
30
|
+
export interface WebSearchTool {
|
|
31
|
+
type: "web_search";
|
|
32
|
+
allowed_domains?: string[];
|
|
33
|
+
excluded_domains?: string[];
|
|
34
|
+
enable_image_understanding?: boolean;
|
|
35
|
+
user_location?: {
|
|
36
|
+
type: "approximate";
|
|
37
|
+
country?: string;
|
|
38
|
+
city?: string;
|
|
39
|
+
region?: string;
|
|
40
|
+
timezone?: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
26
43
|
export interface SearchOptions {
|
|
44
|
+
/** @deprecated Use enable_web_search and web_search_filters instead */
|
|
27
45
|
search_parameters?: SearchParameters;
|
|
46
|
+
enable_web_search?: boolean;
|
|
47
|
+
web_search_filters?: {
|
|
48
|
+
allowed_domains?: string[];
|
|
49
|
+
excluded_domains?: string[];
|
|
50
|
+
enable_image_understanding?: boolean;
|
|
51
|
+
user_location?: {
|
|
52
|
+
type: "approximate";
|
|
53
|
+
country?: string;
|
|
54
|
+
city?: string;
|
|
55
|
+
region?: string;
|
|
56
|
+
timezone?: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
28
59
|
}
|
|
29
60
|
export interface LLMResponse {
|
|
30
61
|
choices: Array<{
|
|
@@ -43,8 +74,10 @@ export declare class LLMClient {
|
|
|
43
74
|
private backendName;
|
|
44
75
|
private supportsTools;
|
|
45
76
|
private supportsVision;
|
|
77
|
+
private disableReasoningOverride;
|
|
46
78
|
constructor(apiKey: string, model?: string, baseURL?: string, displayName?: string);
|
|
47
79
|
setModel(model: string): Promise<void>;
|
|
80
|
+
private parseModelSuffix;
|
|
48
81
|
private enableTools;
|
|
49
82
|
private enableVision;
|
|
50
83
|
getCurrentModel(): string;
|
|
@@ -55,6 +88,27 @@ export declare class LLMClient {
|
|
|
55
88
|
setSupportsVision(value: boolean): void;
|
|
56
89
|
chat(messages: LLMMessage[], tools?: LLMTool[], model?: string, searchOptions?: SearchOptions, temperature?: number, signal?: AbortSignal, maxTokens?: number): Promise<LLMResponse>;
|
|
57
90
|
chatStream(messages: LLMMessage[], tools?: LLMTool[], model?: string, searchOptions?: SearchOptions, temperature?: number, signal?: AbortSignal, maxTokens?: number): AsyncGenerator<any, void, unknown>;
|
|
91
|
+
/**
|
|
92
|
+
* @deprecated This method uses the deprecated search_parameters API.
|
|
93
|
+
*
|
|
94
|
+
* Migrate to using chat() with enable_web_search instead:
|
|
95
|
+
*
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const searchOptions: SearchOptions = {
|
|
98
|
+
* enable_web_search: true,
|
|
99
|
+
* web_search_filters: {
|
|
100
|
+
* allowed_domains: ['example.com'], // optional
|
|
101
|
+
* excluded_domains: ['spam.com'], // optional
|
|
102
|
+
* enable_image_understanding: true // optional
|
|
103
|
+
* }
|
|
104
|
+
* };
|
|
105
|
+
*
|
|
106
|
+
* await client.chat([{role: "user", content: query}], [], undefined, searchOptions);
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* The search_parameters field was deprecated by Grok API on December 15, 2025.
|
|
110
|
+
* See: https://docs.x.ai/docs/guides/tools/search-tools
|
|
111
|
+
*/
|
|
58
112
|
search(query: string, searchParameters?: SearchParameters): Promise<LLMResponse>;
|
|
59
113
|
/**
|
|
60
114
|
* Returns true if the host part of baseURL matches one of the allowedHosts or a subdomain thereof.
|