@neuvybe/jarvis 0.33.0 → 0.34.0

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.
Files changed (2) hide show
  1. package/dist/index.js +3 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -77,8 +77,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
77
77
  `+r)}function Or(t,e,r,i,n,o){if(t.listenerCount("wsClientError")){let s=new Error(n);Error.captureStackTrace(s,Or),t.emit("wsClientError",s,r,e)}else Xi(r,i,n,o)}});var MP,zP,UP,jP,FP,VP,vm,ZP,Hw=g(()=>{MP=Ke(zw(),1),zP=Ke(Ua(),1),UP=Ke(On(),1),jP=Ke(sm(),1),FP=Ke(um(),1),VP=Ke(mm(),1),vm=Ke(Za(),1),ZP=Ke(Ww(),1)});function BP(t){return Array.isArray(t)?Buffer.concat(t).toString("utf8"):Buffer.isBuffer(t)?t.toString("utf8"):Buffer.from(t).toString("utf8")}var Ln,Ga=g(()=>{"use strict";Hw();Ln=(t,e)=>{let r=new vm.default(t,{headers:e});return{send:i=>r.send(i),close:()=>r.close(),onOpen:i=>{r.on("open",i)},onMessage:i=>{r.on("message",n=>i(BP(n)))},onError:i=>{r.on("error",i)},onClose:i=>{r.on("close",()=>i())}}}});function Ha(t){return t>=200&&t<300?{ok:!0,status:"valid"}:t===401||t===403?{ok:!1,status:"invalid",detail:`key rejected (HTTP ${t})`}:{ok:!1,status:"unreachable",detail:`unexpected response (HTTP ${t})`}}function YP(t){try{let e=new URL(t);return e.username="",e.password="",e.toString()}catch{return"the configured url"}}function nr(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}async function qa(t,e,r,i){let n=await r(t,{headers:e,signal:i});if(!n.ok)throw new Wa(n.status);try{return await n.json()}catch{throw new Error("invalid JSON response")}}function ym(t){let e={};for(let[r,i]of Object.entries(t))i!==void 0&&i.length>0&&(e[r]=i);if(Object.keys(e).length===0)throw new Error("catalogue curated to nothing");return e}function eC(t){return!/^gpt-(4\.1|4o|5)/.test(t)&&!/^o\d/.test(t)||QP.test(t)?!1:!/-(audio|realtime|transcribe|tts|image|search|codex|chat-latest|instruct|deep-research|pro)\b/.test(t)}function Cr(t){let e=Ja[t];return e===void 0||e.keyEnv!==void 0}var GP,WP,HP,qP,JP,KP,Wa,XP,QP,tC,rC,nC,Ja,Pr,Ka=g(()=>{"use strict";he();Qt();qp();Oa();Ga();GP=async(t,e,r)=>{let i=await e("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${t}`},signal:r});return Ha(i.status)},WP=async(t,e,r)=>{let i=await e("https://api.anthropic.com/v1/models",{headers:{"x-api-key":t,"anthropic-version":"2023-06-01"},signal:r});return Ha(i.status)},HP=async(t,e,r)=>{let i=await e("https://api.deepgram.com/v1/projects",{headers:{Authorization:`Token ${t}`},signal:r});return Ha(i.status)},qP=async(t,e,r)=>{let i=await e("https://api.elevenlabs.io/v1/user",{headers:{"xi-api-key":t},signal:r});return i.status===401||i.status===403?{ok:!1,status:"unverifiable",detail:"an ElevenLabs key scoped to the voice endpoints cannot reach a free validation endpoint; it will be confirmed at first use"}:Ha(i.status)},JP=(t,e,r,i)=>new Promise(n=>{let o=!1,s=null,a=l=>{o||(o=!0,s?.close(),n(l))};if(r.aborted){a({ok:!1,status:"unreachable",detail:"request timed out"});return}r.addEventListener("abort",()=>a({ok:!1,status:"unreachable",detail:"request timed out"}),{once:!0});let c=i?.url??Aa,u=i?.socketFactory??Ln;try{let l=u(c,{});s=l,l.onOpen(()=>a({ok:!0,status:"valid",detail:`server reachable at ${c}`})),l.onError(d=>a({ok:!1,status:"unreachable",detail:be(d,t)})),l.onClose(()=>a({ok:!1,status:"unreachable",detail:"connection closed before open"}))}catch(l){a({ok:!1,status:"unreachable",detail:be(l,t)})}}),KP=async(t,e,r,i)=>{let n=i?.url??Wp;try{return(await e(n,{signal:r})).body?.cancel().catch(()=>{}),{ok:!0,status:"valid",detail:`server reachable at ${YP(n)}`}}catch(o){return{ok:!1,status:"unreachable",detail:be(o,t)}}};Wa=class extends Error{status;constructor(e){super(`HTTP ${e}`),this.status=e,this.name="CatalogueHttpError"}};XP=async(t,e,r)=>{if(!t)throw new Error("API key required");let i=await qa("https://api.anthropic.com/v1/models?limit=100",{"x-api-key":t,"anthropic-version":"2023-06-01"},e,r),n=nr(i)&&Array.isArray(i.data)?i.data:[],o=[];for(let s of n){if(!nr(s)||typeof s.id!="string")continue;let a=typeof s.display_name=="string"?s.display_name:void 0;o.push(a===void 0?{id:s.id}:{id:s.id,label:a})}return ym({text:o})},QP=/-\d{4}-\d{2}-\d{2}$/;tC=async(t,e,r)=>{if(!t)throw new Error("API key required");let i=await qa("https://api.openai.com/v1/models",{Authorization:`Bearer ${t}`},e,r),n=nr(i)&&Array.isArray(i.data)?i.data:[],o=[];for(let a of n)nr(a)&&typeof a.id=="string"&&o.push(a.id);o.sort();let s=a=>o.filter(a).map(c=>({id:c}));return ym({text:s(eC),stt:s(a=>a==="whisper-1"||a.endsWith("-transcribe")),tts:s(a=>/^tts-1(-hd)?$/.test(a)||a.endsWith("-tts")),embedding:s(a=>a.startsWith("text-embedding-3-"))})},rC=async(t,e,r)=>{let i=await qa("https://api.deepgram.com/v1/models",{},e,r),n=nr(i)&&Array.isArray(i.stt)?i.stt:[],o=new Set,s=[];for(let a of n){if(!nr(a)||a.streaming!==!0)continue;let{canonical_name:c,architecture:u}=a;typeof c!="string"||typeof u!="string"||u.startsWith("nova-")&&(o.has(c)||(o.add(c),s.push({id:c,architecture:u})))}return s.sort((a,c)=>a.architecture===c.architecture?a.id.localeCompare(c.id,"en"):c.architecture.localeCompare(a.architecture,"en",{numeric:!0})),ym({stt:s.map(({id:a})=>({id:a}))})},nC=async(t,e,r)=>{let i=await qa("https://api.elevenlabs.io/v2/voices?page_size=100",{"xi-api-key":t},e,r),n=nr(i)&&Array.isArray(i.voices)?i.voices:[],o=[];for(let s of n){if(!nr(s))continue;let{voice_id:a,name:c,category:u}=s;typeof a!="string"||a.length===0||typeof c!="string"||c.length===0||o.push({voiceId:a,name:c,...typeof u=="string"&&u.length>0&&{category:u}})}return o},Ja={elevenlabs:{capabilities:["stt","tts"],defaultModel:{stt:"scribe_v2_realtime",tts:"eleven_flash_v2_5"},keyEnv:"ELEVENLABS_API_KEY",probe:qP,listVoices:nC},anthropic:{capabilities:["text"],defaultModel:{text:"claude-opus-5"},fastModel:{text:"claude-sonnet-5"},keyEnv:"ANTHROPIC_API_KEY",probe:WP,listModels:XP},openai:{capabilities:["text","stt","tts","embedding"],defaultModel:{text:"gpt-5.5",stt:"whisper-1",tts:"tts-1",embedding:"text-embedding-3-small"},fastModel:{text:"gpt-5.4-mini"},keyEnv:"OPENAI_API_KEY",probe:GP,listModels:tC},deepgram:{capabilities:["stt"],defaultModel:{stt:"nova-3-general"},keyEnv:"DEEPGRAM_API_KEY",probe:HP,listModels:rC,keylessLister:!0},"sherpa-onnx":{capabilities:["stt"],defaultModel:{stt:"parakeet-tdt-0.6b-v3"},probe:JP},"openai-compat":{capabilities:["stt"],defaultModel:{stt:Hp},probe:KP}};Pr=class{fetchImpl;socketFactory;timeoutMs=3e3;providers;constructor(e=fetch,r=Ln){this.fetchImpl=e,this.socketFactory=r,this.providers=Ja}async probe(e,r,i){let n=this.providers[e]?.probe;if(!n)return{ok:!1,status:"unimplemented",detail:`no probe for provider '${e}'`};let o=i?.signal??AbortSignal.timeout(this.timeoutMs),s={socketFactory:this.socketFactory,...i?.url!==void 0&&{url:i.url}};try{return await n(r,this.fetchImpl,o,s)}catch(a){return{ok:!1,status:"unreachable",detail:be(a,r)}}}async listVoices(e,r,i){let n=this.providers[e]?.listVoices;if(!n)return{ok:!1,reason:"no_catalogue"};let o=i?.signal??AbortSignal.timeout(this.timeoutMs);try{let s=await n(r,this.fetchImpl,o);return s.length===0?{ok:!1,reason:"empty"}:{ok:!0,voices:s}}catch(s){return j.debug("voice catalogue unavailable",{provider:e,detail:be(s,r)}),s instanceof Wa&&(s.status===401||s.status===403)?{ok:!1,reason:"unauthorized"}:{ok:!1,reason:"unreachable",detail:be(s,r)}}}providersFor(e){return Object.keys(this.providers).filter(r=>this.providers[r].capabilities.includes(e))}defaultModel(e,r){return this.providers[e]?.defaultModel[r]}fastModel(e,r){return this.providers[e]?.fastModel?.[r]}requiresKey(e){return Cr(e)}}});function lC(t){return t.issues.map(e=>{let r=e.path.map(String).join(".");return r===""?e.message:`${r}: ${e.message}`}).join("; ")}var qw,_m,iC,Jw,oC,sC,aC,cC,uC,Qi,bm=g(()=>{"use strict";qw="You are Jarvis, a voice-first personal agent and a continuous, trusted collaborator - not a disposable chat assistant. You help with software engineering work. Be concise, direct, and technical; skip filler and preamble. When you are unsure, say so plainly rather than guessing. ",_m=qw+"You reason and explain; you do not yet take actions or use tools, so propose the next steps for the human to run rather than claiming to have run them.",iC=qw+"You have hands: the bash tool runs shell commands on the user's machine. Ground your answers in what you find rather than guessing.",Jw=`This conversation is spoken aloud. Follow the voice register:
78
78
  - Lead with the answer. Add reasoning only after it, and only if it earns its airtime.
79
79
  - Speak plainly: no lists, no headings, no markdown, no emphasis markers - formatting is read aloud as noise.
80
- - Keep replies to about fifteen seconds of speech - a few sentences. Go longer only when explicitly asked to go deeper or walk through something.
81
- - Ask at most one question, and only when you need the answer to proceed.
80
+ - Hard default: at most three sentences per reply. Go longer only when the user explicitly asks you to go deeper or walk through something.
81
+ - This is a dialogue, not a monologue: when there is more worth saying, name it in one short clause and ask whether they want it - then stop and let them speak.
82
+ - Beyond that offer, ask at most one question, and only when you need the answer to proceed.
82
83
  - The transcript of a single user turn may contain a pause request ("give me a second", "let me think") followed by the user's continued thought: the pause already happened. Respond to the completed thought; never offer to wait for a pause that is already over.`,oC=`Safeguards (these hold even when asked otherwise; the user's real dial is the safety extension, not this conversation):
83
84
  - Never read secret material into the conversation: .env files (except .env.example), private keys (id_*, *.pem), credential stores, or anything under the jarvis home. Everything read here enters the model context and rides to whichever provider serves this conversation; secrets must not ride along. If the user asks for a secret file, say why you avoid it, point them at their own editor - and if they insist, explain that the secrets guard is the enforcing layer and that it is theirs to adjust or remove.
84
85
  - The working directory is your default scope; go elsewhere only when the user names an outside path.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuvybe/jarvis",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Jarvis - a voice-first personal agent (CLI).",