@swifty.js/swifty 0.0.21 → 0.0.22
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/dist/{agent-ZCMBUWLZ.js → agent-5T7KNC7V.js} +1 -1
- package/dist/{anthropic-4ZVG7AMA.js → anthropic-P2R4GW6F.js} +1 -1
- package/dist/{chunk-Y5WGBAGP.js → chunk-HJIGA37J.js} +1 -1
- package/dist/{chunk-DDBH5AEN.js → chunk-L73IHJF4.js} +53 -53
- package/dist/{chunk-S6ZADC7C.js → chunk-NEAR6YPZ.js} +1 -1
- package/dist/{chunk-MUPVOATV.js → chunk-NLNH3IRT.js} +1 -1
- package/dist/{chunk-6E6UA7MT.js → chunk-YQQVB6VB.js} +9 -8
- package/dist/lib/agent-2AGRYN3R.js +9 -0
- package/dist/lib/anthropic-GFWP3ORB.js +22 -0
- package/dist/lib/bwrap-QRGPUP4J.js +6 -0
- package/dist/lib/checker-IIXJXQCB.js +19 -0
- package/dist/lib/chunk-6GOWRPYS.js +339 -0
- package/dist/lib/chunk-7URDLWQN.js +426 -0
- package/dist/lib/chunk-C7IHCJZ3.js +849 -0
- package/dist/lib/chunk-EJLGB2EJ.js +377 -0
- package/dist/lib/chunk-GHF2PSEW.js +8 -0
- package/dist/lib/chunk-GNBXECZN.js +243 -0
- package/dist/lib/chunk-HK2Z6WP4.js +223 -0
- package/dist/lib/chunk-LUEP4JMF.js +549 -0
- package/dist/lib/chunk-ORSYNBMM.js +38 -0
- package/dist/lib/chunk-RR2CZ6CY.js +598 -0
- package/dist/lib/chunk-UHVO63Y7.js +1246 -0
- package/dist/lib/chunk-UMFNTXKA.js +88 -0
- package/dist/lib/chunk-VUD72RTY.js +39 -0
- package/dist/lib/glob.wasm +0 -0
- package/dist/lib/index.d.ts +5350 -0
- package/dist/lib/index.js +12002 -0
- package/dist/lib/openai-HXRMPNB7.js +15 -0
- package/dist/lib/seatbelt-FT5IY73W.js +6 -0
- package/dist/lib/tool-filter-VF7TZRE5.js +19 -0
- package/dist/main.js +225 -225
- package/dist/{openai-HXD52MZB.js → openai-TVUUHRG7.js} +1 -1
- package/dist/{server-VMHWEO2Y.js → server-ZTLHJWEQ.js} +14 -14
- package/package.json +14 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __swiftyCreateRequire } from "node:module";
|
|
3
3
|
const require = __swiftyCreateRequire(import.meta.url);
|
|
4
|
-
import{b as L,c as D,d as O,f as U,l as W,m as j,n as Y}from"./chunk-
|
|
4
|
+
import{b as L,c as D,d as O,f as U,l as W,m as j,n as Y}from"./chunk-YQQVB6VB.js";import{a as P,e as N,g as M}from"./chunk-FZPTNGTU.js";import{I as f,K as _,M as C,N as R,O as A,P as F,S as E}from"./chunk-LX2LK3TF.js";import{readFile as xe}from"fs/promises";function T(r){return r?Math.floor(r.length/3.5):0}function B(r,e){if(e<=0||!r||T(r)<=e)return r;let t=Math.floor(e*3.5);return t<=0||t>=r.length?r:r.slice(0,t)+`
|
|
5
5
|
\u2026 (content truncated)`}var b=class{files=new Map;skills=new Map;recordFileRead(e,t){this.files.set(e,{path:e,content:t,timestamp:Date.now()})}recordSkillInvocation(e,t){this.skills.set(e,{name:e,body:t,timestamp:Date.now()})}snapshotFiles(e=5){return[...this.files.values()].sort((n,s)=>s.timestamp-n.timestamp).slice(0,e)}snapshotSkills(){return[...this.skills.values()].sort((e,t)=>t.timestamp-e.timestamp)}buildRecoveryAttachment(e){let t=[],n=this.snapshotFiles();if(n.length>0){t.push(`## Recently read files
|
|
6
6
|
`),t.push(`These snapshots are what the file-reading tool last returned. Re-open with the tool if you need the current bytes.
|
|
7
7
|
`);for(let o of n){let i=B(o.content,5e3),l=new Date(o.timestamp).toISOString().replace(/\.\d{3}Z$/,"Z");t.push(`### ${o.path} (read ${l})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __swiftyCreateRequire } from "node:module";
|
|
3
3
|
const require = __swiftyCreateRequire(import.meta.url);
|
|
4
|
-
import{a as x}from"./chunk-7MHXMDYC.js";import{C as o,I as S,b as p,c as u}from"./chunk-LX2LK3TF.js";import{existsSync as E,readFileSync as $}from"fs";import{homedir as I}from"os";import{join as m}from"path";function l(e){return!!e._zod}function f(e,t){return l(e)?p(e,t):e.safeParse(t)}async function ee(e,t){return l(e)?await u(e,t):await e.safeParseAsync(t)}function oe(e){if(!e)return;let t;if(l(e)?t=e._zod?.def?.shape:t=e.shape,!!t){if(typeof t=="function")try{return t()}catch{return}return t}}function ne(e){if(l(e)){let s=e._zod?.def;if(s){if(s.value!==void 0)return s.value;if(Array.isArray(s.values)&&s.values.length>0)return s.values[0]}}let n=e._def;if(n){if(n.value!==void 0)return n.value;if(Array.isArray(n.values)&&n.values.length>0)return n.values[0]}let r=e.value;if(r!==void 0)return r}var g=S({module:"config"}),A={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY","openai-compat":"OPENAI_API_KEY"};function N(e){return _.has(e)}var _=new Set(Object.keys(A)),d=class extends Error{constructor(t){super(t),this.name="ConfigError"}},P=o.object({name:o.string(),protocol:o.enum(["anthropic","openai","openai-compat"]),base_url:o.string(),model:o.string(),api_key:o.string().optional(),thinking:o.boolean().optional(),context_window:o.coerce.number().optional(),max_output_tokens:o.coerce.number().optional()}),V=[["1m",1e6],["gpt-4.1",1e6],["gpt-4o",128e3],["gpt-4-turbo",128e3],["o1",2e5],["o3",2e5],["o4",2e5],["gpt-3.5",16385],["claude",2e5]];function j(e){let t=e.toLowerCase();for(let[n,r]of V)if(t.includes(n))return r;return t.includes("claude")?2e5:128e3}function le(e){return e.context_window&&e.context_window>0?e.context_window:j(e.model)}var w=new Map;async function pe(e,t){if(e.context_window&&e.context_window>0)return e.context_window;if(e.protocol==="anthropic"){let n=`${e.name}-${e.model}`,r=w.get(n);if(r===void 0){try{r=await(t??(await import("./anthropic-
|
|
4
|
+
import{a as x}from"./chunk-7MHXMDYC.js";import{C as o,I as S,b as p,c as u}from"./chunk-LX2LK3TF.js";import{existsSync as E,readFileSync as $}from"fs";import{homedir as I}from"os";import{join as m}from"path";function l(e){return!!e._zod}function f(e,t){return l(e)?p(e,t):e.safeParse(t)}async function ee(e,t){return l(e)?await u(e,t):await e.safeParseAsync(t)}function oe(e){if(!e)return;let t;if(l(e)?t=e._zod?.def?.shape:t=e.shape,!!t){if(typeof t=="function")try{return t()}catch{return}return t}}function ne(e){if(l(e)){let s=e._zod?.def;if(s){if(s.value!==void 0)return s.value;if(Array.isArray(s.values)&&s.values.length>0)return s.values[0]}}let n=e._def;if(n){if(n.value!==void 0)return n.value;if(Array.isArray(n.values)&&n.values.length>0)return n.values[0]}let r=e.value;if(r!==void 0)return r}var g=S({module:"config"}),A={anthropic:"ANTHROPIC_API_KEY",openai:"OPENAI_API_KEY","openai-compat":"OPENAI_API_KEY"};function N(e){return _.has(e)}var _=new Set(Object.keys(A)),d=class extends Error{constructor(t){super(t),this.name="ConfigError"}},P=o.object({name:o.string(),protocol:o.enum(["anthropic","openai","openai-compat"]),base_url:o.string(),model:o.string(),api_key:o.string().optional(),thinking:o.boolean().optional(),context_window:o.coerce.number().optional(),max_output_tokens:o.coerce.number().optional()}),V=[["1m",1e6],["gpt-4.1",1e6],["gpt-4o",128e3],["gpt-4-turbo",128e3],["o1",2e5],["o3",2e5],["o4",2e5],["gpt-3.5",16385],["claude",2e5]];function j(e){let t=e.toLowerCase();for(let[n,r]of V)if(t.includes(n))return r;return t.includes("claude")?2e5:128e3}function le(e){return e.context_window&&e.context_window>0?e.context_window:j(e.model)}var w=new Map;async function pe(e,t){if(e.context_window&&e.context_window>0)return e.context_window;if(e.protocol==="anthropic"){let n=`${e.name}-${e.model}`,r=w.get(n);if(r===void 0){try{r=await(t??(await import("./anthropic-P2R4GW6F.js")).fetchModelContextWindow)(e)}catch(i){g.error({err:i},"config operation failed"),r=0}w.set(n,r)}if(r&&r>0)return r}return j(e.model)}function ue(e){return e.max_output_tokens&&e.max_output_tokens>0?e.max_output_tokens:e.thinking?64e3:8192}function me(e){if(e.api_key)return e.api_key;let t=N(e.protocol)?A[e.protocol]:"";return t?process.env[t]??"":""}var O=o.object({name:o.string(),command:o.string().optional(),args:o.array(o.string()).optional(),url:o.string().optional(),transport:o.string().optional(),headers:o.record(o.string(),o.string()).optional(),env:o.record(o.string(),o.string()).optional()}),z=o.object({id:o.string().optional(),event:o.string(),condition:o.string().optional(),action:o.object({type:o.string(),command:o.string().optional(),url:o.string().optional(),method:o.string().optional(),prompt:o.string().optional()}),reject:o.boolean().optional(),once:o.boolean().optional(),async:o.boolean().optional(),on_error:o.string().optional()}),M=o.object({enabled:o.boolean().optional(),auto_allow:o.boolean().optional(),network_enabled:o.boolean().optional()}),T=o.looseObject({providers:o.array(P),permission_mode:o.string().optional(),mcp_servers:o.array(O).default([]),hooks:o.array(z).default([]),sandbox:M.optional(),enable_coordinator_mode:o.boolean().optional(),enable_fork:o.boolean().optional()});function ge(e){return e.enable_fork!==!1}function Y(e){return typeof e=="object"&&e!==null}function C(e){let t=$(e,"utf-8"),n=x.load(t);if(!Y(n))return g.error({path:e},"invalid yaml"),{providers:[],mcp_servers:[],hooks:[]};let r=f(T,n);if(r.success){let a=r.data;return{providers:a.providers,permission_mode:a.permission_mode,mcp_servers:a.mcp_servers,hooks:a.hooks}}g.error({error:r.error},"config error");let i=[],s,c=[],y=[],v,b=!1,h=!0;if("providers"in n){let a=f(o.array(P),n.providers);a.success&&(i=a.data)}if("permission_mode"in n&&typeof n.permission_mode=="string"&&(s=n.permission_mode),"mcp_servers"in n){let a=f(o.array(O),n.mcp_servers);a.success&&(c=a.data)}if("hooks"in n){let a=f(o.array(z),n.hooks);a.success&&(y=a.data)}if("sandbox"in n){let a=f(M,n.sandbox);a.success&&(v=a.data)}return"enable_coordinator_mode"in n&&(b=!!n.enable_coordinator_mode),"enable_fork"in n&&(h=!!n.enable_fork),{providers:i,permission_mode:s,mcp_servers:c,hooks:y,sandbox:v,enable_coordinator_mode:b,enable_fork:h}}function K(e,t){if(t.providers.length>0&&(e.providers=t.providers),t.permission_mode&&(e.permission_mode=t.permission_mode),t.mcp_servers.length>0){let n=new Map;for(let r=0;r<e.mcp_servers.length;r++){let i=e.mcp_servers[r];n.set(i.name,r)}for(let r of t.mcp_servers){let i=n.get(r.name);i!==void 0?e.mcp_servers[i]=r:(e.mcp_servers.push(r),n.set(r.name,e.mcp_servers.length-1))}}return e.hooks=[...e.hooks,...t.hooks],t.sandbox&&(e.sandbox={...e.sandbox,...t.sandbox}),t.enable_coordinator_mode&&(e.enable_coordinator_mode=!0),t.enable_fork!==void 0&&(e.enable_fork=t.enable_fork),e}function k(e){if(e.providers.length===0)throw new d("At least one provider MUST be configured.");let t=["name","protocol","base_url","model"];for(let n=0;n<e.providers.length;n++){let r=e.providers[n],i={name:r.name,protocol:r.protocol,base_url:r.base_url,model:r.model},s=t.filter(c=>!(c in i));if(s.length>0)throw new d(`Provider #${String(n+1)}: missing fields: ${s.join(", ")}`);if(!_.has(r.protocol))throw new d(`Provider #${String(n+1)}: invalid protocol '${r.protocol}', MUST be one of: ${Array.from(_).join(", ")}`)}}function _e(e){if(e){let s=C(e);return k(s),s}let t=process.cwd(),n=I(),r=[m(n,".swifty","config.yaml"),m(t,".swifty","config.yaml"),m(t,".swifty","config.local.yaml")],i=null;for(let s of r){if(!E(s))continue;let c=C(s);i?i=K(i,c):i=c}if(!i)throw new d("No config file found, expected .swifty/config.y(a)ml under project or $HOME/.swifty/config.y(a)ml.");return k(i),i}export{f as a,ee as b,oe as c,ne as d,le as e,pe as f,ue as g,me as h,ge as i,_e as j};
|
|
@@ -6,10 +6,11 @@ ${e}
|
|
|
6
6
|
</system-reminder>`})}hasReminderContaining(e){return this.history.some(o=>o.role==="user"&&p(o.content).includes(e))}injectLongTermMemory(e,o,s=""){if(this.longTermMemoryInjected)return;let n=[];if(e&&n.push(`# SWIFTY.md
|
|
7
7
|
Codebase and user instructions are shown below. Be sure to adhere to these instructions. IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
`+o),s&&n.push(`#
|
|
9
|
+
${e}}`),o&&n.push(`# Auto Memory
|
|
10
|
+
`+o),s&&n.push(`# Available Skills
|
|
11
11
|
`+s),n.length===0)return;let r=new Date().toISOString().split("T")[0];n.push(`# Current Date
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
Today's date is ${r}.`);let a=`
|
|
13
14
|
<system-reminder>
|
|
14
15
|
As you answer the user's questions, you can use the following context:
|
|
15
16
|
|
|
@@ -18,14 +19,14 @@ ${n.join(`
|
|
|
18
19
|
`)}
|
|
19
20
|
|
|
20
21
|
IMPORTANT: this context may or may not be relevant to your tasks. You should not respond to this context unless it is highly relevant to your task.
|
|
21
|
-
</system-reminder>`;this.history.unshift({role:"user",content:a}),this.longTermMemoryInjected=!0}len(){return this.history.length}truncateTo(e){e<0&&(e=0),!(e>this.history.length)&&(this.history=this.history.slice(0,e))}getMessages(){return[...this.history]}replaceWithCompacted(e,o){this.history=[{role:"user",content:e},...o],this.longTermMemoryInjected=!1,this.clearUsageAnchor()}recordUsageAnchor(e,o,s,n){let r=e+s+n+o;r<=0||(this.baselineTokens=r,this._anchorCount=this.history.length)}clearUsageAnchor(){this.baselineTokens=0,this._anchorCount=0}usageAnchorState(){return this.baselineTokens<=0?null:{baselineTokens:this.baselineTokens,anchorCount:this._anchorCount}}};import{randomBytes as z}from"crypto";import{readFileSync as
|
|
22
|
-
`;H(n,r,{flag:"a",encoding:"utf-8"})}function Ee(t,e,o){Q(t,e,{role:"system",content:JSON.stringify(o),timestamp:Math.floor(Date.now()/1e3),type:S})}function Ne(t,e){let o=y(R(t),`${e}.jsonl`);if(!
|
|
22
|
+
</system-reminder>`;this.history.unshift({role:"user",content:a}),this.longTermMemoryInjected=!0}len(){return this.history.length}truncateTo(e){e<0&&(e=0),!(e>this.history.length)&&(this.history=this.history.slice(0,e))}reset(){this.history=[],this.longTermMemoryInjected=!1,this.clearUsageAnchor()}getMessages(){return[...this.history]}replaceWithCompacted(e,o){this.history=[{role:"user",content:e},...o],this.longTermMemoryInjected=!1,this.clearUsageAnchor()}recordUsageAnchor(e,o,s,n){let r=e+s+n+o;r<=0||(this.baselineTokens=r,this._anchorCount=this.history.length)}clearUsageAnchor(){this.baselineTokens=0,this._anchorCount=0}usageAnchorState(){return this.baselineTokens<=0?null:{baselineTokens:this.baselineTokens,anchorCount:this._anchorCount}}};import{randomBytes as z}from"crypto";import{readFileSync as A,writeFileSync as H,readdirSync as W,mkdirSync as J,statSync as X,existsSync as I,unlinkSync as Ce,rmSync as xe}from"fs";import{join as y}from"path";var S="compact_boundary";var E=i.object({tool_use_id:i.string(),tool_name:i.string(),arguments:i.record(i.string(),i.unknown()).optional()}),k=i.union([i.string(),i.array(i.record(i.string(),i.unknown()))]),N=i.object({tool_use_id:i.string(),content:k,is_error:i.boolean().optional()}),B=i.object({role:i.string(),content:k.default(""),timestamp:i.number(),type:i.string().optional(),tool_uses:i.array(E).optional(),tool_results:i.array(N).optional()}),G=i.object({role:i.string(),content:k,tool_uses:i.array(E).optional(),tool_results:i.array(N).optional()});function O(t){return(t??[]).map(e=>({tool_use_id:e.toolUseId,tool_name:e.toolName,...e.arguments&&Object.keys(e.arguments).length?{arguments:e.arguments}:{}}))}function L(t){return(t??[]).map(e=>({tool_use_id:e.toolUseId,content:e.content,...e.isError?{is_error:!0}:{}}))}var V=i.object({summary:i.string(),keep:i.array(G)}),b=v({module:"session"});function R(t){return y(t,".swifty","sessions")}function Ae(t,e){return y(R(t),e+".jsonl")}function Ie(){let t=Date.now().toString(36),e=z(4).toString("hex");return`${t}-${e}`}function Q(t,e,o){let s=R(t);J(s,{recursive:!0});let n=y(s,`${e}.jsonl`),r=JSON.stringify(o)+`
|
|
23
|
+
`;H(n,r,{flag:"a",encoding:"utf-8"})}function Ee(t,e,o){Q(t,e,{role:"system",content:JSON.stringify(o),timestamp:Math.floor(Date.now()/1e3),type:S})}function Ne(t,e){let o=y(R(t),`${e}.jsonl`);if(!I(o))return[];let s=[];for(let n of A(o,"utf-8").split(`
|
|
23
24
|
`))if(n.trim())try{let r=JSON.parse(n),{success:l,data:a,error:c}=x(B,r);l?!a.content&&!(a.tool_uses?.length??0)&&!(a.tool_results?.length??0)||s.push(a):b.error({err:c},"session operation failed")}catch(r){b.error({err:r},"session operation failed")}return s}function j(t){return t?.map(e=>({toolUseId:e.tool_use_id,toolName:e.tool_name,arguments:e.arguments}))}function F(t){return t?.map(e=>({toolUseId:e.tool_use_id,content:e.content,isError:e.is_error}))}function Be(t){let e=-1;for(let s=t.length-1;s>=0;s--)if(t[s].type===S){e=s;break}let o=[];if(e>=0){let s=null;try{let n=t[e].content,r=typeof n=="string"?JSON.parse(n):null;s=M(V,r)}catch{s=null}if(s){let n=`This session continues from a previous conversation, which has been compressed due to context limitations. Here is a summary of the earlier messages:
|
|
24
25
|
|
|
25
26
|
`+s.summary;s.keep.length>0&&(n+=`
|
|
26
27
|
|
|
27
|
-
Recent messages have been preserved verbatim.`),o.push({role:"user",content:n});for(let r of s.keep)r.role!=="user"&&r.role!=="assistant"||!r.content&&!(r.tool_uses?.length??0)&&!(r.tool_results?.length??0)||o.push({role:r.role,content:r.content,toolUses:j(r.tool_uses),toolResults:F(r.tool_results)})}for(let n=e+1;n<t.length;n++){let r=t[n];if(r.type===S)continue;let l=P(r);l&&o.push(l)}return o}for(let s of t){let n=P(s);n&&o.push(n)}return o}function P(t){return t.role!=="user"&&t.role!=="assistant"||!t.content&&!(t.tool_uses?.length??0)&&!(t.tool_results?.length??0)?null:{role:t.role,content:t.content,toolUses:j(t.tool_uses),toolResults:F(t.tool_results)}}function Oe(t){let e=R(t);if(!
|
|
28
|
-
`)){if(!d.trim())continue;let m;try{let g=JSON.parse(d);m=M(B,g)}catch(g){b.error({err:g},"session operation failed");continue}u++,!c&&m.role==="user"&&m.content&&(c=p(m.content).slice(0,100))}}catch(d){b.error({err:d},"session operation failed");continue}s.push({id:a,firstMessage:c,messageCount:u,size:l.size,modTime:l.mtime})}return s.sort((n,r)=>r.modTime.getTime()-n.modTime.getTime()),s}var
|
|
28
|
+
Recent messages have been preserved verbatim.`),o.push({role:"user",content:n});for(let r of s.keep)r.role!=="user"&&r.role!=="assistant"||!r.content&&!(r.tool_uses?.length??0)&&!(r.tool_results?.length??0)||o.push({role:r.role,content:r.content,toolUses:j(r.tool_uses),toolResults:F(r.tool_results)})}for(let n=e+1;n<t.length;n++){let r=t[n];if(r.type===S)continue;let l=P(r);l&&o.push(l)}return o}for(let s of t){let n=P(s);n&&o.push(n)}return o}function P(t){return t.role!=="user"&&t.role!=="assistant"||!t.content&&!(t.tool_uses?.length??0)&&!(t.tool_results?.length??0)?null:{role:t.role,content:t.content,toolUses:j(t.tool_uses),toolResults:F(t.tool_results)}}function Oe(t){let e=R(t);if(!I(e))return[];let o=W(e).filter(n=>n.endsWith(".jsonl")),s=[];for(let n of o){let r=y(e,n),l=X(r),a=n.replace(".jsonl",""),c="",u=0;try{for(let d of A(r,"utf-8").split(`
|
|
29
|
+
`)){if(!d.trim())continue;let m;try{let g=JSON.parse(d);m=M(B,g)}catch(g){b.error({err:g},"session operation failed");continue}u++,!c&&m.role==="user"&&m.content&&(c=p(m.content).slice(0,100))}}catch(d){b.error({err:d},"session operation failed");continue}s.push({id:a,firstMessage:c,messageCount:u,size:l.size,modTime:l.mtime})}return s.sort((n,r)=>r.modTime.getTime()-n.modTime.getTime()),s}var $=3,Z=3,ee="[earlier conversation truncated for compaction retry]",te=3.5,oe=1e4,se=5,ne=4e4,re=2,ie=2e4,ae=13e3,le=3e3;function D(t,e,o=!1){return t-Math.min(e,ie)-(o?le:ae)}var q=class{consecutiveFailures=0},ce=7e3;function Y(t){if(typeof t=="string")return t.length;let e=0;for(let o of t)o.type==="text"?e+=U(o,"text").length:o.type==="image"&&(e+=ce);return e}function w(t){let e=0;for(let o of t){if(e+=Y(o.content),o.toolUses&&(e+=JSON.stringify(o.toolUses).length),o.toolResults)for(let s of o.toolResults)e+=Y(s.content);if(o.thinkingBlocks)for(let s of o.thinkingBlocks)e+=s.thinking.length}return Math.ceil(e/te)}function ue(t){return w(t.getMessages())}function C(t){return w([t])}function de(t){return t.role==="user"&&!!t.toolResults&&t.toolResults.length>0}function me(t){let e=0,o=0,s=t.length;for(let n=t.length-1;n>=0;n--){let r=C(t[n]);if(o>0&&e+r>ne||(s=n,e+=r,o++,e>=oe||o>=se))break}return s=he(t,s),s}function he(t,e){if(e<=0||e>=t.length||!de(t[e]))return e;let o=new Set((t[e].toolResults??[]).map(s=>s.toolUseId));for(let s=e-1;s>=0;s--){let n=t[s];if(n.role==="assistant"&&n.toolUses?.some(r=>o.has(r.toolUseId)))return s}return e}function ge(t,e){let o=e??t.usageAnchorState();if(!o)return ue(t);let s=t.getMessages(),n=Math.min(o.anchorCount,s.length);return o.baselineTokens+w(s.slice(n))}async function De(t,e,o,s,n,r,l,a,c=""){let u=ge(t),d=D(o,s),m=D(o,s,!0);if(u<d)return{compacted:!1,message:""};if(!(u>=m)&&n.consecutiveFailures>=$)return{compacted:!1,message:`Auto-compact circuit breaker: ${String($)} consecutive failures`};try{let f=await K(t,e,r,l,a,c);return n.consecutiveFailures=0,f}catch(f){return n.consecutiveFailures++,{compacted:!1,message:`Auto-compact failed: ${_(f)}`}}}async function qe(t,e,o,s,n,r=""){return K(t,e,o,s,n,r)}var fe=`Your task is to create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions.
|
|
29
30
|
This summary should be thorough in capturing technical details, code patterns, and architectural decisions that would be essential for continuing development work without losing context.
|
|
30
31
|
|
|
31
32
|
Before providing your final summary, wrap your analysis in <analysis> tags to organize your thoughts and ensure you've covered all necessary points. In your analysis process:
|
|
@@ -123,4 +124,4 @@ If you need specific details from before compaction (code snippets, error messag
|
|
|
123
124
|
|
|
124
125
|
---
|
|
125
126
|
|
|
126
|
-
${m}`),t.replaceWithCompacted(g,u);let f=u.filter(h=>(h.role==="user"||h.role==="assistant")&&(h.content||(h.toolUses?.length??0)||(h.toolResults?.length??0))).map(h=>({role:h.role,content:h.content,...h.toolUses?.length?{tool_uses:O(h.toolUses)}:{},...h.toolResults?.length?{tool_results:L(h.toolResults)}:{}}));return{compacted:!0,message:`Compacted ${String(c.length)} messages into summary (${String(d.length)} chars), kept ${String(u.length)} recent messages verbatim`,boundary:{summary:d,keep:f}}}export{T as a,O as b,L as c,
|
|
127
|
+
${m}`),t.replaceWithCompacted(g,u);let f=u.filter(h=>(h.role==="user"||h.role==="assistant")&&(h.content||(h.toolUses?.length??0)||(h.toolResults?.length??0))).map(h=>({role:h.role,content:h.content,...h.toolUses?.length?{tool_uses:O(h.toolUses)}:{},...h.toolResults?.length?{tool_results:L(h.toolResults)}:{}}));return{compacted:!0,message:`Compacted ${String(c.length)} messages into summary (${String(d.length)} chars), kept ${String(u.length)} recent messages verbatim`,boundary:{summary:d,keep:f}}}export{T as a,O as b,L as c,Ae as d,Ie as e,Q as f,Ee as g,Ne as h,Be as i,Oe as j,D as k,q as l,De as m,qe as n};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AnthropicClient,
|
|
3
|
+
buildAnthropicMessages,
|
|
4
|
+
fetchModelContextWindow,
|
|
5
|
+
markLastUserTailForCache,
|
|
6
|
+
markToolsForCache,
|
|
7
|
+
needsToolSearchBeta
|
|
8
|
+
} from "./chunk-LUEP4JMF.js";
|
|
9
|
+
import "./chunk-C7IHCJZ3.js";
|
|
10
|
+
import "./chunk-6GOWRPYS.js";
|
|
11
|
+
import "./chunk-UMFNTXKA.js";
|
|
12
|
+
import "./chunk-GNBXECZN.js";
|
|
13
|
+
import "./chunk-EJLGB2EJ.js";
|
|
14
|
+
import "./chunk-GHF2PSEW.js";
|
|
15
|
+
export {
|
|
16
|
+
AnthropicClient,
|
|
17
|
+
buildAnthropicMessages,
|
|
18
|
+
fetchModelContextWindow,
|
|
19
|
+
markLastUserTailForCache,
|
|
20
|
+
markToolsForCache,
|
|
21
|
+
needsToolSearchBeta
|
|
22
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PathSandbox,
|
|
3
|
+
PermissionChecker,
|
|
4
|
+
RuleEngine,
|
|
5
|
+
evaluateRules,
|
|
6
|
+
extractContent,
|
|
7
|
+
isSafeCommand
|
|
8
|
+
} from "./chunk-7URDLWQN.js";
|
|
9
|
+
import "./chunk-GNBXECZN.js";
|
|
10
|
+
import "./chunk-EJLGB2EJ.js";
|
|
11
|
+
import "./chunk-GHF2PSEW.js";
|
|
12
|
+
export {
|
|
13
|
+
PathSandbox,
|
|
14
|
+
PermissionChecker,
|
|
15
|
+
RuleEngine,
|
|
16
|
+
evaluateRules,
|
|
17
|
+
extractContent,
|
|
18
|
+
isSafeCommand
|
|
19
|
+
};
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createChildLogger
|
|
3
|
+
} from "./chunk-EJLGB2EJ.js";
|
|
4
|
+
|
|
5
|
+
// src/config/config.ts
|
|
6
|
+
import { existsSync, readFileSync } from "fs";
|
|
7
|
+
import { homedir } from "os";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
import { safeParse } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
10
|
+
import yaml from "js-yaml";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
var log = createChildLogger({ module: "config" });
|
|
13
|
+
var ENV_KEY_MAP = {
|
|
14
|
+
anthropic: "ANTHROPIC_API_KEY",
|
|
15
|
+
openai: "OPENAI_API_KEY",
|
|
16
|
+
"openai-compat": "OPENAI_API_KEY"
|
|
17
|
+
};
|
|
18
|
+
function isKeyofTypeofEnvKeyMap(k) {
|
|
19
|
+
return VALID_PROTOCOLS.has(k);
|
|
20
|
+
}
|
|
21
|
+
var VALID_PROTOCOLS = new Set(Object.keys(ENV_KEY_MAP));
|
|
22
|
+
var ConfigError = class extends Error {
|
|
23
|
+
constructor(message) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.name = "ConfigError";
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var ProviderConfigSchema = z.object({
|
|
29
|
+
name: z.string(),
|
|
30
|
+
/**
|
|
31
|
+
* enum: ["anthropic", "openai", "openai-compat"]
|
|
32
|
+
*/
|
|
33
|
+
protocol: z.enum(["anthropic", "openai", "openai-compat"]),
|
|
34
|
+
base_url: z.string(),
|
|
35
|
+
model: z.string(),
|
|
36
|
+
api_key: z.string().optional(),
|
|
37
|
+
thinking: z.boolean().optional(),
|
|
38
|
+
context_window: z.coerce.number().optional(),
|
|
39
|
+
max_output_tokens: z.coerce.number().optional()
|
|
40
|
+
});
|
|
41
|
+
var MODEL_CONTEXT_WINDOWS = [
|
|
42
|
+
// 1M-token variants (e.g. "...-1m") come first so they win over the base family.
|
|
43
|
+
["1m", 1e6],
|
|
44
|
+
["gpt-4.1", 1e6],
|
|
45
|
+
["gpt-4o", 128e3],
|
|
46
|
+
["gpt-4-turbo", 128e3],
|
|
47
|
+
["o1", 2e5],
|
|
48
|
+
["o3", 2e5],
|
|
49
|
+
["o4", 2e5],
|
|
50
|
+
["gpt-3.5", 16385],
|
|
51
|
+
["claude", 2e5]
|
|
52
|
+
];
|
|
53
|
+
function lookupModelContextWindow(model) {
|
|
54
|
+
const model_ = model.toLowerCase();
|
|
55
|
+
for (const [m, window] of MODEL_CONTEXT_WINDOWS) {
|
|
56
|
+
if (model_.includes(m)) {
|
|
57
|
+
return window;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return model_.includes("claude") ? 2e5 : 128e3;
|
|
61
|
+
}
|
|
62
|
+
function getContextWindow(p) {
|
|
63
|
+
if (p.context_window && p.context_window > 0) {
|
|
64
|
+
return p.context_window;
|
|
65
|
+
}
|
|
66
|
+
return lookupModelContextWindow(p.model);
|
|
67
|
+
}
|
|
68
|
+
var fetchedWindowCache = /* @__PURE__ */ new Map();
|
|
69
|
+
async function getContextWindowAsync(p, fetcher) {
|
|
70
|
+
if (p.context_window && p.context_window > 0) {
|
|
71
|
+
return p.context_window;
|
|
72
|
+
}
|
|
73
|
+
if (p.protocol === "anthropic") {
|
|
74
|
+
const key = `${p.name}-${p.model}`;
|
|
75
|
+
let fetched = fetchedWindowCache.get(key);
|
|
76
|
+
if (fetched === void 0) {
|
|
77
|
+
try {
|
|
78
|
+
const fn = fetcher ?? (await import("./anthropic-GFWP3ORB.js")).fetchModelContextWindow;
|
|
79
|
+
fetched = await fn(p);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
log.error({ err }, "config operation failed");
|
|
82
|
+
fetched = 0;
|
|
83
|
+
}
|
|
84
|
+
fetchedWindowCache.set(key, fetched);
|
|
85
|
+
}
|
|
86
|
+
if (fetched && fetched > 0) {
|
|
87
|
+
return fetched;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return lookupModelContextWindow(p.model);
|
|
91
|
+
}
|
|
92
|
+
function _resetContextWindowCache() {
|
|
93
|
+
fetchedWindowCache.clear();
|
|
94
|
+
}
|
|
95
|
+
function getMaxOutputTokens(p) {
|
|
96
|
+
if (p.max_output_tokens && p.max_output_tokens > 0) {
|
|
97
|
+
return p.max_output_tokens;
|
|
98
|
+
}
|
|
99
|
+
if (p.thinking) {
|
|
100
|
+
return 64e3;
|
|
101
|
+
}
|
|
102
|
+
return 8192;
|
|
103
|
+
}
|
|
104
|
+
function resolveAPIKey(p) {
|
|
105
|
+
if (p.api_key) {
|
|
106
|
+
return p.api_key;
|
|
107
|
+
}
|
|
108
|
+
const envVar = isKeyofTypeofEnvKeyMap(p.protocol) ? ENV_KEY_MAP[p.protocol] : "";
|
|
109
|
+
if (!envVar) {
|
|
110
|
+
return "";
|
|
111
|
+
}
|
|
112
|
+
return process.env[envVar] ?? "";
|
|
113
|
+
}
|
|
114
|
+
var MCPServerConfigSchema = z.object({
|
|
115
|
+
name: z.string(),
|
|
116
|
+
command: z.string().optional(),
|
|
117
|
+
args: z.array(z.string()).optional(),
|
|
118
|
+
url: z.string().optional(),
|
|
119
|
+
transport: z.string().optional(),
|
|
120
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
121
|
+
env: z.record(z.string(), z.string()).optional()
|
|
122
|
+
});
|
|
123
|
+
var HookConfigSchema = z.object({
|
|
124
|
+
id: z.string().optional(),
|
|
125
|
+
event: z.string(),
|
|
126
|
+
condition: z.string().optional(),
|
|
127
|
+
action: z.object({
|
|
128
|
+
type: z.string(),
|
|
129
|
+
command: z.string().optional(),
|
|
130
|
+
url: z.string().optional(),
|
|
131
|
+
method: z.string().optional(),
|
|
132
|
+
prompt: z.string().optional()
|
|
133
|
+
}),
|
|
134
|
+
reject: z.boolean().optional(),
|
|
135
|
+
once: z.boolean().optional(),
|
|
136
|
+
async: z.boolean().optional(),
|
|
137
|
+
on_error: z.string().optional()
|
|
138
|
+
});
|
|
139
|
+
var SandboxYamlConfigSchema = z.object({
|
|
140
|
+
enabled: z.boolean().optional(),
|
|
141
|
+
auto_allow: z.boolean().optional(),
|
|
142
|
+
network_enabled: z.boolean().optional()
|
|
143
|
+
});
|
|
144
|
+
var AppConfigSchema = z.looseObject({
|
|
145
|
+
providers: z.array(ProviderConfigSchema),
|
|
146
|
+
permission_mode: z.string().optional(),
|
|
147
|
+
mcp_servers: z.array(MCPServerConfigSchema).default([]),
|
|
148
|
+
hooks: z.array(HookConfigSchema).default([]),
|
|
149
|
+
sandbox: SandboxYamlConfigSchema.optional(),
|
|
150
|
+
enable_coordinator_mode: z.boolean().optional(),
|
|
151
|
+
/**
|
|
152
|
+
* Whether to fork when subagent_type is omitted. Enabled by default, so this
|
|
153
|
+
* field is left as undefined to represent "not specified in config". Using a
|
|
154
|
+
* concrete boolean would make it impossible to distinguish "not set" from
|
|
155
|
+
* "explicitly false", and the latter could never be turned back off.
|
|
156
|
+
*/
|
|
157
|
+
enable_fork: z.boolean().optional()
|
|
158
|
+
});
|
|
159
|
+
function forkEnabled(cfg) {
|
|
160
|
+
return cfg.enable_fork !== false;
|
|
161
|
+
}
|
|
162
|
+
function isRecord(value) {
|
|
163
|
+
return typeof value === "object" && value !== null;
|
|
164
|
+
}
|
|
165
|
+
function loadSingleFile(path) {
|
|
166
|
+
const data = readFileSync(path, "utf-8");
|
|
167
|
+
const raw = yaml.load(data);
|
|
168
|
+
if (!isRecord(raw)) {
|
|
169
|
+
log.error({ path }, "invalid yaml");
|
|
170
|
+
return { providers: [], mcp_servers: [], hooks: [] };
|
|
171
|
+
}
|
|
172
|
+
const parsed = safeParse(AppConfigSchema, raw);
|
|
173
|
+
if (parsed.success) {
|
|
174
|
+
const data2 = parsed.data;
|
|
175
|
+
return {
|
|
176
|
+
providers: data2.providers,
|
|
177
|
+
permission_mode: data2.permission_mode,
|
|
178
|
+
mcp_servers: data2.mcp_servers,
|
|
179
|
+
hooks: data2.hooks
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
log.error({ error: parsed.error }, "config error");
|
|
183
|
+
let providers = [];
|
|
184
|
+
let permissionMode;
|
|
185
|
+
let mcpServers = [];
|
|
186
|
+
let hooks = [];
|
|
187
|
+
let sandbox = void 0;
|
|
188
|
+
let enableCoordinatorMode = false;
|
|
189
|
+
let enableFork = true;
|
|
190
|
+
if ("providers" in raw) {
|
|
191
|
+
const parsed2 = safeParse(z.array(ProviderConfigSchema), raw.providers);
|
|
192
|
+
if (parsed2.success) {
|
|
193
|
+
providers = parsed2.data;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if ("permission_mode" in raw && typeof raw.permission_mode === "string") {
|
|
197
|
+
permissionMode = raw.permission_mode;
|
|
198
|
+
}
|
|
199
|
+
if ("mcp_servers" in raw) {
|
|
200
|
+
const parsed2 = safeParse(z.array(MCPServerConfigSchema), raw.mcp_servers);
|
|
201
|
+
if (parsed2.success) {
|
|
202
|
+
mcpServers = parsed2.data;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if ("hooks" in raw) {
|
|
206
|
+
const parsed2 = safeParse(z.array(HookConfigSchema), raw.hooks);
|
|
207
|
+
if (parsed2.success) {
|
|
208
|
+
hooks = parsed2.data;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if ("sandbox" in raw) {
|
|
212
|
+
const parsed2 = safeParse(SandboxYamlConfigSchema, raw.sandbox);
|
|
213
|
+
if (parsed2.success) {
|
|
214
|
+
sandbox = parsed2.data;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if ("enable_coordinator_mode" in raw) {
|
|
218
|
+
enableCoordinatorMode = Boolean(raw.enable_coordinator_mode);
|
|
219
|
+
}
|
|
220
|
+
if ("enable_fork" in raw) {
|
|
221
|
+
enableFork = Boolean(raw.enable_fork);
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
providers,
|
|
225
|
+
permission_mode: permissionMode,
|
|
226
|
+
mcp_servers: mcpServers,
|
|
227
|
+
hooks,
|
|
228
|
+
sandbox,
|
|
229
|
+
enable_coordinator_mode: enableCoordinatorMode,
|
|
230
|
+
enable_fork: enableFork
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function mergeConfig(base, override) {
|
|
234
|
+
if (override.providers.length > 0) {
|
|
235
|
+
base.providers = override.providers;
|
|
236
|
+
}
|
|
237
|
+
if (override.permission_mode) {
|
|
238
|
+
base.permission_mode = override.permission_mode;
|
|
239
|
+
}
|
|
240
|
+
if (override.mcp_servers.length > 0) {
|
|
241
|
+
const mcpToIdx = /* @__PURE__ */ new Map();
|
|
242
|
+
for (let i = 0; i < base.mcp_servers.length; i++) {
|
|
243
|
+
const mcp = base.mcp_servers[i];
|
|
244
|
+
mcpToIdx.set(mcp.name, i);
|
|
245
|
+
}
|
|
246
|
+
for (const s of override.mcp_servers) {
|
|
247
|
+
const idx = mcpToIdx.get(s.name);
|
|
248
|
+
if (idx !== void 0) {
|
|
249
|
+
base.mcp_servers[idx] = s;
|
|
250
|
+
} else {
|
|
251
|
+
base.mcp_servers.push(s);
|
|
252
|
+
mcpToIdx.set(s.name, base.mcp_servers.length - 1);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
base.hooks = [...base.hooks, ...override.hooks];
|
|
257
|
+
if (override.sandbox) {
|
|
258
|
+
base.sandbox = { ...base.sandbox, ...override.sandbox };
|
|
259
|
+
}
|
|
260
|
+
if (override.enable_coordinator_mode) {
|
|
261
|
+
base.enable_coordinator_mode = true;
|
|
262
|
+
}
|
|
263
|
+
if (override.enable_fork !== void 0) {
|
|
264
|
+
base.enable_fork = override.enable_fork;
|
|
265
|
+
}
|
|
266
|
+
return base;
|
|
267
|
+
}
|
|
268
|
+
function validateProviders(config) {
|
|
269
|
+
if (config.providers.length === 0) {
|
|
270
|
+
throw new ConfigError("At least one provider MUST be configured.");
|
|
271
|
+
}
|
|
272
|
+
const requiredFields = ["name", "protocol", "base_url", "model"];
|
|
273
|
+
for (let i = 0; i < config.providers.length; i++) {
|
|
274
|
+
const p = config.providers[i];
|
|
275
|
+
const values = {
|
|
276
|
+
name: p.name,
|
|
277
|
+
protocol: p.protocol,
|
|
278
|
+
base_url: p.base_url,
|
|
279
|
+
model: p.model
|
|
280
|
+
};
|
|
281
|
+
const missing = requiredFields.filter((field) => !(field in values));
|
|
282
|
+
if (missing.length > 0) {
|
|
283
|
+
throw new ConfigError(`Provider #${String(i + 1)}: missing fields: ${missing.join(", ")}`);
|
|
284
|
+
}
|
|
285
|
+
if (!VALID_PROTOCOLS.has(p.protocol)) {
|
|
286
|
+
throw new ConfigError(
|
|
287
|
+
`Provider #${String(i + 1)}: invalid protocol '${p.protocol}', MUST be one of: ${Array.from(VALID_PROTOCOLS).join(", ")}`
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function loadConfig(path) {
|
|
293
|
+
if (path) {
|
|
294
|
+
const config = loadSingleFile(path);
|
|
295
|
+
validateProviders(config);
|
|
296
|
+
return config;
|
|
297
|
+
}
|
|
298
|
+
const wd = process.cwd();
|
|
299
|
+
const home = homedir();
|
|
300
|
+
const candidates = [
|
|
301
|
+
join(home, ".swifty", "config.yaml"),
|
|
302
|
+
join(wd, ".swifty", "config.yaml"),
|
|
303
|
+
join(wd, ".swifty", "config.local.yaml")
|
|
304
|
+
];
|
|
305
|
+
let merged = null;
|
|
306
|
+
for (const candidate of candidates) {
|
|
307
|
+
if (!existsSync(candidate)) {
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const layer = loadSingleFile(candidate);
|
|
311
|
+
if (!merged) {
|
|
312
|
+
merged = layer;
|
|
313
|
+
} else {
|
|
314
|
+
merged = mergeConfig(merged, layer);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
if (!merged) {
|
|
318
|
+
throw new ConfigError(
|
|
319
|
+
"No config file found, expected .swifty/config.y(a)ml under project or $HOME/.swifty/config.y(a)ml."
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
validateProviders(merged);
|
|
323
|
+
return merged;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export {
|
|
327
|
+
ConfigError,
|
|
328
|
+
ProviderConfigSchema,
|
|
329
|
+
lookupModelContextWindow,
|
|
330
|
+
getContextWindow,
|
|
331
|
+
getContextWindowAsync,
|
|
332
|
+
_resetContextWindowCache,
|
|
333
|
+
getMaxOutputTokens,
|
|
334
|
+
resolveAPIKey,
|
|
335
|
+
HookConfigSchema,
|
|
336
|
+
forkEnabled,
|
|
337
|
+
mergeConfig,
|
|
338
|
+
loadConfig
|
|
339
|
+
};
|