@opentiny/tiny-robot-kit 0.4.2-alpha.2 → 0.4.2-alpha.4
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/chunk-6JEZBNBO.mjs +5 -0
- package/dist/chunk-ZO2ZONVX.mjs +1 -0
- package/dist/core.d.mts +142 -0
- package/dist/core.d.ts +142 -0
- package/dist/core.js +6 -0
- package/dist/core.mjs +2 -0
- package/dist/index.d.mts +63 -244
- package/dist/index.d.ts +63 -244
- package/dist/index.js +7 -3
- package/dist/index.mjs +3 -3
- package/dist/node.d.mts +14 -0
- package/dist/node.d.ts +14 -0
- package/dist/node.js +1 -0
- package/dist/node.mjs +1 -0
- package/dist/skillPlugin-4pC5SvPk.d.mts +548 -0
- package/dist/skillPlugin-D6X-p9fQ.d.ts +548 -0
- package/dist/types-ChCZ8jKB.d.mts +70 -0
- package/dist/types-ChCZ8jKB.d.ts +70 -0
- package/package.json +30 -6
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{computed as Ce,isProxy as ye,reactive as he,ref as H,toRaw as Me}from"vue";var fe=e=>typeof e=="function"?null:Array.isArray(e)?e.length>0?new Set(e):null:new Set([e]),se=e=>{let t=new Set,o=(n,i)=>{try{n.listener(i)}catch(g){console.error("Error in message state subscriber:",g)}};return{notify:n=>{let i=new Set(Array.isArray(n)?n:[n]),g=e(),f=Array.from(t);for(let l of f){if(l.kinds){let p=!1;for(let T of l.kinds)if(i.has(T)){p=!0;break}if(!p)continue}o(l,g)}},subscribe:(n,i)=>{let g=typeof n=="function"?n:i;if(!g)throw new Error("subscribe listener is required");let f={kinds:fe(n),listener:g};return t.add(f),o(f,e()),()=>{t.delete(f)}}}};var oe=e=>he(e),Q=e=>{let t=ye(e)?Me(e):e;if(Array.isArray(t))return t.map(o=>Q(o));if(t&&typeof t=="object"){let o={};for(let[s,r]of Object.entries(t))o[s]=Q(r);return o}return t},je=()=>{let e=!1,t=H("idle"),o=H(void 0),s=H([]),r=Ce(()=>t.value==="processing"),n=p=>{if(e)throw new Error("Message state adapter is already initialized");t.value=p.requestState,o.value=p.processingState,s.value=p.messages.map(oe),e=!0},i=p=>oe(p),g=()=>{if(!e)throw new Error("Message state adapter is not initialized");return{requestState:t.value,processingState:o.value,messages:Q(s.value),isProcessing:r.value}},f=se(g);return{requestState:t,processingState:o,messages:s,isProcessing:r,initialize:n,getState:g,createMessage:i,mutate:(p,T)=>{if(!e)throw new Error("Message state adapter is not initialized");let v={get requestState(){return t.value},set requestState(F){t.value=F},get processingState(){return o.value},set processingState(F){o.value=F},get messages(){return s.value},set messages(F){s.value=F.map(i)}},N=!1;if(T(v,()=>{N=!0}),N)return;(Array.isArray(p)?p:[p]).includes("messages")&&(s.value=[...s.value]),f.notify(p)},subscribe:f.subscribe}};var X=(e={})=>{let{continueContent:t="Please continue with your previous answer.",...o}=e;return{name:"length",...o,onAfterRequest:async s=>{let{lastChoice:r,appendMessage:n,requestNext:i}=s;return r?.finish_reason==="length"&&(n({role:"user",content:t}),i()),o.onAfterRequest?.(s)}}};var re={listSkillFiles:"list_skill_files",readSkillFile:"read_skill_file"},Se="execute_skill_command",ae=[{type:"function",function:{name:re.listSkillFiles,description:"List files available from the current skills.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Optional skill name. When omitted, files from all current skills are listed."}},additionalProperties:!1}}},{type:"function",function:{name:re.readSkillFile,description:"Read a file from a current skill by skill name and relative path.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Skill name that owns the file."},path:{type:"string",description:"File path relative to the skill root."}},required:["skillName","path"],additionalProperties:!1}}}],Te={type:"function",function:{name:Se,description:"Execute a command in the backend runtime environment for a selected skill.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Name of the current skill that provides the command instructions."},command:{type:"string",description:"Command name to execute in the skill backend runtime."},args:{type:"array",description:"Command arguments passed as argv items.",items:{type:"string"}}},required:["skillName","command","args"],additionalProperties:!1}}},Y=(e,t)=>({skillName:e,id:t.id,path:t.path,kind:t.kind,mimeType:t.mimeType,size:t.size,lastModified:t.lastModified}),Z=e=>{let t=e.function.arguments;if(!t)return{};try{let o=JSON.parse(t);return o&&typeof o=="object"&&!Array.isArray(o)?o:{}}catch{return{}}},ke=e=>Array.isArray(e)&&e.every(t=>typeof t=="string")?e:void 0,Pe=e=>{if(!e.some(s=>!!s.files?.length))return[];let o=s=>{if(!(typeof s!="string"||!s))return e.find(r=>r.name===s)};return[{tool:ae[0],handler:s=>{let r=Z(s),n=o(r.skillName);return{files:(n?[n]:e).flatMap(g=>(g.files??[]).map(f=>Y(g.name,f)))}}},{tool:ae[1],handler:s=>{let r=Z(s),n=o(r.skillName),i=typeof r.path=="string"?r.path:void 0;if(!n)return{error:"skill_not_found"};if(!i)return{error:"file_path_required",skillName:n.name};let g=n.files?.find(f=>f.path===i);return g?g.kind==="binary"?{error:"binary_file_not_readable",file:Y(n.name,g)}:{file:Y(n.name,g),content:g.content}:{error:"file_not_found",skillName:n.name,path:i}}}]},be=(e,t)=>{if(!t||e.length===0)return[];let o=s=>{if(!(typeof s!="string"||!s))return e.find(r=>r.name===s)};return[{tool:Te,handler:async s=>{let r=Z(s),n=o(r.skillName),i=typeof r.command=="string"?r.command:void 0,g=ke(r.args);return n?i?g?t({skill:n,skillName:n.name,command:i,args:g}):{error:"args_required",skillName:n.name,command:i}:{error:"command_required",skillName:n.name}:{error:"skill_not_found"}}}]},ie=(e,t={})=>[...Pe(e),...be(e,t.executeSkillCommand)],le=async e=>{let t=[];for(let o of e){let s=o.instructions?.trim();s&&t.push(`## ${o.name}
|
|
2
|
+
|
|
3
|
+
${s}`)}if(t.length!==0)return{role:"system",content:["Apply these skill instructions when generating the response.",...t].join(`
|
|
4
|
+
|
|
5
|
+
`)}};var ee="__tiny_robot_skill",xe=e=>{let{getSkills:t,executeSkillCommand:o,onSkillsResolved:s,...r}=e;return{name:"skill",...r,provideTools:async n=>n.customContext[ee]?.runtimeTools??[],onTurnStart:async n=>{let i=await t?.(n)??[],g={skills:i,skillNames:i.map(f=>f.name),runtimeTools:ie(i,{executeSkillCommand:o&&(f=>o(f,n))})};return n.setCustomContext({[ee]:g}),await s?.(g,n),r.onTurnStart?.(n)},onBeforeRequest:async n=>{let i=n.customContext[ee];if(i){let g=await le(i.skills);g&&(n.requestBody.messages=[g,...n.requestBody.messages])}return r.onBeforeRequest?.(n)}}};var te=(e={})=>{let t=(o,s)=>!!o.thinking!==s||!!o.open!==s;return{name:"thinking",...e,onCompletionChunk(o){let{choice:s,currentMessage:r,updateCurrentMessage:n}=o,i=s,g=i?.message?.reasoning_content||i?.delta?.reasoning_content,f=typeof g=="string"&&g.trim()!=="";return f?r.state&&typeof r.state=="object"?t(r.state,f)&&n(l=>{l.state.thinking=!0,l.state.open=!0}):n(l=>{l.state={thinking:f,open:f}}):r.state&&typeof r.state=="object"&&"thinking"in r.state&&t(r.state,f)&&n(l=>{l.state.thinking=!1,l.state.open=!1}),e.onCompletionChunk?.(o)},onTurnEnd(o){let{currentTurn:s,mutate:r}=o,n=s.at(-1);return n?.state&&typeof n.state=="object"&&"thinking"in n.state&&t(n.state,!1)&&r("messages",()=>{n.state.thinking=!1,n.state.open=!1}),e.onTurnEnd?.(o)}}};var G=class extends Error{constructor(t){super(t),this.name="AbortError"}};function Re(e){if(e.aborted)return{promise:Promise.reject(new G(String(e.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((r,n)=>{t=()=>{n(new G(String(e.reason??"Aborted")))},e.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(e.removeEventListener("abort",t),t=null)}}}function ge(e,t){let{promise:o,cleanup:s}=Re(t);return Promise.race([e,o]).finally(s)}function me(e,t){let o={};for(let s in e)t.includes(s)&&(o[s]=e[s]);return o}function de(e,t){let o={};for(let s in e)t.includes(s)||(o[s]=e[s]);return o}async function*J(e){if(ce(e)){yield*e;return}let t=await e;if(ce(t)){yield*t;return}yield t}function ce(e){return e&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function"}var ne=e=>typeof e=="object"&&e!==null,ue=e=>ne(e)&&typeof e.index=="number",V=(e,t)=>{for(let[o,s]of Object.entries(t)){let r=e[o];if(r)if(typeof r=="string"&&typeof s=="string")o==="type"&&r||(e[o]=r+s);else if(Array.isArray(r)&&Array.isArray(s))if(r.every(n=>ue(n))&&s.every(n=>ue(n))){let n=new Map(r.map(l=>[l.index,l])),i=new Map(s.map(l=>[l.index,l]));for(let[l,p]of i)if(n.has(l)){let T=n.get(l);n.set(l,V(T,p))}else n.set(l,p);let g=Math.max(...Array.from(n.keys()),-1)+1,f=g>r.length?Array.from({length:g}):r;for(let[l,p]of n)f[l]=p;e[o]=f}else e[o]=[...r,...s];else ne(r)&&ne(s)&&(e[o]=V(r,s));else e[o]=s}return e};function Ae({messages:e,cancelledContent:t,createMessage:o,mutate:s}){let r=[];for(let n=0;n<e.length;n++){let i=e[n];if(i.role==="assistant"&&i.tool_calls&&i.tool_calls.length>0){let g=new Set(i.tool_calls.map(p=>p.id)),f=new Set;for(let p=n+1;p<e.length;p++){let T=e[p];T.role==="tool"&&T.tool_call_id&&g.has(T.tool_call_id)&&f.add(T.tool_call_id)}let l=i.tool_calls.map(p=>p.id).filter(p=>!f.has(p));l.length>0&&r.push({insertAfterIndex:n,missingToolCallIds:l})}}r.length!==0&&s("messages",n=>{for(let i=r.length-1;i>=0;i--){let{insertAfterIndex:g,missingToolCallIds:f}=r[i],l=f.map(p=>o({role:"tool",tool_call_id:p,content:t}));n.messages.splice(g+1,0,...l)}})}var we=e=>{let{getTools:t,beforeCallTools:o,callTool:s,onToolCallStart:r,onToolCallEnd:n,toolCallCancelledContent:i="Tool call cancelled.",toolCallFailedContent:g="Tool call failed.",autoFillMissingToolMessages:f=!1,...l}=e,p=(c,d)=>{var M,y;return c.state??(c.state={}),(M=c.state).toolCall??(M.toolCall={}),(y=c.state.toolCall)[d]??(y[d]={}),c},T=(...c)=>{let[d,{assistantMessage:M,mutate:y}]=c;y("messages",()=>{let A=p(M,d.id);A.state.toolCall[d.id].status="running"}),r?.(...c)},v=(...c)=>{let[d,{status:M,assistantMessage:y,mutate:A}]=c;A("messages",()=>{let I=p(y,d.id);I.state.toolCall[d.id].status=M}),n?.(...c)},N=c=>c.type==="function"&&"function"in c,z=c=>!!(c&&typeof c=="object"&&"tool"in c&&"handler"in c),_=c=>{let d=c;return typeof d.provideTools=="function"?d:void 0},F=(c,d)=>typeof c.disabled=="function"?c.disabled(d):!!c.disabled,L=async(c,d=[])=>{let M=[];for(let k of c.plugins){let a=_(k);!F(k,c)&&a&&M.push(...(await a.provideTools(c)).map(m=>({item:m,source:{type:"toolProvider",pluginName:k.name}})))}let y=[...M,...(await t(c)).map(k=>({item:k,source:{type:"toolPlugin"}}))],A=[],I=new Map,D=new Map,j=new Set,W=k=>{let a=k.function.name;if(j.has(a))throw new Error(`Duplicate tool name "${a}" detected. Tool names must be unique because tool calls are routed by function.name.`);j.add(a)};d.forEach(W);for(let{item:k,source:a}of y){let m=z(k)?k.tool:k;W(m),D.set(m.function.name,a),z(k)?(A.push(k.tool),I.set(k.tool.function.name,k)):A.push(k)}return{tools:A,runtimeToolMap:I,toolSourceMap:D}};return{name:"tool",...l,onTurnStart:c=>{let{getState:d,createMessage:M,mutate:y}=c,A=d().messages;return f&&Ae({messages:A,cancelledContent:i,createMessage:M,mutate:y}),l.onTurnStart?.(c)},onBeforeRequest:async c=>{let{requestBody:d}=c,M=Array.isArray(d.tools)?d.tools:[],{tools:y}=await L(c,M);return y&&y.length>0&&(d.tools=M.length?[...M,...y]:y),l.onBeforeRequest?.(c)},onAfterRequest:async c=>{let{currentMessage:d,lastChoice:M,appendMessage:y,abortSignal:A,setRequestState:I,requestNext:D,mutate:j,createMessage:W}=c;if(M?.finish_reason!=="tool_calls"||!d.tool_calls?.length)return;I("processing","calling-tools"),await o?.(d.tool_calls,{...c,assistantMessage:d});let{runtimeToolMap:k,toolSourceMap:a}=await L(c),m=d.tool_calls.map(async C=>{let S=Math.floor(Date.now()/1e3),x=!1,u=W({role:"tool",tool_call_id:C.id,content:"",metadata:{createdAt:S,updatedAt:S}});y(u);let h=N(C)?C:void 0,E=h?a.get(h.function.name)??{type:"unknown"}:{type:"unknown"},R={...c,assistantMessage:d,toolMessage:u,toolSource:E};T(C,R);try{let b=h?k.get(h.function.name):void 0,P=b&&h?b.handler(h,R):s(C,R),B=J(P);for await(let q of B)j("messages",()=>{if((typeof q=="string"&&q.length>0||q&&typeof q=="object"&&Object.keys(q).length>0)&&(x=!0),typeof q=="string")u.content+=q;else{let U={};try{let w=Array.isArray(u.content)?u.content.map(O=>O.text).join(""):u.content;U=JSON.parse(w||"{}")}catch(w){console.warn(w)}u.content=JSON.stringify(V(U,q))}u.metadata.updatedAt=Math.floor(Date.now()/1e3)});v(C,{...R,status:"success"})}catch(b){let P=b instanceof Error?b:new Error(String(b));if(A.aborted){v(C,{...R,status:"cancelled",error:P});return}console.error(b),x||j("messages",()=>{u.content=g,u.metadata.updatedAt=Math.floor(Date.now()/1e3)}),v(C,{...R,status:"failed",error:P})}});return await Promise.all(m),A.aborted||D(),l.onAfterRequest?.(c)}}};var ve=async()=>{throw new Error("Response provider is not set")},Ee=e=>{let t=[];for(let o of e){if(o.name){let s=t.findIndex(r=>r.name===o.name);s!==-1&&t.splice(s,1)}t.push(o)}return t},K=(e,t)=>typeof e.disabled=="function"?e.disabled(t):!!e.disabled,qe=(e,t={})=>{let{initialMessages:o=[],requestMessageFields:s=[],requestMessageFieldsExclude:r=["state","metadata","loading"],responseProvider:n=ve,onCompletionChunk:i,plugins:g=[]}=t,f={requestState:"idle",processingState:void 0,messages:[...o]};e.initialize(f);let l={currentTurn:[],customContext:{},abortController:null,responseProvider:n},p=[te(),X()],T=Ee(p.concat(g)),v=()=>e.getState(),N=a=>e.createMessage(a),z=e.subscribe,_=e.mutate,F=a=>!a||Object.keys(a).length===0?!1:Object.values(a).some(m=>!!m),L=a=>{let m=a;return s.length&&(m=m.map(C=>me(C,s))),r.length&&(m=m.map(C=>de(C,r))),m},c=a=>{Object.assign(l.customContext,a)},d=(a,m)=>{_("requestState",(C,S)=>{if(C.requestState===a&&C.processingState===m){S();return}C.requestState=a,C.processingState=a==="processing"?m??"requesting":void 0})},M=(...a)=>{let m=a.map(C=>N(C));return _("messages",C=>{C.messages.push(...m)}),l.currentTurn.push(...m),m},y=a=>({getState:v,createMessage:N,mutate:_,abortSignal:a,currentTurn:l.currentTurn,plugins:T,customContext:l.customContext,setRequestState:d,setCustomContext:c});async function A(a,m,C={}){d("processing","requesting");let S={messages:v().messages},x=y(m);for(let b of T.filter(P=>!K(P,x)))await b.onBeforeRequest?.({...x,requestBody:S});S.messages=L(S.messages);let u={role:"assistant",content:"",loading:!0};[u]=M(u),C.setAssistantMessage?.(u);let h=a(S,m),E=J(h),R;for await(let b of E){d("processing","completing"),_("messages",(w,O)=>{u.loading?u.loading=void 0:O()});let P=(b.choices||[]).find(w=>w.index===0)??b.choices?.[0];if(!P)continue;R=P;let B=()=>{_("messages",()=>{u.metadata||(u.metadata={});let{created:w,...O}=b;u.metadata.createdAt=w,u.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(u.metadata,O);let $="delta"in P&&F(P.delta)&&P.delta||"message"in P&&F(P.message)&&P.message||null;if($?.role&&(u.role=$.role),$){let{role:_e,...pe}=$;V(u,pe)}})},q=w=>{_("messages",()=>{w(u)})};if(i){let w=y(m);i({...w,chunk:b,choice:P,currentMessage:u,updateCurrentMessage:q},B)}else B();let U=y(m);for(let w of T.filter(O=>!K(O,U)))w.onCompletionChunk?.({...U,abortSignal:m,chunk:b,choice:P,currentMessage:u,updateCurrentMessage:q})}await I(u,a,m,R,C)}async function I(a,m,C,S,x){let u=!1,h=y(C),E=T.filter(R=>!K(R,h)).map(R=>{if(!R.onAfterRequest)return null;let b=B=>{M(...Array.isArray(B)?B:[B])},P=()=>{u=!0};return R.onAfterRequest({...h,currentMessage:a,lastChoice:S,appendMessage:b,requestNext:P})}).filter(R=>R!==null);await ge(Promise.all(E),C),u&&await A(m,C,x)}async function D(){let a=new AbortController;l.abortController=a,l.customContext={};let m=null,C=S=>{m=S};try{d("processing","requesting");let S=y(a.signal);for(let h of T.filter(E=>!K(E,S)))await h.onTurnStart?.(S);let x=l.responseProvider;try{await A(x,a.signal,{setAssistantMessage:C}),d("completed")}catch(h){if(a.signal.aborted||h instanceof G||h instanceof Error&&h.name==="AbortError")d("aborted");else throw h}let u=y(a.signal);for(let h of T.filter(E=>!K(E,u)))await h.onTurnEnd?.(u)}catch(S){d("error");let x=!1,u=y(a.signal);for(let h of T.filter(E=>!K(E,u)))h.onError&&(x=!0,h.onError({...u,error:S}));if(!x)throw S}finally{let S=y(a.signal);for(let x of T.filter(u=>!K(u,S)))try{x.onFinally?.(S)}catch(u){console.error(`Error in onFinally hook for plugin [${x.name||"Anonymous"}]:`,u)}l.abortController=null,l.currentTurn=[],_("messages",(x,u)=>{m?.loading?m.loading=void 0:u()})}}async function j(a){if(!a||!a.trim()){console.warn("Cannot send empty message");return}if(v().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}let m=Math.floor(Date.now()/1e3);M({role:"user",content:a.trim(),metadata:{createdAt:m,updatedAt:m}}),await D()}async function W(...a){if(v().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}M(...a),await D()}async function k(){l.abortController?.abort(),v().isProcessing&&await new Promise(a=>{let m=()=>{};m=z("requestState",C=>{C.isProcessing||(m(),a())})})}return{getState:v,subscribe:z,sendMessage:j,send:W,abort:k,setResponseProvider(a){l.responseProvider=a}}};export{se as a,je as b,X as c,ie as d,le as e,xe as f,te as g,J as h,V as i,we as j,qe as k};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var i=n=>{let t=n.split("\\").join("/").replace(/^\.\/+/,"");return!t||t.startsWith("/")||t.includes("\0")||t.split("/").some(e=>e===".."||e==="")?null:t},l=n=>[".md",".txt",".json"].includes(s(n)),s=n=>{let t=n.split("/").at(-1)||n,e=t.lastIndexOf(".");return e===-1?"":t.slice(e).toLowerCase()};export{i as a,l as b,s as c};
|
package/dist/core.d.mts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z as MessageStateAdapter, J as RequestState, R as RequestProcessingState, o as ChatMessage, r as CreateMessageEngineOptions, s as MessageEngine, t as MessageEnginePlugin } from './skillPlugin-4pC5SvPk.mjs';
|
|
2
|
+
export { c as AfterRequestContext, d as BasePluginContext, e as BeforeRequestContext, q as CompletionChunkContext, D as DeepReadonly, I as InternalMessageState, v as MessageMutationRecipe, w as MessageRequestBody, y as MessageRuntime, F as MessageUpdateKind, G as MessageUpdateKinds, H as MutateMessageStateFn, P as PublicMessageState, K as ResponseProvider, L as RuntimeTool, S as SkillCommandExecutor, N as SkillCommandRequest, O as SkillCommandResult, Q as SkillPluginOptions, T as SkillPluginState, U as SkillRuntimeToolsOptions, Y as ToolCallContext, Z as ToolProvider, _ as ToolProviderItem, $ as ToolSource, a0 as compileSkillInstructions, a1 as createSkillRuntimeTools, a2 as skillPlugin, a3 as toolPlugin } from './skillPlugin-4pC5SvPk.mjs';
|
|
3
|
+
import { Ref, ComputedRef } from 'vue';
|
|
4
|
+
import { b as SkillFile, S as SkillDefinition } from './types-ChCZ8jKB.mjs';
|
|
5
|
+
export { B as BaseSkillFile, a as BinarySkillFile, c as SkillFileKind, d as SkillFileResource, T as TextSkillFile } from './types-ChCZ8jKB.mjs';
|
|
6
|
+
import 'openai/resources';
|
|
7
|
+
|
|
8
|
+
declare const createNativeMessageAdapter: () => MessageStateAdapter;
|
|
9
|
+
|
|
10
|
+
interface VueMessageStateAdapter extends MessageStateAdapter {
|
|
11
|
+
requestState: Ref<RequestState>;
|
|
12
|
+
processingState: Ref<RequestProcessingState | undefined>;
|
|
13
|
+
messages: Ref<ChatMessage[]>;
|
|
14
|
+
isProcessing: ComputedRef<boolean>;
|
|
15
|
+
}
|
|
16
|
+
declare const createVueMessageAdapter: () => VueMessageStateAdapter;
|
|
17
|
+
|
|
18
|
+
declare const createMessageEngine: (adapter: MessageStateAdapter, options?: CreateMessageEngineOptions) => MessageEngine;
|
|
19
|
+
|
|
20
|
+
declare const lengthPlugin: (options?: MessageEnginePlugin & {
|
|
21
|
+
continueContent?: string;
|
|
22
|
+
}) => MessageEnginePlugin;
|
|
23
|
+
|
|
24
|
+
declare const thinkingPlugin: (options?: MessageEnginePlugin) => MessageEnginePlugin;
|
|
25
|
+
|
|
26
|
+
declare function normalizeToAsyncGenerator<T>(result: T | Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>): AsyncGenerator<T>;
|
|
27
|
+
/**
|
|
28
|
+
* Merge delta data from completion responses
|
|
29
|
+
* Handles string concatenation, object merging, and array merging by index
|
|
30
|
+
*
|
|
31
|
+
* @param target - Target object to merge into
|
|
32
|
+
* @param source - Source object to merge from
|
|
33
|
+
* @returns Merged target object
|
|
34
|
+
*/
|
|
35
|
+
declare const combineDeltaData: (target: Record<string, any>, source: Record<string, any>) => Record<string, any>;
|
|
36
|
+
|
|
37
|
+
type BrowserFile = Pick<File, 'arrayBuffer' | 'lastModified' | 'name' | 'size' | 'text' | 'type'> & {
|
|
38
|
+
webkitRelativePath?: string;
|
|
39
|
+
};
|
|
40
|
+
type BrowserFileHandle = {
|
|
41
|
+
kind: 'file';
|
|
42
|
+
name: string;
|
|
43
|
+
getFile: () => Promise<BrowserFile>;
|
|
44
|
+
};
|
|
45
|
+
type BrowserDirectoryHandle = {
|
|
46
|
+
kind: 'directory';
|
|
47
|
+
name: string;
|
|
48
|
+
entries: () => AsyncIterable<[string, BrowserFileHandle | BrowserDirectoryHandle]>;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Browser FileList 适配器,用于读取文件选择器选中的 skill 目录。
|
|
52
|
+
*/
|
|
53
|
+
declare const loadSkillFilesFromFileList: (fileList: ArrayLike<BrowserFile>) => Promise<SkillFile[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Browser FileSystemDirectoryHandle 适配器,用于读取 window.showDirectoryPicker() 选中的目录。
|
|
56
|
+
*/
|
|
57
|
+
declare const loadSkillFilesFromDirectoryHandle: (directoryHandle: BrowserDirectoryHandle) => Promise<SkillFile[]>;
|
|
58
|
+
|
|
59
|
+
interface SkillLoaderResult {
|
|
60
|
+
/**
|
|
61
|
+
* 从源文件解析出的 skill 定义。
|
|
62
|
+
*/
|
|
63
|
+
skill: SkillDefinition;
|
|
64
|
+
/**
|
|
65
|
+
* 非致命的加载警告。
|
|
66
|
+
*/
|
|
67
|
+
warnings: Array<{
|
|
68
|
+
/**
|
|
69
|
+
* 用于 UI 和日志分类的警告编码。
|
|
70
|
+
*/
|
|
71
|
+
code: string;
|
|
72
|
+
/**
|
|
73
|
+
* 人类可读的警告信息。
|
|
74
|
+
*/
|
|
75
|
+
message: string;
|
|
76
|
+
/**
|
|
77
|
+
* 关联的 skill 文件路径。
|
|
78
|
+
*/
|
|
79
|
+
path?: string;
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
82
|
+
interface SkillLoaderOptions {
|
|
83
|
+
/**
|
|
84
|
+
* skill 入口文件名。
|
|
85
|
+
*/
|
|
86
|
+
entryFile?: string;
|
|
87
|
+
/**
|
|
88
|
+
* 启用后,警告会直接抛出为错误。
|
|
89
|
+
*/
|
|
90
|
+
strict?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 将标准化后的 skill 文件转换为 SkillDefinition。
|
|
94
|
+
*
|
|
95
|
+
* 文件来源适配器负责提供 SkillFile[];该 loader 负责解析入口文件和资源文件。
|
|
96
|
+
*/
|
|
97
|
+
declare class SkillLoader {
|
|
98
|
+
private entryFile;
|
|
99
|
+
private strict;
|
|
100
|
+
constructor(options?: SkillLoaderOptions);
|
|
101
|
+
load(files: SkillFile[]): SkillLoaderResult;
|
|
102
|
+
private normalizeFiles;
|
|
103
|
+
private handleWarning;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type SkillManagerOptions = {
|
|
107
|
+
/**
|
|
108
|
+
* 初始化时写入 manager 的 skill 列表。
|
|
109
|
+
*/
|
|
110
|
+
skills?: SkillDefinition[];
|
|
111
|
+
/**
|
|
112
|
+
* 初始化时选中的 skill 名称。
|
|
113
|
+
*/
|
|
114
|
+
selectedSkillNames?: string[];
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* 管理 skill 集合和选择状态。
|
|
118
|
+
*
|
|
119
|
+
* manager 不编译 prompt 或 tools,也不接入 message 生命周期。
|
|
120
|
+
*/
|
|
121
|
+
declare class SkillManager {
|
|
122
|
+
private skills;
|
|
123
|
+
private selectedSkillNames;
|
|
124
|
+
constructor(options?: SkillManagerOptions);
|
|
125
|
+
set(skill: SkillDefinition): SkillDefinition;
|
|
126
|
+
remove(name: string): SkillDefinition | undefined;
|
|
127
|
+
clear(): void;
|
|
128
|
+
get(name: string): SkillDefinition | undefined;
|
|
129
|
+
has(name: string): boolean;
|
|
130
|
+
list(): SkillDefinition[];
|
|
131
|
+
select(names: string | string[]): void;
|
|
132
|
+
unselect(names: string | string[]): void;
|
|
133
|
+
getSelectedSkillNames(): string[];
|
|
134
|
+
getSelectedSkills(): SkillDefinition[];
|
|
135
|
+
import(files: SkillFile[], options?: SkillLoaderOptions): SkillLoaderResult;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
declare const normalizeSkillPath: (path: string) => string | null;
|
|
139
|
+
declare const isTextSkillFilePath: (path: string) => boolean;
|
|
140
|
+
declare const getExtension: (path: string) => string;
|
|
141
|
+
|
|
142
|
+
export { type BrowserDirectoryHandle, type BrowserFile, type BrowserFileHandle, ChatMessage, CreateMessageEngineOptions, MessageEngine, MessageEnginePlugin, MessageStateAdapter, RequestProcessingState, RequestState, SkillDefinition, SkillFile, SkillLoader, type SkillLoaderOptions, type SkillLoaderResult, SkillManager, type SkillManagerOptions, type VueMessageStateAdapter, combineDeltaData, createMessageEngine, createNativeMessageAdapter, createVueMessageAdapter, getExtension, isTextSkillFilePath, lengthPlugin, loadSkillFilesFromDirectoryHandle, loadSkillFilesFromFileList, normalizeSkillPath, normalizeToAsyncGenerator, thinkingPlugin };
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z as MessageStateAdapter, J as RequestState, R as RequestProcessingState, o as ChatMessage, r as CreateMessageEngineOptions, s as MessageEngine, t as MessageEnginePlugin } from './skillPlugin-D6X-p9fQ.js';
|
|
2
|
+
export { c as AfterRequestContext, d as BasePluginContext, e as BeforeRequestContext, q as CompletionChunkContext, D as DeepReadonly, I as InternalMessageState, v as MessageMutationRecipe, w as MessageRequestBody, y as MessageRuntime, F as MessageUpdateKind, G as MessageUpdateKinds, H as MutateMessageStateFn, P as PublicMessageState, K as ResponseProvider, L as RuntimeTool, S as SkillCommandExecutor, N as SkillCommandRequest, O as SkillCommandResult, Q as SkillPluginOptions, T as SkillPluginState, U as SkillRuntimeToolsOptions, Y as ToolCallContext, Z as ToolProvider, _ as ToolProviderItem, $ as ToolSource, a0 as compileSkillInstructions, a1 as createSkillRuntimeTools, a2 as skillPlugin, a3 as toolPlugin } from './skillPlugin-D6X-p9fQ.js';
|
|
3
|
+
import { Ref, ComputedRef } from 'vue';
|
|
4
|
+
import { b as SkillFile, S as SkillDefinition } from './types-ChCZ8jKB.js';
|
|
5
|
+
export { B as BaseSkillFile, a as BinarySkillFile, c as SkillFileKind, d as SkillFileResource, T as TextSkillFile } from './types-ChCZ8jKB.js';
|
|
6
|
+
import 'openai/resources';
|
|
7
|
+
|
|
8
|
+
declare const createNativeMessageAdapter: () => MessageStateAdapter;
|
|
9
|
+
|
|
10
|
+
interface VueMessageStateAdapter extends MessageStateAdapter {
|
|
11
|
+
requestState: Ref<RequestState>;
|
|
12
|
+
processingState: Ref<RequestProcessingState | undefined>;
|
|
13
|
+
messages: Ref<ChatMessage[]>;
|
|
14
|
+
isProcessing: ComputedRef<boolean>;
|
|
15
|
+
}
|
|
16
|
+
declare const createVueMessageAdapter: () => VueMessageStateAdapter;
|
|
17
|
+
|
|
18
|
+
declare const createMessageEngine: (adapter: MessageStateAdapter, options?: CreateMessageEngineOptions) => MessageEngine;
|
|
19
|
+
|
|
20
|
+
declare const lengthPlugin: (options?: MessageEnginePlugin & {
|
|
21
|
+
continueContent?: string;
|
|
22
|
+
}) => MessageEnginePlugin;
|
|
23
|
+
|
|
24
|
+
declare const thinkingPlugin: (options?: MessageEnginePlugin) => MessageEnginePlugin;
|
|
25
|
+
|
|
26
|
+
declare function normalizeToAsyncGenerator<T>(result: T | Promise<T> | AsyncGenerator<T> | Promise<AsyncGenerator<T>>): AsyncGenerator<T>;
|
|
27
|
+
/**
|
|
28
|
+
* Merge delta data from completion responses
|
|
29
|
+
* Handles string concatenation, object merging, and array merging by index
|
|
30
|
+
*
|
|
31
|
+
* @param target - Target object to merge into
|
|
32
|
+
* @param source - Source object to merge from
|
|
33
|
+
* @returns Merged target object
|
|
34
|
+
*/
|
|
35
|
+
declare const combineDeltaData: (target: Record<string, any>, source: Record<string, any>) => Record<string, any>;
|
|
36
|
+
|
|
37
|
+
type BrowserFile = Pick<File, 'arrayBuffer' | 'lastModified' | 'name' | 'size' | 'text' | 'type'> & {
|
|
38
|
+
webkitRelativePath?: string;
|
|
39
|
+
};
|
|
40
|
+
type BrowserFileHandle = {
|
|
41
|
+
kind: 'file';
|
|
42
|
+
name: string;
|
|
43
|
+
getFile: () => Promise<BrowserFile>;
|
|
44
|
+
};
|
|
45
|
+
type BrowserDirectoryHandle = {
|
|
46
|
+
kind: 'directory';
|
|
47
|
+
name: string;
|
|
48
|
+
entries: () => AsyncIterable<[string, BrowserFileHandle | BrowserDirectoryHandle]>;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Browser FileList 适配器,用于读取文件选择器选中的 skill 目录。
|
|
52
|
+
*/
|
|
53
|
+
declare const loadSkillFilesFromFileList: (fileList: ArrayLike<BrowserFile>) => Promise<SkillFile[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Browser FileSystemDirectoryHandle 适配器,用于读取 window.showDirectoryPicker() 选中的目录。
|
|
56
|
+
*/
|
|
57
|
+
declare const loadSkillFilesFromDirectoryHandle: (directoryHandle: BrowserDirectoryHandle) => Promise<SkillFile[]>;
|
|
58
|
+
|
|
59
|
+
interface SkillLoaderResult {
|
|
60
|
+
/**
|
|
61
|
+
* 从源文件解析出的 skill 定义。
|
|
62
|
+
*/
|
|
63
|
+
skill: SkillDefinition;
|
|
64
|
+
/**
|
|
65
|
+
* 非致命的加载警告。
|
|
66
|
+
*/
|
|
67
|
+
warnings: Array<{
|
|
68
|
+
/**
|
|
69
|
+
* 用于 UI 和日志分类的警告编码。
|
|
70
|
+
*/
|
|
71
|
+
code: string;
|
|
72
|
+
/**
|
|
73
|
+
* 人类可读的警告信息。
|
|
74
|
+
*/
|
|
75
|
+
message: string;
|
|
76
|
+
/**
|
|
77
|
+
* 关联的 skill 文件路径。
|
|
78
|
+
*/
|
|
79
|
+
path?: string;
|
|
80
|
+
}>;
|
|
81
|
+
}
|
|
82
|
+
interface SkillLoaderOptions {
|
|
83
|
+
/**
|
|
84
|
+
* skill 入口文件名。
|
|
85
|
+
*/
|
|
86
|
+
entryFile?: string;
|
|
87
|
+
/**
|
|
88
|
+
* 启用后,警告会直接抛出为错误。
|
|
89
|
+
*/
|
|
90
|
+
strict?: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 将标准化后的 skill 文件转换为 SkillDefinition。
|
|
94
|
+
*
|
|
95
|
+
* 文件来源适配器负责提供 SkillFile[];该 loader 负责解析入口文件和资源文件。
|
|
96
|
+
*/
|
|
97
|
+
declare class SkillLoader {
|
|
98
|
+
private entryFile;
|
|
99
|
+
private strict;
|
|
100
|
+
constructor(options?: SkillLoaderOptions);
|
|
101
|
+
load(files: SkillFile[]): SkillLoaderResult;
|
|
102
|
+
private normalizeFiles;
|
|
103
|
+
private handleWarning;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type SkillManagerOptions = {
|
|
107
|
+
/**
|
|
108
|
+
* 初始化时写入 manager 的 skill 列表。
|
|
109
|
+
*/
|
|
110
|
+
skills?: SkillDefinition[];
|
|
111
|
+
/**
|
|
112
|
+
* 初始化时选中的 skill 名称。
|
|
113
|
+
*/
|
|
114
|
+
selectedSkillNames?: string[];
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* 管理 skill 集合和选择状态。
|
|
118
|
+
*
|
|
119
|
+
* manager 不编译 prompt 或 tools,也不接入 message 生命周期。
|
|
120
|
+
*/
|
|
121
|
+
declare class SkillManager {
|
|
122
|
+
private skills;
|
|
123
|
+
private selectedSkillNames;
|
|
124
|
+
constructor(options?: SkillManagerOptions);
|
|
125
|
+
set(skill: SkillDefinition): SkillDefinition;
|
|
126
|
+
remove(name: string): SkillDefinition | undefined;
|
|
127
|
+
clear(): void;
|
|
128
|
+
get(name: string): SkillDefinition | undefined;
|
|
129
|
+
has(name: string): boolean;
|
|
130
|
+
list(): SkillDefinition[];
|
|
131
|
+
select(names: string | string[]): void;
|
|
132
|
+
unselect(names: string | string[]): void;
|
|
133
|
+
getSelectedSkillNames(): string[];
|
|
134
|
+
getSelectedSkills(): SkillDefinition[];
|
|
135
|
+
import(files: SkillFile[], options?: SkillLoaderOptions): SkillLoaderResult;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
declare const normalizeSkillPath: (path: string) => string | null;
|
|
139
|
+
declare const isTextSkillFilePath: (path: string) => boolean;
|
|
140
|
+
declare const getExtension: (path: string) => string;
|
|
141
|
+
|
|
142
|
+
export { type BrowserDirectoryHandle, type BrowserFile, type BrowserFileHandle, ChatMessage, CreateMessageEngineOptions, MessageEngine, MessageEnginePlugin, MessageStateAdapter, RequestProcessingState, RequestState, SkillDefinition, SkillFile, SkillLoader, type SkillLoaderOptions, type SkillLoaderResult, SkillManager, type SkillManagerOptions, type VueMessageStateAdapter, combineDeltaData, createMessageEngine, createNativeMessageAdapter, createVueMessageAdapter, getExtension, isTextSkillFilePath, lengthPlugin, loadSkillFilesFromDirectoryHandle, loadSkillFilesFromFileList, normalizeSkillPath, normalizeToAsyncGenerator, thinkingPlugin };
|
package/dist/core.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";var re=Object.defineProperty;var ve=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var qe=Object.prototype.hasOwnProperty;var Be=(e,t)=>{for(var s in t)re(e,s,{get:t[s],enumerable:!0})},_e=(e,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Ee(t))!qe.call(e,i)&&i!==s&&re(e,i,{get:()=>t[i],enumerable:!(n=ve(t,i))||n.enumerable});return e};var Ie=e=>_e(re({},"__esModule",{value:!0}),e);var Ze={};Be(Ze,{SkillLoader:()=>J,SkillManager:()=>ie,combineDeltaData:()=>D,compileSkillInstructions:()=>ne,createMessageEngine:()=>Pe,createNativeMessageAdapter:()=>De,createSkillRuntimeTools:()=>se,createVueMessageAdapter:()=>ze,getExtension:()=>Q,isTextSkillFilePath:()=>U,lengthPlugin:()=>te,loadSkillFilesFromDirectoryHandle:()=>we,loadSkillFilesFromFileList:()=>xe,normalizeSkillPath:()=>V,normalizeToAsyncGenerator:()=>H,skillPlugin:()=>ye,thinkingPlugin:()=>oe,toolPlugin:()=>Te});module.exports=Ie(Ze);var Ne=e=>typeof e=="function"?null:Array.isArray(e)?e.length>0?new Set(e):null:new Set([e]),ee=e=>{let t=new Set,s=(o,r)=>{try{o.listener(r)}catch(c){console.error("Error in message state subscriber:",c)}};return{notify:o=>{let r=new Set(Array.isArray(o)?o:[o]),c=e(),p=Array.from(t);for(let a of p){if(a.kinds){let u=!1;for(let M of a.kinds)if(r.has(M)){u=!0;break}if(!u)continue}s(a,c)}},subscribe:(o,r)=>{let c=typeof o=="function"?o:r;if(!c)throw new Error("subscribe listener is required");let p={kinds:Ne(o),listener:c};return t.add(p),s(p,e()),()=>{t.delete(p)}}}};var De=()=>{let e=!1,t,s=r=>{if(e)throw new Error("Message state adapter is already initialized");t={requestState:r.requestState,processingState:r.processingState,messages:[...r.messages]},e=!0},n=()=>{if(!e)throw new Error("Message state adapter is not initialized");return{requestState:t.requestState,processingState:t.processingState,messages:[...t.messages],isProcessing:t.requestState==="processing"}},i=ee(n);return{initialize:s,getState:n,createMessage(r){return r},mutate:(r,c)=>{if(!e)throw new Error("Message state adapter is not initialized");let p=!1;c(t,()=>{p=!0}),p||i.notify(r)},subscribe:i.subscribe}};var v=require("vue");var de=e=>(0,v.reactive)(e),ae=e=>{let t=(0,v.isProxy)(e)?(0,v.toRaw)(e):e;if(Array.isArray(t))return t.map(s=>ae(s));if(t&&typeof t=="object"){let s={};for(let[n,i]of Object.entries(t))s[n]=ae(i);return s}return t},ze=()=>{let e=!1,t=(0,v.ref)("idle"),s=(0,v.ref)(void 0),n=(0,v.ref)([]),i=(0,v.computed)(()=>t.value==="processing"),o=u=>{if(e)throw new Error("Message state adapter is already initialized");t.value=u.requestState,s.value=u.processingState,n.value=u.messages.map(de),e=!0},r=u=>de(u),c=()=>{if(!e)throw new Error("Message state adapter is not initialized");return{requestState:t.value,processingState:s.value,messages:ae(n.value),isProcessing:i.value}},p=ee(c);return{requestState:t,processingState:s,messages:n,isProcessing:i,initialize:o,getState:c,createMessage:r,mutate:(u,M)=>{if(!e)throw new Error("Message state adapter is not initialized");let F={get requestState(){return t.value},set requestState(_){t.value=_},get processingState(){return s.value},set processingState(_){s.value=_},get messages(){return n.value},set messages(_){n.value=_.map(r)}},z=!1;if(M(F,()=>{z=!0}),z)return;(Array.isArray(u)?u:[u]).includes("messages")&&(n.value=[...n.value]),p.notify(u)},subscribe:p.subscribe}};var te=(e={})=>{let{continueContent:t="Please continue with your previous answer.",...s}=e;return{name:"length",...s,onAfterRequest:async n=>{let{lastChoice:i,appendMessage:o,requestNext:r}=n;return i?.finish_reason==="length"&&(o({role:"user",content:t}),r()),s.onAfterRequest?.(n)}}};var pe={listSkillFiles:"list_skill_files",readSkillFile:"read_skill_file"},Oe="execute_skill_command",fe=[{type:"function",function:{name:pe.listSkillFiles,description:"List files available from the current skills.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Optional skill name. When omitted, files from all current skills are listed."}},additionalProperties:!1}}},{type:"function",function:{name:pe.readSkillFile,description:"Read a file from a current skill by skill name and relative path.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Skill name that owns the file."},path:{type:"string",description:"File path relative to the skill root."}},required:["skillName","path"],additionalProperties:!1}}}],je={type:"function",function:{name:Oe,description:"Execute a command in the backend runtime environment for a selected skill.",parameters:{type:"object",properties:{skillName:{type:"string",description:"Name of the current skill that provides the command instructions."},command:{type:"string",description:"Command name to execute in the skill backend runtime."},args:{type:"array",description:"Command arguments passed as argv items.",items:{type:"string"}}},required:["skillName","command","args"],additionalProperties:!1}}},le=(e,t)=>({skillName:e,id:t.id,path:t.path,kind:t.kind,mimeType:t.mimeType,size:t.size,lastModified:t.lastModified}),ce=e=>{let t=e.function.arguments;if(!t)return{};try{let s=JSON.parse(t);return s&&typeof s=="object"&&!Array.isArray(s)?s:{}}catch{return{}}},Le=e=>Array.isArray(e)&&e.every(t=>typeof t=="string")?e:void 0,Ke=e=>{if(!e.some(n=>!!n.files?.length))return[];let s=n=>{if(!(typeof n!="string"||!n))return e.find(i=>i.name===n)};return[{tool:fe[0],handler:n=>{let i=ce(n),o=s(i.skillName);return{files:(o?[o]:e).flatMap(c=>(c.files??[]).map(p=>le(c.name,p)))}}},{tool:fe[1],handler:n=>{let i=ce(n),o=s(i.skillName),r=typeof i.path=="string"?i.path:void 0;if(!o)return{error:"skill_not_found"};if(!r)return{error:"file_path_required",skillName:o.name};let c=o.files?.find(p=>p.path===r);return c?c.kind==="binary"?{error:"binary_file_not_readable",file:le(o.name,c)}:{file:le(o.name,c),content:c.content}:{error:"file_not_found",skillName:o.name,path:r}}}]},We=(e,t)=>{if(!t||e.length===0)return[];let s=n=>{if(!(typeof n!="string"||!n))return e.find(i=>i.name===n)};return[{tool:je,handler:async n=>{let i=ce(n),o=s(i.skillName),r=typeof i.command=="string"?i.command:void 0,c=Le(i.args);return o?r?c?t({skill:o,skillName:o.name,command:r,args:c}):{error:"args_required",skillName:o.name,command:r}:{error:"command_required",skillName:o.name}:{error:"skill_not_found"}}}]},se=(e,t={})=>[...Ke(e),...We(e,t.executeSkillCommand)],ne=async e=>{let t=[];for(let s of e){let n=s.instructions?.trim();n&&t.push(`## ${s.name}
|
|
2
|
+
|
|
3
|
+
${n}`)}if(t.length!==0)return{role:"system",content:["Apply these skill instructions when generating the response.",...t].join(`
|
|
4
|
+
|
|
5
|
+
`)}};var ue="__tiny_robot_skill",ye=e=>{let{getSkills:t,executeSkillCommand:s,onSkillsResolved:n,...i}=e;return{name:"skill",...i,provideTools:async o=>o.customContext[ue]?.runtimeTools??[],onTurnStart:async o=>{let r=await t?.(o)??[],c={skills:r,skillNames:r.map(p=>p.name),runtimeTools:se(r,{executeSkillCommand:s&&(p=>s(p,o))})};return o.setCustomContext({[ue]:c}),await n?.(c,o),i.onTurnStart?.(o)},onBeforeRequest:async o=>{let r=o.customContext[ue];if(r){let c=await ne(r.skills);c&&(o.requestBody.messages=[c,...o.requestBody.messages])}return i.onBeforeRequest?.(o)}}};var oe=(e={})=>{let t=(s,n)=>!!s.thinking!==n||!!s.open!==n;return{name:"thinking",...e,onCompletionChunk(s){let{choice:n,currentMessage:i,updateCurrentMessage:o}=s,r=n,c=r?.message?.reasoning_content||r?.delta?.reasoning_content,p=typeof c=="string"&&c.trim()!=="";return p?i.state&&typeof i.state=="object"?t(i.state,p)&&o(a=>{a.state.thinking=!0,a.state.open=!0}):o(a=>{a.state={thinking:p,open:p}}):i.state&&typeof i.state=="object"&&"thinking"in i.state&&t(i.state,p)&&o(a=>{a.state.thinking=!1,a.state.open=!1}),e.onCompletionChunk?.(s)},onTurnEnd(s){let{currentTurn:n,mutate:i}=s,o=n.at(-1);return o?.state&&typeof o.state=="object"&&"thinking"in o.state&&t(o.state,!1)&&i("messages",()=>{o.state.thinking=!1,o.state.open=!1}),e.onTurnEnd?.(s)}}};var G=class extends Error{constructor(t){super(t),this.name="AbortError"}};function $e(e){if(e.aborted)return{promise:Promise.reject(new G(String(e.reason??"Aborted"))),cleanup:()=>{}};let t=null;return{promise:new Promise((i,o)=>{t=()=>{o(new G(String(e.reason??"Aborted")))},e.addEventListener("abort",t,{once:!0})}),cleanup:()=>{t&&(e.removeEventListener("abort",t),t=null)}}}function Se(e,t){let{promise:s,cleanup:n}=$e(t);return Promise.race([e,s]).finally(n)}function Ce(e,t){let s={};for(let n in e)t.includes(n)&&(s[n]=e[n]);return s}function Me(e,t){let s={};for(let n in e)t.includes(n)||(s[n]=e[n]);return s}async function*H(e){if(he(e)){yield*e;return}let t=await e;if(he(t)){yield*t;return}yield t}function he(e){return e&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function"}var me=e=>typeof e=="object"&&e!==null,ke=e=>me(e)&&typeof e.index=="number",D=(e,t)=>{for(let[s,n]of Object.entries(t)){let i=e[s];if(i)if(typeof i=="string"&&typeof n=="string")s==="type"&&i||(e[s]=i+n);else if(Array.isArray(i)&&Array.isArray(n))if(i.every(o=>ke(o))&&n.every(o=>ke(o))){let o=new Map(i.map(a=>[a.index,a])),r=new Map(n.map(a=>[a.index,a]));for(let[a,u]of r)if(o.has(a)){let M=o.get(a);o.set(a,D(M,u))}else o.set(a,u);let c=Math.max(...Array.from(o.keys()),-1)+1,p=c>i.length?Array.from({length:c}):i;for(let[a,u]of o)p[a]=u;e[s]=p}else e[s]=[...i,...n];else me(i)&&me(n)&&(e[s]=D(i,n));else e[s]=n}return e};function Ge({messages:e,cancelledContent:t,createMessage:s,mutate:n}){let i=[];for(let o=0;o<e.length;o++){let r=e[o];if(r.role==="assistant"&&r.tool_calls&&r.tool_calls.length>0){let c=new Set(r.tool_calls.map(u=>u.id)),p=new Set;for(let u=o+1;u<e.length;u++){let M=e[u];M.role==="tool"&&M.tool_call_id&&c.has(M.tool_call_id)&&p.add(M.tool_call_id)}let a=r.tool_calls.map(u=>u.id).filter(u=>!p.has(u));a.length>0&&i.push({insertAfterIndex:o,missingToolCallIds:a})}}i.length!==0&&n("messages",o=>{for(let r=i.length-1;r>=0;r--){let{insertAfterIndex:c,missingToolCallIds:p}=i[r],a=p.map(u=>s({role:"tool",tool_call_id:u,content:t}));o.messages.splice(c+1,0,...a)}})}var Te=e=>{let{getTools:t,beforeCallTools:s,callTool:n,onToolCallStart:i,onToolCallEnd:o,toolCallCancelledContent:r="Tool call cancelled.",toolCallFailedContent:c="Tool call failed.",autoFillMissingToolMessages:p=!1,...a}=e,u=(m,f)=>{var S,h;return m.state??(m.state={}),(S=m.state).toolCall??(S.toolCall={}),(h=m.state.toolCall)[f]??(h[f]={}),m},M=(...m)=>{let[f,{assistantMessage:S,mutate:h}]=m;h("messages",()=>{let R=u(S,f.id);R.state.toolCall[f.id].status="running"}),i?.(...m)},F=(...m)=>{let[f,{status:S,assistantMessage:h,mutate:R}]=m;R("messages",()=>{let I=u(h,f.id);I.state.toolCall[f.id].status=S}),o?.(...m)},z=m=>m.type==="function"&&"function"in m,W=m=>!!(m&&typeof m=="object"&&"tool"in m&&"handler"in m),B=m=>{let f=m;return typeof f.provideTools=="function"?f:void 0},_=(m,f)=>typeof m.disabled=="function"?m.disabled(f):!!m.disabled,X=async(m,f=[])=>{let S=[];for(let T of m.plugins){let l=B(T);!_(T,m)&&l&&S.push(...(await l.provideTools(m)).map(d=>({item:d,source:{type:"toolProvider",pluginName:T.name}})))}let h=[...S,...(await t(m)).map(T=>({item:T,source:{type:"toolPlugin"}}))],R=[],I=new Map,O=new Map,j=new Set,$=T=>{let l=T.function.name;if(j.has(l))throw new Error(`Duplicate tool name "${l}" detected. Tool names must be unique because tool calls are routed by function.name.`);j.add(l)};f.forEach($);for(let{item:T,source:l}of h){let d=W(T)?T.tool:T;$(d),O.set(d.function.name,l),W(T)?(R.push(T.tool),I.set(T.tool.function.name,T)):R.push(T)}return{tools:R,runtimeToolMap:I,toolSourceMap:O}};return{name:"tool",...a,onTurnStart:m=>{let{getState:f,createMessage:S,mutate:h}=m,R=f().messages;return p&&Ge({messages:R,cancelledContent:r,createMessage:S,mutate:h}),a.onTurnStart?.(m)},onBeforeRequest:async m=>{let{requestBody:f}=m,S=Array.isArray(f.tools)?f.tools:[],{tools:h}=await X(m,S);return h&&h.length>0&&(f.tools=S.length?[...S,...h]:h),a.onBeforeRequest?.(m)},onAfterRequest:async m=>{let{currentMessage:f,lastChoice:S,appendMessage:h,abortSignal:R,setRequestState:I,requestNext:O,mutate:j,createMessage:$}=m;if(S?.finish_reason!=="tool_calls"||!f.tool_calls?.length)return;I("processing","calling-tools"),await s?.(f.tool_calls,{...m,assistantMessage:f});let{runtimeToolMap:T,toolSourceMap:l}=await X(m),d=f.tool_calls.map(async y=>{let C=Math.floor(Date.now()/1e3),w=!1,g=$({role:"tool",tool_call_id:y.id,content:"",metadata:{createdAt:C,updatedAt:C}});h(g);let k=z(y)?y:void 0,E=k?l.get(k.function.name)??{type:"unknown"}:{type:"unknown"},b={...m,assistantMessage:f,toolMessage:g,toolSource:E};M(y,b);try{let x=k?T.get(k.function.name):void 0,P=x&&k?x.handler(k,b):n(y,b),N=H(P);for await(let q of N)j("messages",()=>{if((typeof q=="string"&&q.length>0||q&&typeof q=="object"&&Object.keys(q).length>0)&&(w=!0),typeof q=="string")g.content+=q;else{let Y={};try{let A=Array.isArray(g.content)?g.content.map(L=>L.text).join(""):g.content;Y=JSON.parse(A||"{}")}catch(A){console.warn(A)}g.content=JSON.stringify(D(Y,q))}g.metadata.updatedAt=Math.floor(Date.now()/1e3)});F(y,{...b,status:"success"})}catch(x){let P=x instanceof Error?x:new Error(String(x));if(R.aborted){F(y,{...b,status:"cancelled",error:P});return}console.error(x),w||j("messages",()=>{g.content=c,g.metadata.updatedAt=Math.floor(Date.now()/1e3)}),F(y,{...b,status:"failed",error:P})}});return await Promise.all(d),R.aborted||O(),a.onAfterRequest?.(m)}}};var He=async()=>{throw new Error("Response provider is not set")},Ve=e=>{let t=[];for(let s of e){if(s.name){let n=t.findIndex(i=>i.name===s.name);n!==-1&&t.splice(n,1)}t.push(s)}return t},K=(e,t)=>typeof e.disabled=="function"?e.disabled(t):!!e.disabled,Pe=(e,t={})=>{let{initialMessages:s=[],requestMessageFields:n=[],requestMessageFieldsExclude:i=["state","metadata","loading"],responseProvider:o=He,onCompletionChunk:r,plugins:c=[]}=t,p={requestState:"idle",processingState:void 0,messages:[...s]};e.initialize(p);let a={currentTurn:[],customContext:{},abortController:null,responseProvider:o},u=[oe(),te()],M=Ve(u.concat(c)),F=()=>e.getState(),z=l=>e.createMessage(l),W=e.subscribe,B=e.mutate,_=l=>!l||Object.keys(l).length===0?!1:Object.values(l).some(d=>!!d),X=l=>{let d=l;return n.length&&(d=d.map(y=>Ce(y,n))),i.length&&(d=d.map(y=>Me(y,i))),d},m=l=>{Object.assign(a.customContext,l)},f=(l,d)=>{B("requestState",(y,C)=>{if(y.requestState===l&&y.processingState===d){C();return}y.requestState=l,y.processingState=l==="processing"?d??"requesting":void 0})},S=(...l)=>{let d=l.map(y=>z(y));return B("messages",y=>{y.messages.push(...d)}),a.currentTurn.push(...d),d},h=l=>({getState:F,createMessage:z,mutate:B,abortSignal:l,currentTurn:a.currentTurn,plugins:M,customContext:a.customContext,setRequestState:f,setCustomContext:m});async function R(l,d,y={}){f("processing","requesting");let C={messages:F().messages},w=h(d);for(let x of M.filter(P=>!K(P,w)))await x.onBeforeRequest?.({...w,requestBody:C});C.messages=X(C.messages);let g={role:"assistant",content:"",loading:!0};[g]=S(g),y.setAssistantMessage?.(g);let k=l(C,d),E=H(k),b;for await(let x of E){f("processing","completing"),B("messages",(A,L)=>{g.loading?g.loading=void 0:L()});let P=(x.choices||[]).find(A=>A.index===0)??x.choices?.[0];if(!P)continue;b=P;let N=()=>{B("messages",()=>{g.metadata||(g.metadata={});let{created:A,...L}=x;g.metadata.createdAt=A,g.metadata.updatedAt=Math.floor(Date.now()/1e3),Object.assign(g.metadata,L);let Z="delta"in P&&_(P.delta)&&P.delta||"message"in P&&_(P.message)&&P.message||null;if(Z?.role&&(g.role=Z.role),Z){let{role:et,...Fe}=Z;D(g,Fe)}})},q=A=>{B("messages",()=>{A(g)})};if(r){let A=h(d);r({...A,chunk:x,choice:P,currentMessage:g,updateCurrentMessage:q},N)}else N();let Y=h(d);for(let A of M.filter(L=>!K(L,Y)))A.onCompletionChunk?.({...Y,abortSignal:d,chunk:x,choice:P,currentMessage:g,updateCurrentMessage:q})}await I(g,l,d,b,y)}async function I(l,d,y,C,w){let g=!1,k=h(y),E=M.filter(b=>!K(b,k)).map(b=>{if(!b.onAfterRequest)return null;let x=N=>{S(...Array.isArray(N)?N:[N])},P=()=>{g=!0};return b.onAfterRequest({...k,currentMessage:l,lastChoice:C,appendMessage:x,requestNext:P})}).filter(b=>b!==null);await Se(Promise.all(E),y),g&&await R(d,y,w)}async function O(){let l=new AbortController;a.abortController=l,a.customContext={};let d=null,y=C=>{d=C};try{f("processing","requesting");let C=h(l.signal);for(let k of M.filter(E=>!K(E,C)))await k.onTurnStart?.(C);let w=a.responseProvider;try{await R(w,l.signal,{setAssistantMessage:y}),f("completed")}catch(k){if(l.signal.aborted||k instanceof G||k instanceof Error&&k.name==="AbortError")f("aborted");else throw k}let g=h(l.signal);for(let k of M.filter(E=>!K(E,g)))await k.onTurnEnd?.(g)}catch(C){f("error");let w=!1,g=h(l.signal);for(let k of M.filter(E=>!K(E,g)))k.onError&&(w=!0,k.onError({...g,error:C}));if(!w)throw C}finally{let C=h(l.signal);for(let w of M.filter(g=>!K(g,C)))try{w.onFinally?.(C)}catch(g){console.error(`Error in onFinally hook for plugin [${w.name||"Anonymous"}]:`,g)}a.abortController=null,a.currentTurn=[],B("messages",(w,g)=>{d?.loading?d.loading=void 0:g()})}}async function j(l){if(!l||!l.trim()){console.warn("Cannot send empty message");return}if(F().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}let d=Math.floor(Date.now()/1e3);S({role:"user",content:l.trim(),metadata:{createdAt:d,updatedAt:d}}),await O()}async function $(...l){if(F().requestState==="processing"){console.warn("Cannot send message while processing is in progress");return}S(...l),await O()}async function T(){a.abortController?.abort(),F().isProcessing&&await new Promise(l=>{let d=()=>{};d=W("requestState",y=>{y.isProcessing||(d(),l())})})}return{getState:F,subscribe:W,sendMessage:j,send:$,abort:T,setResponseProvider(l){a.responseProvider=l}}};var V=e=>{let t=e.split("\\").join("/").replace(/^\.\/+/,"");return!t||t.startsWith("/")||t.includes("\0")||t.split("/").some(s=>s===".."||s==="")?null:t},U=e=>[".md",".txt",".json"].includes(Q(e)),Q=e=>{let t=e.split("/").at(-1)||e,s=t.lastIndexOf(".");return s===-1?"":t.slice(s).toLowerCase()};var xe=async e=>{let t=Array.from({length:e.length},(s,n)=>e[n]).filter(s=>!!s);return Promise.all(t.map(s=>{let n=s.webkitRelativePath||s.name;return be(s,Ue(n))}))},we=async e=>{let t=[],s=async(n,i="")=>{for await(let[o,r]of n.entries()){let c=i?`${i}/${o}`:o;if(r.kind==="directory"){await s(r,c);continue}t.push(await be(await r.getFile(),c))}};return await s(e),t.sort((n,i)=>n.path.localeCompare(i.path))},be=async(e,t)=>{let s=V(t);if(!s)throw new Error(`Invalid skill file path: ${t}`);return U(s)?{path:s,kind:"text",content:await e.text(),mimeType:e.type,size:e.size,lastModified:e.lastModified}:{path:s,kind:"binary",content:await e.arrayBuffer(),mimeType:e.type,size:e.size,lastModified:e.lastModified}},Ue=e=>{let t=e.split("\\").join("/"),s=t.split("/").filter(Boolean);return s.length<=1?t:s.slice(1).join("/")};var Re=require("yaml");var J=class{constructor(t={}){this.entryFile=t.entryFile??"SKILL.md",this.strict=t.strict??!1}load(t){let s=[],n=this.normalizeFiles(t,s),i=n.find(u=>u.path===this.entryFile);if(!i)throw new Error(`Skill entry file "${this.entryFile}" is missing.`);if(i.kind!=="text")throw new Error(`Skill entry file "${this.entryFile}" must be a text file.`);let{frontmatter:o,body:r}=Je(i.content),c=r.trim();if(!c)throw new Error(`Skill entry file "${this.entryFile}" must contain instructions.`);let p=Ae(o.metadata),a=[];for(let u of n)if(u.path!==this.entryFile){if(u.kind==="binary"){a.push({...u,id:u.path});continue}if(!U(u.path)){s.push({code:"unsupported-text-file-ignored",message:"Only markdown, text, and json files are converted to text skill files.",path:u.path});continue}a.push({...u,id:u.path})}return{skill:{name:ge(o.name)||Xe(this.entryFile),description:ge(o.description)||"",instructions:c,files:a.length?a:void 0,metadata:{...p,homepage:ge(o.homepage),frontmatter:o}},warnings:s}}normalizeFiles(t,s){let n=[],i=new Set;for(let o of t){let r=V(o.path);if(!r){this.handleWarning(s,{code:"invalid-path",message:`Invalid skill file path: ${o.path}`,path:o.path});continue}if(i.has(r)){this.handleWarning(s,{code:"duplicate-path",message:`Duplicate skill file path: ${r}`,path:r});continue}i.add(r),n.push({...o,path:r})}return n.sort((o,r)=>o.path.localeCompare(r.path))}handleWarning(t,s){if(this.strict)throw new Error(s.path?`${s.path}: ${s.message}`:s.message);t.push(s)}},Je=e=>{if(!e.startsWith("---"))return{frontmatter:{},body:e};let t=e.indexOf(`
|
|
6
|
+
---`,3);if(t===-1)return{frontmatter:{},body:e};let s=e.slice(3,t).trim(),n=e.slice(t+4);return{frontmatter:Ye(s),body:n}},Ye=e=>{let t=(0,Re.parse)(e);return Ae(t)??{}},ge=e=>typeof e=="string"?e:void 0,Ae=e=>e&&typeof e=="object"&&!Array.isArray(e)?e:void 0,Qe=e=>{let t=e.split("/").at(-1)||e,s=Q(t);return s?t.slice(0,-s.length):t},Xe=e=>Qe(e);var ie=class{constructor(t={}){this.skills=new Map;this.selectedSkillNames=new Set;for(let s of t.skills??[])this.set(s);this.select(t.selectedSkillNames??[])}set(t){return this.skills.set(t.name,t),t}remove(t){let s=this.get(t);return this.skills.delete(t),this.selectedSkillNames.delete(t),s}clear(){this.skills.clear(),this.selectedSkillNames.clear()}get(t){return this.skills.get(t)}has(t){return this.skills.has(t)}list(){return Array.from(this.skills.values())}select(t){for(let s of Array.isArray(t)?t:[t]){if(!this.skills.has(s))throw new Error(`Skill "${s}" does not exist.`);this.selectedSkillNames.add(s)}}unselect(t){for(let s of Array.isArray(t)?t:[t])this.selectedSkillNames.delete(s)}getSelectedSkillNames(){return Array.from(this.selectedSkillNames)}getSelectedSkills(){return this.getSelectedSkillNames().flatMap(t=>{let s=this.skills.get(t);return s?[s]:[]})}import(t,s={}){let n=new J(s).load(t);return this.set(n.skill),n}};0&&(module.exports={SkillLoader,SkillManager,combineDeltaData,compileSkillInstructions,createMessageEngine,createNativeMessageAdapter,createSkillRuntimeTools,createVueMessageAdapter,getExtension,isTextSkillFilePath,lengthPlugin,loadSkillFilesFromDirectoryHandle,loadSkillFilesFromFileList,normalizeSkillPath,normalizeToAsyncGenerator,skillPlugin,thinkingPlugin,toolPlugin});
|
package/dist/core.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as g,b as N,c as E,d as F,e as w,f as v,g as O,h as x,i as M,j as T,k as $}from"./chunk-6JEZBNBO.mjs";import{a as p,b as d,c as f}from"./chunk-ZO2ZONVX.mjs";var I=()=>{let i=!1,e,t=r=>{if(i)throw new Error("Message state adapter is already initialized");e={requestState:r.requestState,processingState:r.processingState,messages:[...r.messages]},i=!0},s=()=>{if(!i)throw new Error("Message state adapter is not initialized");return{requestState:e.requestState,processingState:e.processingState,messages:[...e.messages],isProcessing:e.requestState==="processing"}},o=g(s);return{initialize:t,getState:s,createMessage(r){return r},mutate:(r,a)=>{if(!i)throw new Error("Message state adapter is not initialized");let k=!1;a(e,()=>{k=!0}),k||o.notify(r)},subscribe:o.subscribe}};var b=async i=>{let e=Array.from({length:i.length},(t,s)=>i[s]).filter(t=>!!t);return Promise.all(e.map(t=>{let s=t.webkitRelativePath||t.name;return h(t,L(s))}))},R=async i=>{let e=[],t=async(s,o="")=>{for await(let[l,r]of s.entries()){let a=o?`${o}/${l}`:l;if(r.kind==="directory"){await t(r,a);continue}e.push(await h(await r.getFile(),a))}};return await t(i),e.sort((s,o)=>s.path.localeCompare(o.path))},h=async(i,e)=>{let t=p(e);if(!t)throw new Error(`Invalid skill file path: ${e}`);return d(t)?{path:t,kind:"text",content:await i.text(),mimeType:i.type,size:i.size,lastModified:i.lastModified}:{path:t,kind:"binary",content:await i.arrayBuffer(),mimeType:i.type,size:i.size,lastModified:i.lastModified}},L=i=>{let e=i.split("\\").join("/"),t=e.split("/").filter(Boolean);return t.length<=1?e:t.slice(1).join("/")};import{parse as B}from"yaml";var m=class{constructor(e={}){this.entryFile=e.entryFile??"SKILL.md",this.strict=e.strict??!1}load(e){let t=[],s=this.normalizeFiles(e,t),o=s.find(n=>n.path===this.entryFile);if(!o)throw new Error(`Skill entry file "${this.entryFile}" is missing.`);if(o.kind!=="text")throw new Error(`Skill entry file "${this.entryFile}" must be a text file.`);let{frontmatter:l,body:r}=z(o.content),a=r.trim();if(!a)throw new Error(`Skill entry file "${this.entryFile}" must contain instructions.`);let k=y(l.metadata),c=[];for(let n of s)if(n.path!==this.entryFile){if(n.kind==="binary"){c.push({...n,id:n.path});continue}if(!d(n.path)){t.push({code:"unsupported-text-file-ignored",message:"Only markdown, text, and json files are converted to text skill files.",path:n.path});continue}c.push({...n,id:n.path})}return{skill:{name:S(l.name)||P(this.entryFile),description:S(l.description)||"",instructions:a,files:c.length?c:void 0,metadata:{...k,homepage:S(l.homepage),frontmatter:l}},warnings:t}}normalizeFiles(e,t){let s=[],o=new Set;for(let l of e){let r=p(l.path);if(!r){this.handleWarning(t,{code:"invalid-path",message:`Invalid skill file path: ${l.path}`,path:l.path});continue}if(o.has(r)){this.handleWarning(t,{code:"duplicate-path",message:`Duplicate skill file path: ${r}`,path:r});continue}o.add(r),s.push({...l,path:r})}return s.sort((l,r)=>l.path.localeCompare(r.path))}handleWarning(e,t){if(this.strict)throw new Error(t.path?`${t.path}: ${t.message}`:t.message);e.push(t)}},z=i=>{if(!i.startsWith("---"))return{frontmatter:{},body:i};let e=i.indexOf(`
|
|
2
|
+
---`,3);if(e===-1)return{frontmatter:{},body:i};let t=i.slice(3,e).trim(),s=i.slice(e+4);return{frontmatter:D(t),body:s}},D=i=>{let e=B(i);return y(e)??{}},S=i=>typeof i=="string"?i:void 0,y=i=>i&&typeof i=="object"&&!Array.isArray(i)?i:void 0,A=i=>{let e=i.split("/").at(-1)||i,t=f(e);return t?e.slice(0,-t.length):e},P=i=>A(i);var u=class{constructor(e={}){this.skills=new Map;this.selectedSkillNames=new Set;for(let t of e.skills??[])this.set(t);this.select(e.selectedSkillNames??[])}set(e){return this.skills.set(e.name,e),e}remove(e){let t=this.get(e);return this.skills.delete(e),this.selectedSkillNames.delete(e),t}clear(){this.skills.clear(),this.selectedSkillNames.clear()}get(e){return this.skills.get(e)}has(e){return this.skills.has(e)}list(){return Array.from(this.skills.values())}select(e){for(let t of Array.isArray(e)?e:[e]){if(!this.skills.has(t))throw new Error(`Skill "${t}" does not exist.`);this.selectedSkillNames.add(t)}}unselect(e){for(let t of Array.isArray(e)?e:[e])this.selectedSkillNames.delete(t)}getSelectedSkillNames(){return Array.from(this.selectedSkillNames)}getSelectedSkills(){return this.getSelectedSkillNames().flatMap(e=>{let t=this.skills.get(e);return t?[t]:[]})}import(e,t={}){let s=new m(t).load(e);return this.set(s.skill),s}};export{m as SkillLoader,u as SkillManager,M as combineDeltaData,w as compileSkillInstructions,$ as createMessageEngine,I as createNativeMessageAdapter,F as createSkillRuntimeTools,N as createVueMessageAdapter,f as getExtension,d as isTextSkillFilePath,E as lengthPlugin,R as loadSkillFilesFromDirectoryHandle,b as loadSkillFilesFromFileList,p as normalizeSkillPath,x as normalizeToAsyncGenerator,v as skillPlugin,O as thinkingPlugin,T as toolPlugin};
|