@swifty.js/swifty 0.0.26 → 0.0.28

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 (58) hide show
  1. package/README.md +14 -6
  2. package/dist/agent-3NON2EXE.js +4 -0
  3. package/dist/anthropic-BJ5GN2VT.js +4 -0
  4. package/dist/checker-N5TIJEN5.js +4 -0
  5. package/dist/{chunk-H7VXSMJR.js → chunk-C3WGLVVZ.js} +10 -10
  6. package/dist/chunk-D34FUVGU.js +4 -0
  7. package/dist/chunk-FPQ2LBL4.js +10 -0
  8. package/dist/chunk-JGSIQXEN.js +4 -0
  9. package/dist/{chunk-5KXBVL2A.js → chunk-K5ZK27BX.js} +1 -1
  10. package/dist/chunk-LZBOXJX2.js +301 -0
  11. package/dist/chunk-OTVZGPHD.js +121 -0
  12. package/dist/chunk-QCKJLO6X.js +4 -0
  13. package/dist/chunk-R63ASIIW.js +407 -0
  14. package/dist/chunk-WX3B64R4.js +4 -0
  15. package/dist/chunk-Y6SQB5FG.js +4 -0
  16. package/dist/{devtools-3OAJUZGE.js → devtools-OJ75EP3T.js} +1 -1
  17. package/dist/glob.wasm +0 -0
  18. package/dist/lib/agent-XYO2MXXK.js +11 -0
  19. package/dist/lib/{anthropic-RYPJDHQM.js → anthropic-TGJGAP5R.js} +4 -5
  20. package/dist/lib/{checker-6BW4222R.js → checker-AXHPKVBY.js} +2 -2
  21. package/dist/lib/{chunk-HK2Z6WP4.js → chunk-2IVEVG5N.js} +5 -1
  22. package/dist/lib/{chunk-2AUSNVIB.js → chunk-ALJAVRRX.js} +28 -34
  23. package/dist/lib/{chunk-GNI7YX6F.js → chunk-DJ6AILPN.js} +70 -24
  24. package/dist/lib/chunk-DV6RV5WU.js +2345 -0
  25. package/dist/lib/{chunk-3LU4APFB.js → chunk-FBSPZQGC.js} +126 -73
  26. package/dist/lib/chunk-IB5IQK2S.js +136 -0
  27. package/dist/lib/{chunk-PZ42NAFA.js → chunk-KG4MJGKQ.js} +19 -21
  28. package/dist/lib/{chunk-XFSN4LMA.js → chunk-P4F46PEF.js} +43 -14
  29. package/dist/lib/glob.wasm +0 -0
  30. package/dist/lib/index.d.ts +145 -123
  31. package/dist/lib/index.js +2186 -1726
  32. package/dist/lib/{openai-VX5VBXZ4.js → openai-5UCIIDPO.js} +2 -3
  33. package/dist/lib/{tool-filter-VF7TZRE5.js → tool-filter-R6HDDJHE.js} +1 -1
  34. package/dist/main.js +226 -196
  35. package/dist/{node-OES65R33.js → node-4LTSRXL2.js} +1 -1
  36. package/dist/{openai-6MXNADYN.js → openai-YLS2LUAI.js} +14 -14
  37. package/dist/server-GX72MJQF.js +244 -0
  38. package/dist/{tool-filter-NO7I3HFD.js → tool-filter-VBP6WOGO.js} +1 -1
  39. package/package.json +36 -32
  40. package/dist/agent-GAABBZRW.js +0 -4
  41. package/dist/anthropic-7QRAPLOY.js +0 -4
  42. package/dist/checker-3RWAYF2U.js +0 -4
  43. package/dist/chunk-7MHXMDYC.js +0 -35
  44. package/dist/chunk-A2VR3BC4.js +0 -4
  45. package/dist/chunk-FZPTNGTU.js +0 -4
  46. package/dist/chunk-MWZIARZE.js +0 -130
  47. package/dist/chunk-NR62AA5K.js +0 -4
  48. package/dist/chunk-QN27QEFS.js +0 -4
  49. package/dist/chunk-RMMK4PO5.js +0 -389
  50. package/dist/chunk-SIWLMWHH.js +0 -93
  51. package/dist/chunk-VC6OXOMP.js +0 -238
  52. package/dist/chunk-W37Y53LX.js +0 -4
  53. package/dist/chunk-XBHVVB5A.js +0 -10
  54. package/dist/lib/agent-U7MIUCKT.js +0 -9
  55. package/dist/lib/chunk-2QILP24G.js +0 -1120
  56. package/dist/lib/chunk-OO2CLOEE.js +0 -88
  57. package/dist/lib/chunk-RKJYTYQM.js +0 -1285
  58. package/dist/server-P2VE5HLJ.js +0 -244
package/README.md CHANGED
@@ -118,9 +118,9 @@ Provider fields:
118
118
  | base_url | yes | API base URL |
119
119
  | model | yes | Model identifier |
120
120
  | api_key | no | API key (falls back to environment variable) |
121
- | thinking | no | Enable extended thinking mode (increases max_output_tokens to 64000) |
122
- | context_window | no | Override auto-detected context window size |
123
- | max_output_tokens | no | Override default max output tokens |
121
+ | thinking | no | Enable extended thinking (default: true) |
122
+ | context_window | no | Context window in tokens (default: 1000000; no model-name inference) |
123
+ | max_output_tokens | no | Maximum output tokens (default: 128000) |
124
124
 
125
125
  API keys are resolved in this order: explicit api_key field, then environment variables (ANTHROPIC_API_KEY for anthropic, OPENAI_API_KEY for openai and openai-compat).
126
126
 
@@ -134,6 +134,10 @@ swifty
134
134
 
135
135
  Launches the terminal interface. If multiple providers are configured, a provider selection screen appears first.
136
136
 
137
+ Use `/login` to configure and activate a provider from the TUI. When no provider is configured, the login form opens automatically. Name, protocol, base URL, API key, and model are required in the form. Use ↑↓ or Tab to move between fields, ←→ to select protocol or thinking, Enter to save, and Esc to cancel. Duplicate names receive numeric suffixes (`name2`, `name3`, …).
138
+
139
+ The form saves to the project's `.swifty/config.local.yaml`, retaining existing providers and other settings. Context window accepts integers from 1000 to 10000000; max output accepts integers from 1 to 1000000 and must not exceed the context window. Empty optional fields use the defaults above.
140
+
137
141
  ### Print Mode (Non-Interactive)
138
142
 
139
143
  ```bash
@@ -146,8 +150,9 @@ The -p flag sends a single prompt, runs the agent loop, and prints the result to
146
150
  ### Remote Mode (Browser UI)
147
151
 
148
152
  ```bash
149
- swifty --remote # listens on :18888
150
- swifty --remote :9000 # custom address
153
+ swifty --remote # listens on 127.0.0.1:18888
154
+ swifty --remote :9000 # custom loopback port
155
+ swifty --remote 0.0.0.0:9000 # explicitly expose on all interfaces (no built-in authentication)
151
156
  ```
152
157
 
153
158
  Starts a Koa HTTP server and WebSocket bridge. The bundled React frontend is served at the configured address for browser-based interaction.
@@ -158,6 +163,7 @@ Inside the TUI, these commands are available:
158
163
 
159
164
  | Command | Description |
160
165
  | ----------------------- | ---------------------------------------------------------------------------------- |
166
+ | /login | Configure, save, and activate an LLM provider |
161
167
  | /status | Show current session status (model, tokens, tools, sandbox, memories, skills, MCP) |
162
168
  | /permission mode <mode> | Change permission mode (default, acceptEdits, plan, bypassPermissions) |
163
169
  | /memory | List stored memories |
@@ -186,4 +192,6 @@ Inside the TUI, these commands are available:
186
192
  | Ctrl+V | Paste a clipboard image (Alt+V on Windows) |
187
193
  | Shift+Tab | Cycle permission modes |
188
194
 
189
- Pasting an image saves it as a PNG under `.swifty/file-history/<session-id>/` and inserts a workDir-relative `@` reference into the prompt; on submit it expands into an inline image block like any other `@image` mention. Linux requires `wl-clipboard` (Wayland) or `xclip` (X11).
195
+ Pastes longer than 10 lines or 1,000 characters collapse to `[paste #1 +124 lines]` or `[paste #1 1234 chars]`. Clipboard images appear as `[Image #1]`. Arrow keys move across each placeholder as a unit, and Backspace/Delete remove it as a unit. Placeholders survive dialog switches; submitting restores the full text and image attachments.
196
+
197
+ Pasting an image saves it as a PNG under `.swifty/file-history/<session-id>/`. Its placeholder expands to a workDir-relative `@` reference on submit and loads as an inline image block. Linux requires `wl-clipboard` (Wayland) or `xclip` (X11).
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __swiftyCreateRequire } from "node:module";
3
+ const require = __swiftyCreateRequire(import.meta.url);
4
+ import{r as a}from"./chunk-LZBOXJX2.js";import"./chunk-JGSIQXEN.js";import"./chunk-WX3B64R4.js";import"./chunk-QCKJLO6X.js";import"./chunk-OTVZGPHD.js";import"./chunk-E55KH72M.js";import"./chunk-X3UA5OZL.js";export{a as Agent};
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __swiftyCreateRequire } from "node:module";
3
+ const require = __swiftyCreateRequire(import.meta.url);
4
+ import{a as q}from"./chunk-K5ZK27BX.js";import{a as D}from"./chunk-JGSIQXEN.js";import{g as M}from"./chunk-C3WGLVVZ.js";import{f as L,j as S,k as v,n as $,o as I,p as K,q as F,r as H,t as G}from"./chunk-WX3B64R4.js";import"./chunk-QCKJLO6X.js";import{D as P,I as R,J as N,K as O,L as B,M as _,N as j,R as U,g as C}from"./chunk-OTVZGPHD.js";import"./chunk-E55KH72M.js";import"./chunk-X3UA5OZL.js";function V(o){for(let e=o.length-1;e>=0;e--){let t=o[e];if(t.defer_loading!==!0){t.cache_control={type:"ephemeral"};return}}}function W(o){return o.some(e=>e.defer_loading)}var x=R({module:"llm"});var Y=3e3,J=P.object({max_input_tokens:P.coerce.number()});async function ct(o){if(o.protocol!=="anthropic")return 0;let e=v(o),n=`${o.base_url.replace(/\/+$/,"")}/v1/models/${encodeURIComponent(o.model)}`,s=new AbortController,r=setTimeout(()=>{s.abort()},Y);try{let c=await fetch(n,{method:"GET",headers:{"anthropic-version":"2023-06-01",...e?{"x-api-key":e}:{}},signal:s.signal});if(!c.ok)return 0;let k=await c.json(),{success:m,error:h,data:g}=await C(J,k);if(!m)return x.warn({message:h.message},"model context window schema validation failed"),0;let f=g.max_input_tokens;return Math.max(f,0)}catch(c){return x.error({err:c},"failed to fetch model context window"),0}finally{clearTimeout(r)}}function T(o){return typeof o=="string"?[{type:"text",text:o}]:o.map(e=>{let t=D(e);if(!t||t.type==="tool_reference")throw new Error(`Unsupported user content block: ${U(e,"type","unknown")}`);return t})}function Q(o){let e=[];for(let t of o)if(t.role==="assistant"){let n=[];if(t.thinkingBlocks)for(let r of t.thinkingBlocks)n.push({type:"thinking",thinking:r.thinking,signature:r.signature});let s=typeof t.content=="string"?t.content:N(t.content);if(s&&n.push({type:"text",text:s}),t.toolUses)for(let r of t.toolUses)n.push({type:"tool_use",id:r.toolUseId,name:r.toolName,input:r.arguments});n.length===0&&n.push({type:"text",text:""}),e.push({role:"assistant",content:n})}else if(t.toolResults&&t.toolResults.length>0){let n=[];for(let s of t.toolResults)n.push({type:"tool_result",tool_use_id:s.toolUseId,is_error:s.isError,content:s.contentBlocks?.length?s.contentBlocks:s.content});t.content.length>0&&n.push(...T(t.content)),e.push({role:"user",content:n})}else{if(e.length===0){e.push({role:"user",content:T(t.content)});continue}let n=!1,s=e[e.length-1],r=s.content;s.role==="user"&&(typeof r=="string"||Array.isArray(r)&&r.length>0&&(r[0].type==="text"||r[0].type==="image"))&&(n=!0),n?(typeof r=="string"&&(r=s.content=r.trim().length>0?[{type:"text",text:r}]:[]),r.push(...T(t.content))):e.push({role:"user",content:T(t.content)})}return e}var z=class{client;model;thinking;systemPrompt;maxOutputTokens;constructor(e,t){let n=v(e);if(!n)throw new I("Anthropic API key not found, set ANTHROPIC_API_KEY in .swifty/config.y(a)ml, or via ANTHROPIC_API_KEY env variable.");this.client=new M({apiKey:n,baseURL:e.base_url}),this.model=e.model,this.thinking=e.thinking??L,this.systemPrompt=t,this.maxOutputTokens=S(e)}setSystemPrompt(e){this.systemPrompt=e}setMaxOutputTokens(e){this.maxOutputTokens=e}async*stream(e,t,n){let s=Q(G(e.getMessages())),r=W(t),c=t.map(l=>{let p=l.input_schema,u={name:l.name,description:l.description,input_schema:{type:"object",properties:p.properties,required:p.required??[]}};return l.defer_loading===!0&&(u.defer_loading=!0),u});V(c),X(s);let k={model:this.model,max_tokens:this.maxOutputTokens,stream:!0,system:[{type:"text",text:this.systemPrompt,cache_control:{type:"ephemeral"}}],messages:s,...c.length>0?{tools:c}:{}};k.thinking=this.thinking&&this.maxOutputTokens>1024?{type:"enabled",budget_tokens:Math.min(16384,this.maxOutputTokens-1)}:{type:"disabled"};let m=0,h=0,g=0,f=0,E="end_turn",b="",A="",w=!1;try{let l=this.client.messages.stream(k,{...n?{signal:n}:{},...r?{headers:{"anthropic-beta":q}}:{}}),p="",u="",d="";for await(let i of l)switch(i.type){case"content_block_start":{let a=i.content_block;a.type==="thinking"?(w=!0,b="",A=""):a.type==="tool_use"&&(u=a.id,p=a.name,d="",yield{type:"tool_call_start",toolName:p,toolId:u});break}case"content_block_delta":{let a=i.delta;a.type==="thinking_delta"?(b+=a.thinking,yield{type:"thinking_delta",text:a.thinking}):a.type==="signature_delta"?A+=a.signature:a.type==="text_delta"?yield{type:"text_delta",text:a.text}:a.type==="input_json_delta"&&(d+=a.partial_json,yield{type:"tool_call_delta",text:a.partial_json});break}case"content_block_stop":{if(w&&(yield{type:"thinking_complete",thinking:b,signature:A},w=!1),p){let a={};if(d)try{let y=JSON.parse(d);a=O(y)?B(y):{}}catch(y){x.error({err:y},"llm operation failed"),a={}}yield{type:"tool_call_complete",toolId:u,toolName:p,arguments:a},p="",u="",d=""}break}case"message_delta":{i.delta.stop_reason&&(E=i.delta.stop_reason),i.usage.output_tokens&&(h=i.usage.output_tokens,i.usage.input_tokens&&(m=i.usage.input_tokens),i.usage.cache_read_input_tokens&&(g=i.usage.cache_read_input_tokens),i.usage.cache_creation_input_tokens&&(f=i.usage.cache_creation_input_tokens));break}case"message_start":{m=i.message.usage.input_tokens,h=i.message.usage.output_tokens,g=i.message.usage.cache_read_input_tokens??0,f=i.message.usage.cache_creation_input_tokens??0;break}}yield{type:"stream_end",stopReason:E,usage:{inputTokens:m,outputTokens:h,cacheReadInputTokens:g,cacheCreationInputTokens:f}}}catch(l){throw x.error({err:l},"llm operation failed"),Z(l)}}};function X(o){for(let e=o.length-1;e>=0;e--){if(o[e].role!=="user")continue;let t=o[e].content;if(typeof t=="string"&&t.length===0||Array.isArray(t)&&t.length===0)return;typeof t=="string"&&(t=o[e].content=[{type:"text",text:t}]);let n=t[t.length-1];for(let s=t.length-1;s>=0;s--)if(t[s].type!=="image"){n=t[s];break}Reflect.set(n,"cache_control",{type:"ephemeral"});return}}function Z(o){if(o instanceof M.APIError){if(o.status===413||/prompts?\s+too\s+long/i.test(o.message))return new H(`Prompt too long: ${o.message}`);if(o.status===401)return new I(`Invalid API key: ${o.message}`);if(o.status===429){let e=o.headers,t=e instanceof Headers?e.get("retry-after"):void 0,n="Rate Limited";if(t){let s=Number.parseInt(_(t));Number.isNaN(s)?n+=", please wait.":n+=`, retry after ${_(s)}s.`}else n+=", please wait.";return new K(n,t?_(t):void 0)}return new $(`Anthropic API error (${_(o.status)}): ${o.message}`)}return new F(`Network error: ${j(o)}`)}export{z as AnthropicClient,Q as buildAnthropicMessages,ct as fetchModelContextWindow,X as markLastUserTailForCache,V as markToolsForCache,W as needsToolSearchBeta};
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __swiftyCreateRequire } from "node:module";
3
+ const require = __swiftyCreateRequire(import.meta.url);
4
+ import{c as a,d as b,e as c,f as d,g as e,h as f}from"./chunk-D34FUVGU.js";import"./chunk-QCKJLO6X.js";import"./chunk-OTVZGPHD.js";import"./chunk-E55KH72M.js";import"./chunk-X3UA5OZL.js";export{b as PathSandbox,f as PermissionChecker,d as RuleEngine,c as evaluateRules,a as extractContent,e as isSafeCommand};