@@ -144,44 +144,52 @@ if [ -d "$PROJECT_DIR" ] && [ -f "$PROJECT_DIR/agent.yaml" ]; then
144144 echo -e " ${GREEN} ✓${NC} Loaded keys from ${DIM}${PROJECT_DIR} /.env${NC} "
145145 fi
146146
147- # Prompt for missing required keys
148- if [ -z " ${OPENAI_API_KEY:- } " ] && [ -z " ${GEMINI_API_KEY:- } " ]; then
149- echo " "
150- echo -e " ${YELLOW} ⚠${NC} No voice API key found."
151- echo -e " ${BOLD} OpenAI API Key${NC} ${DIM} (for voice — get one at platform.openai.com)${NC} "
152- read -rsp " Key: " OPENAI_KEY
153- echo " "
154- if [ -z " $OPENAI_KEY " ]; then
155- echo -e " ${RED} ✗ OpenAI or Gemini key is required for voice mode${NC} "
156- exit 1
147+ # Prompt for missing required keys (skip if Lyzr is configured)
148+ if [ -n " ${GITCLAW_LYZR_AGENT_ID:- } " ]; then
149+ echo -e " ${GREEN} ✓${NC} Lyzr agent: ${DIM}${GITCLAW_LYZR_AGENT_ID}${NC} "
150+ else
151+ if [ -z " ${OPENAI_API_KEY:- } " ] && [ -z " ${GEMINI_API_KEY:- } " ]; then
152+ echo " "
153+ echo -e " ${YELLOW} ⚠${NC} No voice API key found."
154+ echo -e " ${BOLD} OpenAI API Key${NC} ${DIM} (for voice — get one at platform.openai.com)${NC} "
155+ read -rsp " Key: " OPENAI_KEY
156+ echo " "
157+ if [ -n " $OPENAI_KEY " ]; then
158+ export OPENAI_API_KEY=" $OPENAI_KEY "
159+ echo -e " ${GREEN} ✓${NC} OPENAI_API_KEY saved"
160+ echo " OPENAI_API_KEY=${OPENAI_API_KEY} " >> " $PROJECT_DIR /.env"
161+ else
162+ echo -e " ${DIM} skipped — text-only mode${NC} "
163+ fi
157164 fi
158- export OPENAI_API_KEY=" $OPENAI_KEY "
159- echo -e " ${GREEN} ✓${NC} OPENAI_API_KEY saved"
160- # Append to .env for future runs
161- echo " OPENAI_API_KEY=${OPENAI_API_KEY} " >> " $PROJECT_DIR /.env"
162- fi
163165
164- if [ -z " ${ANTHROPIC_API_KEY:- } " ]; then
165- echo " "
166- echo -e " ${YELLOW} ⚠${NC} No Anthropic API key found."
167- echo -e " ${BOLD} Anthropic API Key${NC} ${DIM} (for agent brain — get one at console.anthropic.com)${NC} "
168- read -rsp " Key: " ANTHROPIC_KEY
169- echo " "
170- if [ -z " $ANTHROPIC_KEY " ]; then
171- echo -e " ${RED} ✗ Anthropic key is required for the agent${NC} "
172- exit 1
166+ if [ -z " ${ANTHROPIC_API_KEY:- } " ]; then
167+ echo " "
168+ echo -e " ${YELLOW} ⚠${NC} No Anthropic API key found."
169+ echo -e " ${BOLD} Anthropic API Key${NC} ${DIM} (for agent brain — get one at console.anthropic.com)${NC} "
170+ read -rsp " Key: " ANTHROPIC_KEY
171+ echo " "
172+ if [ -z " $ANTHROPIC_KEY " ]; then
173+ echo -e " ${RED} ✗ Anthropic key is required for the agent${NC} "
174+ exit 1
175+ fi
176+ export ANTHROPIC_API_KEY=" $ANTHROPIC_KEY "
177+ echo -e " ${GREEN} ✓${NC} ANTHROPIC_API_KEY saved"
178+ echo " ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} " >> " $PROJECT_DIR /.env"
173179 fi
174- export ANTHROPIC_API_KEY=" $ANTHROPIC_KEY "
175- echo -e " ${GREEN} ✓${NC} ANTHROPIC_API_KEY saved"
176- # Append to .env for future runs
177- echo " ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} " >> " $PROJECT_DIR /.env"
178180 fi
179181
180- # Let loadAgent() read model directly from agent.yaml — no extraction needed
181- MODEL=" "
182+ # Set model — use Lyzr if configured, otherwise let loadAgent() read from agent.yaml
183+ if [ -n " ${GITCLAW_LYZR_AGENT_ID:- } " ]; then
184+ MODEL=" lyzr:${GITCLAW_LYZR_AGENT_ID} @https://agent-prod.studio.lyzr.ai/v4/chat"
185+ else
186+ MODEL=" "
187+ fi
182188
183189 # Determine adapter from available keys
184- if [ -n " ${GEMINI_API_KEY:- } " ] && [ -z " ${OPENAI_API_KEY:- } " ]; then
190+ if [ -n " ${GITCLAW_LYZR_AGENT_ID:- } " ] && [ -z " ${OPENAI_API_KEY:- } " ]; then
191+ ADAPTER_LABEL=" Text Only (Lyzr)"
192+ elif [ -n " ${GEMINI_API_KEY:- } " ] && [ -z " ${OPENAI_API_KEY:- } " ]; then
185193 ADAPTER_LABEL=" Gemini Live"
186194 elif [ -n " ${OPENAI_API_KEY:- } " ]; then
187195 ADAPTER_LABEL=" OpenAI Realtime"
@@ -199,9 +207,10 @@ else
199207# ── Setup Mode Selection ─────────────────────────────────────────
200208echo -e " ${BOLD} How would you like to run?${NC} "
201209echo " "
202- echo -e " ${RED}${BOLD} 1)${NC} ${BOLD} Voice + Text${NC} ${DIM} — real-time voice chat + text (requires OpenAI key)${NC} "
203- echo -e " ${RED}${BOLD} 2)${NC} ${BOLD} Text Only${NC} ${DIM} — text chat only, no voice (just Anthropic key)${NC} "
204- echo -e " ${RED}${BOLD} 3)${NC} ${BOLD} Advanced Setup${NC} ${DIM} — choose voice adapter, model, project dir, integrations${NC} "
210+ echo -e " ${RED}${BOLD} 1)${NC} ${BOLD} Install with LYZR${NC} ${DIM} — powered by Lyzr AI Studio (easiest)${NC} "
211+ echo -e " ${RED}${BOLD} 2)${NC} ${BOLD} Voice + Text${NC} ${DIM} — real-time voice chat + text (requires OpenAI key)${NC} "
212+ echo -e " ${RED}${BOLD} 3)${NC} ${BOLD} Text Only${NC} ${DIM} — text chat only, no voice (just Anthropic key)${NC} "
213+ echo -e " ${RED}${BOLD} 4)${NC} ${BOLD} Advanced Setup${NC} ${DIM} — choose voice adapter, model, project dir, integrations${NC} "
205214echo " "
206215read -rp " Choice [1]: " SETUP_MODE
207216SETUP_MODE=" ${SETUP_MODE:- 1} "
@@ -210,10 +219,121 @@ echo ""
210219# ═══════════════════════════════════════════════════════════════════
211220# QUICK SETUP
212221# ═══════════════════════════════════════════════════════════════════
213- if [ " $SETUP_MODE " = " 1" ] || [ " $SETUP_MODE " = " 2" ]; then
222+ # ═══════════════════════════════════════════════════════════════════
223+ # LYZR SETUP
224+ # ═══════════════════════════════════════════════════════════════════
225+ if [ " $SETUP_MODE " = " 1" ]; then
226+
227+ echo -e " ${DIM} ────────────────────────────────────────────────────${NC} "
228+ echo -e " ${RED}${BOLD} Install with LYZR${NC} "
229+ echo -e " ${DIM} Powered by Lyzr AI Studio — agent brain runs on Lyzr cloud${NC} "
230+ echo " "
231+
232+ # LYZR API key
233+ echo -e " ${BOLD} Lyzr API Key${NC} ${DIM} (get one at studio.lyzr.ai)${NC} "
234+ read -rsp " Key: " LYZR_KEY
235+ echo " "
236+ if [ -z " $LYZR_KEY " ]; then
237+ echo -e " ${RED} ✗ Lyzr API key is required${NC} "
238+ exit 1
239+ fi
240+ export LYZR_API_KEY=" $LYZR_KEY "
241+ echo -e " ${GREEN} ✓${NC} LYZR_API_KEY saved"
242+
243+ # Check if agent already exists
244+ if [ -z " ${GITCLAW_LYZR_AGENT_ID:- } " ]; then
245+ echo " "
246+ echo -e " ${DIM} Creating Lyzr agent...${NC} "
247+ LYZR_RESPONSE=$( curl -s -X POST ' https://agent-prod.studio.lyzr.ai/v3/agents/' \
248+ -H ' accept: application/json' \
249+ -H ' content-type: application/json' \
250+ -H " x-api-key: ${LYZR_API_KEY} " \
251+ --data-raw ' {
252+ "name": "GitClaw Assistant",
253+ "description": "GitClaw AI agent powered by Lyzr",
254+ "agent_role": "",
255+ "agent_goal": "",
256+ "agent_instructions": "",
257+ "examples": null,
258+ "tools": [],
259+ "tool_usage_description": "{}",
260+ "tool_configs": [],
261+ "provider_id": "Anthropic",
262+ "model": "anthropic/claude-sonnet-4-6",
263+ "temperature": 0.7,
264+ "top_p": 0.9,
265+ "llm_credential_id": "lyzr_anthropic",
266+ "features": [],
267+ "managed_agents": [],
268+ "a2a_tools": [],
269+ "additional_model_params": null,
270+ "response_format": {"type": "text"},
271+ "store_messages": true,
272+ "file_output": false,
273+ "image_output_config": null,
274+ "max_iterations": 25
275+ }' 2> /dev/null)
276+
277+ # Extract agent ID from response
278+ LYZR_AGENT_ID=$( echo " $LYZR_RESPONSE " | grep -o ' "agent_id"\s*:\s*"[^"]*"' | head -1 | sed ' s/.*"agent_id"\s*:\s*"\([^"]*\)".*/\1/' )
279+ if [ -z " $LYZR_AGENT_ID " ]; then
280+ # Try alternate field name
281+ LYZR_AGENT_ID=$( echo " $LYZR_RESPONSE " | grep -o ' "id"\s*:\s*"[^"]*"' | head -1 | sed ' s/.*"id"\s*:\s*"\([^"]*\)".*/\1/' )
282+ fi
283+
284+ if [ -z " $LYZR_AGENT_ID " ]; then
285+ echo -e " ${RED} ✗ Failed to create Lyzr agent${NC} "
286+ echo -e " ${DIM} Response: ${LYZR_RESPONSE}${NC} "
287+ exit 1
288+ fi
289+
290+ export GITCLAW_LYZR_AGENT_ID=" $LYZR_AGENT_ID "
291+ echo -e " ${GREEN} ✓${NC} Agent created: ${DIM}${LYZR_AGENT_ID}${NC} "
292+ else
293+ echo -e " ${GREEN} ✓${NC} Using existing agent: ${DIM}${GITCLAW_LYZR_AGENT_ID}${NC} "
294+ fi
295+
296+ # OpenAI key for voice (optional)
297+ echo " "
298+ echo -e " ${BOLD} OpenAI API Key${NC} ${DIM} (optional — for voice mode, press Enter to skip)${NC} "
299+ read -rsp " Key: " OPENAI_KEY
300+ echo " "
301+ if [ -n " $OPENAI_KEY " ]; then
302+ export OPENAI_API_KEY=" $OPENAI_KEY "
303+ echo -e " ${GREEN} ✓${NC} OPENAI_API_KEY saved"
304+ VOICE_ENABLED=true
305+ else
306+ echo -e " ${DIM} skipped — text-only mode${NC} "
307+ VOICE_ENABLED=false
308+ fi
309+
310+ # Set model to use Lyzr completions endpoint with agent ID as model
311+ MODEL=" lyzr:${GITCLAW_LYZR_AGENT_ID} @https://agent-prod.studio.lyzr.ai/v4/chat"
312+ export GITCLAW_MODEL_BASE_URL=" https://agent-prod.studio.lyzr.ai/v4/chat"
313+ ADAPTER_LABEL=" ${VOICE_ENABLED: +OpenAI Realtime}${VOICE_ENABLED:- Text Only} "
314+ if [ " $VOICE_ENABLED " = true ]; then
315+ ADAPTER_LABEL=" OpenAI Realtime"
316+ else
317+ ADAPTER_LABEL=" Text Only (Lyzr)"
318+ fi
319+ PROJECT_DIR=" ${HOME} /assistant"
320+
321+ # Create project dir and init git if needed
322+ mkdir -p " $PROJECT_DIR "
323+ if [ ! -d " $PROJECT_DIR /.git" ]; then
324+ git init -q " $PROJECT_DIR "
325+ echo -e " ${GREEN} ✓${NC} Initialized ~/assistant"
326+ fi
327+
328+ echo " "
329+
330+ # ═══════════════════════════════════════════════════════════════════
331+ # VOICE + TEXT / TEXT ONLY SETUP
332+ # ═══════════════════════════════════════════════════════════════════
333+ elif [ " $SETUP_MODE " = " 2" ] || [ " $SETUP_MODE " = " 3" ]; then
214334
215335 VOICE_ENABLED=true
216- if [ " $SETUP_MODE " = " 2 " ]; then
336+ if [ " $SETUP_MODE " = " 3 " ]; then
217337 VOICE_ENABLED=false
218338 fi
219339
@@ -424,6 +544,9 @@ echo -e " ${LGRAY}Voice${NC} ${WHITE}${ADAPTER_LABEL}${NC}"
424544echo -e " ${LGRAY} Model${NC} ${WHITE}${MODEL}${NC} "
425545echo -e " ${LGRAY} Directory${NC} ${WHITE}${PROJECT_DIR}${NC} "
426546echo -e " ${LGRAY} Port${NC} ${WHITE}${PORT}${NC} "
547+ if [ -n " ${GITCLAW_LYZR_AGENT_ID:- } " ]; then
548+ echo -e " ${LGRAY} Lyzr${NC} ${GREEN} enabled${NC} ${DIM} (agent: ${GITCLAW_LYZR_AGENT_ID} )${NC} "
549+ fi
427550if [ -n " ${COMPOSIO_API_KEY:- } " ]; then
428551 echo -e " ${LGRAY} Composio${NC} ${GREEN} enabled${NC} "
429552fi
@@ -445,6 +568,9 @@ ENV_FILE="${PROJECT_DIR}/.env"
445568 [ -n " ${ANTHROPIC_API_KEY:- } " ] && echo " ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} "
446569 [ -n " ${COMPOSIO_API_KEY:- } " ] && echo " COMPOSIO_API_KEY=${COMPOSIO_API_KEY} "
447570 [ -n " ${TELEGRAM_BOT_TOKEN:- } " ] && echo " TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN} "
571+ [ -n " ${LYZR_API_KEY:- } " ] && echo " LYZR_API_KEY=${LYZR_API_KEY} "
572+ [ -n " ${GITCLAW_LYZR_AGENT_ID:- } " ] && echo " GITCLAW_LYZR_AGENT_ID=${GITCLAW_LYZR_AGENT_ID} "
573+ [ -n " ${GITCLAW_MODEL_BASE_URL:- } " ] && echo " GITCLAW_MODEL_BASE_URL=${GITCLAW_MODEL_BASE_URL} "
448574} > " $ENV_FILE "
449575echo -e " ${GREEN} ✓${NC} Keys saved to ${DIM}${ENV_FILE}${NC} ${DIM} (gitignored)${NC} "
450576echo " "
0 commit comments