@stacknet/stacks 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,9 @@
1
- var m={"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"};async function*S(i){if(!i.body)throw new Error("Response body is null");let t=i.body.getReader(),r=new TextDecoder,n="",e={};try{for(;;){let{done:a,value:o}=await t.read();if(a)break;n+=r.decode(o,{stream:!0});let s=n.split(`
2
- `);n=s.pop()||"";for(let c of s){if(c===""){e.data!==void 0&&(yield e),e={};continue}if(c.startsWith(":"))continue;let u=c.indexOf(":");if(u===-1)continue;let f=c.slice(0,u),l=c.slice(u+1).trimStart();switch(f){case "event":e.event=l;break;case "data":try{e.data=JSON.parse(l);}catch{e.data=l;}break;case "id":e.id=l;break;case "retry":e.retry=parseInt(l,10);break}}}e.data!==void 0&&(yield e);}finally{t.releaseLock();}}function h(i,t){let r=new TextEncoder,n=new ReadableStream({async start(e){try{for await(let a of i){let o="";a.event&&(o+=`event: ${a.event}
3
- `),a.id&&(o+=`id: ${a.id}
4
- `),a.retry&&(o+=`retry: ${a.retry}
5
- `);let s=typeof a.data=="string"?a.data:JSON.stringify(a.data);o+=`data: ${s}
1
+ var m={"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"};var S=1024*1024;function f(a){return a.replace(/[\r\n\u2028\u2029]/g," ")}async function*y(a){if(!a.body)throw new Error("Response body is null");let t=a.body.getReader(),n=new TextDecoder,r="",e={};try{for(;;){let{done:o,value:i}=await t.read();if(o)break;if(r+=n.decode(i,{stream:!0}),r.length>S)throw new Error(`SSE buffer exceeded ${S} bytes without an event delimiter`);let s=r.split(`
2
+ `);r=s.pop()||"";for(let c of s){if(c===""){e.data!==void 0&&(yield e),e={};continue}if(c.startsWith(":"))continue;let p=c.indexOf(":");if(p===-1)continue;let g=c.slice(0,p),l=c.slice(p+1).trimStart();switch(g){case "event":e.event=l;break;case "data":try{e.data=JSON.parse(l);}catch{e.data=l;}break;case "id":e.id=l;break;case "retry":e.retry=parseInt(l,10);break}}}e.data!==void 0&&(yield e);}finally{t.releaseLock();}}function h(a){let t="";a.event&&(t+=`event: ${f(a.event)}
3
+ `),a.id&&(t+=`id: ${f(a.id)}
4
+ `),a.retry!==void 0&&Number.isFinite(a.retry)&&(t+=`retry: ${Math.floor(a.retry)}
5
+ `);let n=typeof a.data=="string"?a.data:JSON.stringify(a.data);for(let r of n.split(/\r?\n/))t+=`data: ${r}
6
+ `;return t+=`
7
+ `,t}function E(a,t){let n=new TextEncoder,r=new ReadableStream({async start(e){try{for await(let o of a)e.enqueue(n.encode(h(o)));}catch(o){console.error("SSE stream error:",o);}finally{e.close();}}});return new Response(r,{headers:{...m,...t}})}var d=class{encoder=new TextEncoder;controller=null;stream;constructor(){this.stream=new ReadableStream({start:t=>{this.controller=t;}});}getStream(){return this.stream}getResponse(t){return new Response(this.stream,{headers:{...m,...t}})}write(t){this.controller&&this.controller.enqueue(this.encoder.encode(h(t)));}writeData(t){this.write({data:t});}writeComment(t){if(!this.controller)return;let n=f(t);this.controller.enqueue(this.encoder.encode(`: ${n}
6
8
 
7
- `,e.enqueue(r.encode(o));}}catch(a){console.error("SSE stream error:",a);}finally{e.close();}}});return new Response(n,{headers:{...m,...t}})}var d=class{encoder=new TextEncoder;controller=null;stream;constructor(){this.stream=new ReadableStream({start:t=>{this.controller=t;}});}getStream(){return this.stream}getResponse(t){return new Response(this.stream,{headers:{...m,...t}})}write(t){if(!this.controller)return;let r="";t.event&&(r+=`event: ${t.event}
8
- `),t.id&&(r+=`id: ${t.id}
9
- `);let n=typeof t.data=="string"?t.data:JSON.stringify(t.data);r+=`data: ${n}
10
-
11
- `,this.controller.enqueue(this.encoder.encode(r));}writeData(t){this.write({data:t});}writeComment(t){this.controller&&this.controller.enqueue(this.encoder.encode(`: ${t}
12
-
13
- `));}close(){this.controller&&(this.controller.close(),this.controller=null);}error(t){this.controller&&(this.controller.error(t),this.controller=null);}};function g(){return new d}var p=class{constructor(t){this.dataStream=t;}processToolCalls(t){if(!(!t||t.length===0))for(let r of t)try{let n=JSON.parse(r.function.arguments),e=r.function.name;switch(e){case "create_document":this.handleCreateDocument(n,r.id);break;case "update_document":this.handleUpdateDocument(n,r.id);break;default:console.log(`[ComponentStream] Unknown tool: ${e}`);}}catch(n){console.error("[ComponentStream] Error processing tool call:",n);}}processToolResult(t){try{t.type==="artifact"?this.handleArtifactResult(t):t.type==="artifact_update"&&this.handleArtifactUpdate(t);}catch(r){console.error("[ComponentStream] Error processing tool result:",r);}}streamArtifact(t){this.dataStream.write({type:"data-kind",data:t.kind,transient:true}),this.dataStream.write({type:"data-id",data:t.id,transient:true}),this.dataStream.write({type:"data-title",data:t.title,transient:true}),this.dataStream.write({type:"data-clear",data:null,transient:true}),this.streamContent(t.content),this.dataStream.write({type:"data-finish",data:null,transient:true});}streamTextDelta(t){this.dataStream.write({type:"data-textDelta",data:t,transient:true});}streamContent(t,r=50){let n=this.splitIntoChunks(t,r);for(let e of n)this.dataStream.write({type:"data-textDelta",data:e,transient:true});}finish(){this.dataStream.write({type:"data-finish",data:null,transient:true});}handleCreateDocument(t,r){let{title:n,kind:e,content:a}=t,o=`doc_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;console.log(`[ComponentStream] Creating document: ${n} (${e})`),this.streamArtifact({id:o,kind:e,title:n,content:a}),this.dataStream.write({type:"tool-result",data:{toolCallId:r,toolName:"create_document",result:{id:o,title:n,kind:e,message:"Document created successfully"}}});}handleUpdateDocument(t,r){let{id:n,description:e,content:a}=t;console.log(`[ComponentStream] Updating document: ${n}`),this.dataStream.write({type:"data-clear",data:null,transient:true}),this.streamContent(a),this.dataStream.write({type:"data-finish",data:null,transient:true}),this.dataStream.write({type:"tool-result",data:{toolCallId:r,toolName:"update_document",result:{id:n,message:`Document updated: ${e}`}}});}handleArtifactResult(t){let{id:r,title:n,kind:e,content:a}=t;if(!r||!n||!e||!a){console.error("[ComponentStream] Invalid artifact result:",t);return}this.streamArtifact({id:r,kind:e,title:n,content:a});}handleArtifactUpdate(t){let{content:r}=t;if(!r){console.error("[ComponentStream] Invalid artifact update:",t);return}this.dataStream.write({type:"data-clear",data:null,transient:true}),this.streamContent(r),this.dataStream.write({type:"data-finish",data:null,transient:true});}splitIntoChunks(t,r){let n=[],e=t.split(" "),a="";for(let o=0;o<e.length;o++){let s=o===0?e[o]:" "+e[o];a.length+s.length>r&&a.length>0?(n.push(a),a=s.trim()):a+=s;}return a.length>0&&n.push(a),n}};function y(i){return !!(i?.tool_calls&&Array.isArray(i.tool_calls)&&i.tool_calls.length>0)}function E(i){try{let t=JSON.parse(i);if(t.type&&(t.type==="artifact"||t.type==="artifact_update"))return [t]}catch{}return []}function v(i){return new p(i)}export{p as ComponentStreamAdapter,d as SSEWriter,v as createComponentStreamAdapter,h as createSSEResponse,g as createSSEWriter,E as extractToolResults,y as hasToolCalls,S as parseSSEStream};
9
+ `));}close(){this.controller&&(this.controller.close(),this.controller=null);}error(t){this.controller&&(this.controller.error(t),this.controller=null);}};function w(){return new d}var u=class{constructor(t){this.dataStream=t;}processToolCalls(t){if(!(!t||t.length===0))for(let n of t)try{let r=JSON.parse(n.function.arguments),e=n.function.name;switch(e){case "create_document":this.handleCreateDocument(r,n.id);break;case "update_document":this.handleUpdateDocument(r,n.id);break;default:console.log(`[ComponentStream] Unknown tool: ${e}`);}}catch(r){console.error("[ComponentStream] Error processing tool call:",r);}}processToolResult(t){try{t.type==="artifact"?this.handleArtifactResult(t):t.type==="artifact_update"&&this.handleArtifactUpdate(t);}catch(n){console.error("[ComponentStream] Error processing tool result:",n);}}streamArtifact(t){this.dataStream.write({type:"data-kind",data:t.kind,transient:true}),this.dataStream.write({type:"data-id",data:t.id,transient:true}),this.dataStream.write({type:"data-title",data:t.title,transient:true}),this.dataStream.write({type:"data-clear",data:null,transient:true}),this.streamContent(t.content),this.dataStream.write({type:"data-finish",data:null,transient:true});}streamTextDelta(t){this.dataStream.write({type:"data-textDelta",data:t,transient:true});}streamContent(t,n=50){let r=this.splitIntoChunks(t,n);for(let e of r)this.dataStream.write({type:"data-textDelta",data:e,transient:true});}finish(){this.dataStream.write({type:"data-finish",data:null,transient:true});}handleCreateDocument(t,n){let{title:r,kind:e,content:o}=t,i=`doc_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;console.log(`[ComponentStream] Creating document: ${r} (${e})`),this.streamArtifact({id:i,kind:e,title:r,content:o}),this.dataStream.write({type:"tool-result",data:{toolCallId:n,toolName:"create_document",result:{id:i,title:r,kind:e,message:"Document created successfully"}}});}handleUpdateDocument(t,n){let{id:r,description:e,content:o}=t;console.log(`[ComponentStream] Updating document: ${r}`),this.dataStream.write({type:"data-clear",data:null,transient:true}),this.streamContent(o),this.dataStream.write({type:"data-finish",data:null,transient:true}),this.dataStream.write({type:"tool-result",data:{toolCallId:n,toolName:"update_document",result:{id:r,message:`Document updated: ${e}`}}});}handleArtifactResult(t){let{id:n,title:r,kind:e,content:o}=t;if(!n||!r||!e||!o){console.error("[ComponentStream] Invalid artifact result:",t);return}this.streamArtifact({id:n,kind:e,title:r,content:o});}handleArtifactUpdate(t){let{content:n}=t;if(!n){console.error("[ComponentStream] Invalid artifact update:",t);return}this.dataStream.write({type:"data-clear",data:null,transient:true}),this.streamContent(n),this.dataStream.write({type:"data-finish",data:null,transient:true});}splitIntoChunks(t,n){let r=[],e=t.split(" "),o="";for(let i=0;i<e.length;i++){let s=i===0?e[i]:" "+e[i];o.length+s.length>n&&o.length>0?(r.push(o),o=s.trim()):o+=s;}return o.length>0&&r.push(o),r}};function R(a){return !!(a?.tool_calls&&Array.isArray(a.tool_calls)&&a.tool_calls.length>0)}function A(a){try{let t=JSON.parse(a);if(t.type&&(t.type==="artifact"||t.type==="artifact_update"))return [t]}catch{}return []}function v(a){return new u(a)}export{u as ComponentStreamAdapter,d as SSEWriter,v as createComponentStreamAdapter,E as createSSEResponse,w as createSSEWriter,A as extractToolResults,R as hasToolCalls,y as parseSSEStream};
@@ -1,4 +1,4 @@
1
- export { A as ALL_CAPABILITIES_BITMASK, c as ActionProof, d as AddPointsInput, e as Agent, f as AgentCreateInput, g as AgentExecuteRequest, h as AgentExecuteResponse, i as AgentFromPromptInput, j as AgentResponse, k as AgentTrigger, l as AgentUpdateInput, m as AgentWorkflow, n as AgentWorkflowEdge, o as AgentWorkflowNode, p as AgentsClientConfig, q as AgentsListResponse, r as AllowlistConfig, s as AllowlistMode, t as AllowlistUpdateInput, u as AuthMetrics, B as BillingClientConfig, v as BillingPlan, w as BillingPlansResponse, x as BillingPortalResponse, y as BillingState, z as BillingTier, C as CAPABILITY_BITS, D as CapabilityKey, E as ChatCompletionChunk, F as ChatCompletionRequest, G as ChatCompletionResponse, H as CommentResponse, I as CommentsResponse, J as ConfigureOAuthInput, K as ConfigureStripeInput, L as ConfigureWeb3Input, M as ConsensusStateSummary, N as ConsensusStatus, O as ContextDomain, P as ContextResponse, Q as ContextsListResponse, R as CreateCheckoutSessionResponse, S as CreateContextInput, U as CreateDelegationInput, V as CreateDomainInput, W as CreateKeyResponse, X as CreatePostInput, Y as CreatePostResponse, Z as CreateStackRequest, _ as Delegation, $ as DelegationChainLink, a0 as DelegationFilters, a1 as DelegationResponse, a2 as DelegationScope, a3 as DelegationsListResponse, a4 as DomainResponse, a5 as DomainsListResponse, a6 as FeedResponse, a7 as FileUploadResponse, a8 as FilesClientConfig, a9 as HistoryFilters, aa as HistoryResponse, ab as ImaginationCharacter, ac as ImaginationMetadata, ad as ImaginationSource, ae as InitNetworkResponse, af as LeaderStatus, ag as LikeCheckResponse, ah as LikeResponse, ai as MCPContent, aj as MCPMessage, ak as MCPSession, al as MCPSessionConfig, am as MCPToolResult, an as MPCNode, ao as MagmaFile, ap as MediaType, aq as Message, ar as MeteredUsage, as as ModelLayerInfo, at as ModelLayersResponse, au as NetworkClientConfig, av as NetworkStatus, br as Orientation, aw as PaginationMeta, ax as PaymentRequiredResponse, ay as PointBalance, az as PointContext, aA as PointRecord, aB as PointRecordResponse, aC as PointSpend, aD as PointSpendResponse, aE as PointsClientConfig, aF as PostResponse, aG as ProfileResponse, aH as RemixesResponse, aI as Skill, aJ as SkillCreateInput, bp as SkillMapPromptResponse, bo as SkillMapResponse, aK as SkillResponse, bq as SkillSummaryResponse, aL as SkillUpdateInput, bn as SkillVerifyResponse, aM as SkillsClientConfig, aN as SkillsListResponse, aO as SocialAuthor, aP as SocialClientConfig, aQ as SocialComment, aR as SocialPost, aS as SocialRemix, aT as SpendDestination, aU as SpendPointsInput, aV as StackCapabilities, aW as StackConfig, aX as StackKeyInfo, aY as StackKeysListResponse, aZ as StackListResponse, a_ as StackManagementClientConfig, a$ as StackMember, b0 as StackMemberStats, b1 as StackModelAlias, b2 as StackOAuthProvider, b3 as StackResponse, b4 as StackStripeProvider, b5 as StackWeb3Provider, b6 as TaskPayload, b7 as TaskResponse, a as TaskState, b as TaskStatus, T as TaskType, b8 as UsageRecord, b9 as UserClientConfig, ba as UserProfile, bb as UserProfileResponse, bc as UserProfileUpdateInput, bd as Widget, be as WidgetCreateInput, bf as WidgetResponse, bg as WidgetSystemPromptResponse, bh as WidgetUpdateInput, bi as WidgetsClientConfig, bj as WidgetsListResponse, bk as WorkflowData, bl as bitmaskToCapabilities, bm as capabilitiesToBitmask } from '../billing-BaJlf_S8.cjs';
1
+ export { A as ALL_CAPABILITIES_BITMASK, c as ActionProof, d as AddPointsInput, e as Agent, f as AgentCreateInput, g as AgentExecuteRequest, h as AgentExecuteResponse, i as AgentFromPromptInput, j as AgentResponse, k as AgentTrigger, l as AgentUpdateInput, m as AgentWorkflow, n as AgentWorkflowEdge, o as AgentWorkflowNode, p as AgentsClientConfig, q as AgentsListResponse, r as AllowlistConfig, s as AllowlistMode, t as AllowlistUpdateInput, u as AuthMetrics, B as BillingClientConfig, v as BillingPlan, w as BillingPlansResponse, x as BillingPortalResponse, y as BillingState, z as BillingTier, C as CAPABILITY_BITS, D as CapabilityKey, E as ChatCompletionChunk, F as ChatCompletionRequest, G as ChatCompletionResponse, H as CommentResponse, I as CommentsResponse, J as ConfigureOAuthInput, K as ConfigureStripeInput, L as ConfigureWeb3Input, M as ConsensusStateSummary, N as ConsensusStatus, O as ContextDomain, P as ContextResponse, Q as ContextsListResponse, R as CreateCheckoutSessionResponse, S as CreateContextInput, U as CreateDelegationInput, V as CreateDomainInput, W as CreateKeyResponse, X as CreatePostInput, Y as CreatePostResponse, Z as CreateStackRequest, _ as Delegation, $ as DelegationChainLink, a0 as DelegationFilters, a1 as DelegationResponse, a2 as DelegationScope, a3 as DelegationsListResponse, a4 as DomainResponse, a5 as DomainsListResponse, a6 as FeedResponse, a7 as FileUploadResponse, a8 as FilesClientConfig, a9 as HistoryFilters, aa as HistoryResponse, ab as ImaginationCharacter, ac as ImaginationMetadata, ad as ImaginationSource, ae as InitNetworkResponse, af as LeaderStatus, ag as LikeCheckResponse, ah as LikeResponse, ai as MCPContent, aj as MCPMessage, ak as MCPSession, al as MCPSessionConfig, am as MCPToolResult, an as MPCNode, ao as MagmaFile, ap as MediaType, aq as Message, ar as MeteredUsage, as as ModelLayerInfo, at as ModelLayersResponse, au as NetworkClientConfig, av as NetworkStatus, br as Orientation, aw as PaginationMeta, bs as PaymentMethod, ax as PaymentRequiredResponse, ay as PointBalance, az as PointContext, aA as PointRecord, aB as PointRecordResponse, aC as PointSpend, aD as PointSpendResponse, aE as PointsClientConfig, aF as PostResponse, aG as ProfileResponse, aH as RemixesResponse, aI as Skill, aJ as SkillCreateInput, bp as SkillMapPromptResponse, bo as SkillMapResponse, aK as SkillResponse, bq as SkillSummaryResponse, aL as SkillUpdateInput, bn as SkillVerifyResponse, aM as SkillsClientConfig, aN as SkillsListResponse, aO as SocialAuthor, aP as SocialClientConfig, aQ as SocialComment, aR as SocialPost, aS as SocialRemix, bt as SolPrepaidResult, bu as SolSubscriptionResult, aT as SpendDestination, aU as SpendPointsInput, aV as StackCapabilities, aW as StackConfig, aX as StackKeyInfo, aY as StackKeysListResponse, aZ as StackListResponse, a_ as StackManagementClientConfig, a$ as StackMember, b0 as StackMemberStats, b1 as StackModelAlias, b2 as StackOAuthProvider, b3 as StackResponse, b4 as StackStripeProvider, b5 as StackWeb3Provider, b6 as TaskPayload, b7 as TaskResponse, a as TaskState, b as TaskStatus, T as TaskType, bv as TopupResult, b8 as UsageRecord, b9 as UserClientConfig, ba as UserProfile, bb as UserProfileResponse, bc as UserProfileUpdateInput, bd as Widget, be as WidgetCreateInput, bf as WidgetResponse, bg as WidgetSystemPromptResponse, bh as WidgetUpdateInput, bi as WidgetsClientConfig, bj as WidgetsListResponse, bk as WorkflowData, bl as bitmaskToCapabilities, bm as capabilitiesToBitmask } from '../billing-eQZIWeNW.cjs';
2
2
 
3
3
  /**
4
4
  * Coder type definitions
@@ -1,4 +1,4 @@
1
- export { A as ALL_CAPABILITIES_BITMASK, c as ActionProof, d as AddPointsInput, e as Agent, f as AgentCreateInput, g as AgentExecuteRequest, h as AgentExecuteResponse, i as AgentFromPromptInput, j as AgentResponse, k as AgentTrigger, l as AgentUpdateInput, m as AgentWorkflow, n as AgentWorkflowEdge, o as AgentWorkflowNode, p as AgentsClientConfig, q as AgentsListResponse, r as AllowlistConfig, s as AllowlistMode, t as AllowlistUpdateInput, u as AuthMetrics, B as BillingClientConfig, v as BillingPlan, w as BillingPlansResponse, x as BillingPortalResponse, y as BillingState, z as BillingTier, C as CAPABILITY_BITS, D as CapabilityKey, E as ChatCompletionChunk, F as ChatCompletionRequest, G as ChatCompletionResponse, H as CommentResponse, I as CommentsResponse, J as ConfigureOAuthInput, K as ConfigureStripeInput, L as ConfigureWeb3Input, M as ConsensusStateSummary, N as ConsensusStatus, O as ContextDomain, P as ContextResponse, Q as ContextsListResponse, R as CreateCheckoutSessionResponse, S as CreateContextInput, U as CreateDelegationInput, V as CreateDomainInput, W as CreateKeyResponse, X as CreatePostInput, Y as CreatePostResponse, Z as CreateStackRequest, _ as Delegation, $ as DelegationChainLink, a0 as DelegationFilters, a1 as DelegationResponse, a2 as DelegationScope, a3 as DelegationsListResponse, a4 as DomainResponse, a5 as DomainsListResponse, a6 as FeedResponse, a7 as FileUploadResponse, a8 as FilesClientConfig, a9 as HistoryFilters, aa as HistoryResponse, ab as ImaginationCharacter, ac as ImaginationMetadata, ad as ImaginationSource, ae as InitNetworkResponse, af as LeaderStatus, ag as LikeCheckResponse, ah as LikeResponse, ai as MCPContent, aj as MCPMessage, ak as MCPSession, al as MCPSessionConfig, am as MCPToolResult, an as MPCNode, ao as MagmaFile, ap as MediaType, aq as Message, ar as MeteredUsage, as as ModelLayerInfo, at as ModelLayersResponse, au as NetworkClientConfig, av as NetworkStatus, br as Orientation, aw as PaginationMeta, ax as PaymentRequiredResponse, ay as PointBalance, az as PointContext, aA as PointRecord, aB as PointRecordResponse, aC as PointSpend, aD as PointSpendResponse, aE as PointsClientConfig, aF as PostResponse, aG as ProfileResponse, aH as RemixesResponse, aI as Skill, aJ as SkillCreateInput, bp as SkillMapPromptResponse, bo as SkillMapResponse, aK as SkillResponse, bq as SkillSummaryResponse, aL as SkillUpdateInput, bn as SkillVerifyResponse, aM as SkillsClientConfig, aN as SkillsListResponse, aO as SocialAuthor, aP as SocialClientConfig, aQ as SocialComment, aR as SocialPost, aS as SocialRemix, aT as SpendDestination, aU as SpendPointsInput, aV as StackCapabilities, aW as StackConfig, aX as StackKeyInfo, aY as StackKeysListResponse, aZ as StackListResponse, a_ as StackManagementClientConfig, a$ as StackMember, b0 as StackMemberStats, b1 as StackModelAlias, b2 as StackOAuthProvider, b3 as StackResponse, b4 as StackStripeProvider, b5 as StackWeb3Provider, b6 as TaskPayload, b7 as TaskResponse, a as TaskState, b as TaskStatus, T as TaskType, b8 as UsageRecord, b9 as UserClientConfig, ba as UserProfile, bb as UserProfileResponse, bc as UserProfileUpdateInput, bd as Widget, be as WidgetCreateInput, bf as WidgetResponse, bg as WidgetSystemPromptResponse, bh as WidgetUpdateInput, bi as WidgetsClientConfig, bj as WidgetsListResponse, bk as WorkflowData, bl as bitmaskToCapabilities, bm as capabilitiesToBitmask } from '../billing-BaJlf_S8.js';
1
+ export { A as ALL_CAPABILITIES_BITMASK, c as ActionProof, d as AddPointsInput, e as Agent, f as AgentCreateInput, g as AgentExecuteRequest, h as AgentExecuteResponse, i as AgentFromPromptInput, j as AgentResponse, k as AgentTrigger, l as AgentUpdateInput, m as AgentWorkflow, n as AgentWorkflowEdge, o as AgentWorkflowNode, p as AgentsClientConfig, q as AgentsListResponse, r as AllowlistConfig, s as AllowlistMode, t as AllowlistUpdateInput, u as AuthMetrics, B as BillingClientConfig, v as BillingPlan, w as BillingPlansResponse, x as BillingPortalResponse, y as BillingState, z as BillingTier, C as CAPABILITY_BITS, D as CapabilityKey, E as ChatCompletionChunk, F as ChatCompletionRequest, G as ChatCompletionResponse, H as CommentResponse, I as CommentsResponse, J as ConfigureOAuthInput, K as ConfigureStripeInput, L as ConfigureWeb3Input, M as ConsensusStateSummary, N as ConsensusStatus, O as ContextDomain, P as ContextResponse, Q as ContextsListResponse, R as CreateCheckoutSessionResponse, S as CreateContextInput, U as CreateDelegationInput, V as CreateDomainInput, W as CreateKeyResponse, X as CreatePostInput, Y as CreatePostResponse, Z as CreateStackRequest, _ as Delegation, $ as DelegationChainLink, a0 as DelegationFilters, a1 as DelegationResponse, a2 as DelegationScope, a3 as DelegationsListResponse, a4 as DomainResponse, a5 as DomainsListResponse, a6 as FeedResponse, a7 as FileUploadResponse, a8 as FilesClientConfig, a9 as HistoryFilters, aa as HistoryResponse, ab as ImaginationCharacter, ac as ImaginationMetadata, ad as ImaginationSource, ae as InitNetworkResponse, af as LeaderStatus, ag as LikeCheckResponse, ah as LikeResponse, ai as MCPContent, aj as MCPMessage, ak as MCPSession, al as MCPSessionConfig, am as MCPToolResult, an as MPCNode, ao as MagmaFile, ap as MediaType, aq as Message, ar as MeteredUsage, as as ModelLayerInfo, at as ModelLayersResponse, au as NetworkClientConfig, av as NetworkStatus, br as Orientation, aw as PaginationMeta, bs as PaymentMethod, ax as PaymentRequiredResponse, ay as PointBalance, az as PointContext, aA as PointRecord, aB as PointRecordResponse, aC as PointSpend, aD as PointSpendResponse, aE as PointsClientConfig, aF as PostResponse, aG as ProfileResponse, aH as RemixesResponse, aI as Skill, aJ as SkillCreateInput, bp as SkillMapPromptResponse, bo as SkillMapResponse, aK as SkillResponse, bq as SkillSummaryResponse, aL as SkillUpdateInput, bn as SkillVerifyResponse, aM as SkillsClientConfig, aN as SkillsListResponse, aO as SocialAuthor, aP as SocialClientConfig, aQ as SocialComment, aR as SocialPost, aS as SocialRemix, bt as SolPrepaidResult, bu as SolSubscriptionResult, aT as SpendDestination, aU as SpendPointsInput, aV as StackCapabilities, aW as StackConfig, aX as StackKeyInfo, aY as StackKeysListResponse, aZ as StackListResponse, a_ as StackManagementClientConfig, a$ as StackMember, b0 as StackMemberStats, b1 as StackModelAlias, b2 as StackOAuthProvider, b3 as StackResponse, b4 as StackStripeProvider, b5 as StackWeb3Provider, b6 as TaskPayload, b7 as TaskResponse, a as TaskState, b as TaskStatus, T as TaskType, bv as TopupResult, b8 as UsageRecord, b9 as UserClientConfig, ba as UserProfile, bb as UserProfileResponse, bc as UserProfileUpdateInput, bd as Widget, be as WidgetCreateInput, bf as WidgetResponse, bg as WidgetSystemPromptResponse, bh as WidgetUpdateInput, bi as WidgetsClientConfig, bj as WidgetsListResponse, bk as WorkflowData, bl as bitmaskToCapabilities, bm as capabilitiesToBitmask } from '../billing-eQZIWeNW.js';
2
2
 
3
3
  /**
4
4
  * Coder type definitions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacknet/stacks",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "SDK for connecting to StackNet",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -22,11 +22,25 @@ export type { AgentsClientConfig } from '../types/agent';
22
22
  export class AgentsClient {
23
23
  private baseUrl: string;
24
24
  private useCpxApi: boolean;
25
+ private authToken: string | null;
25
26
 
26
27
  constructor(config: AgentsClientConfig = {}) {
27
28
  this.baseUrl = config.baseUrl || DEFAULT_TASK_NETWORK_URL;
28
29
  // Use coprocessor API by default (can be disabled for backwards compatibility)
29
30
  this.useCpxApi = config.useCpxApi !== false;
31
+ this.authToken = config.authToken || null;
32
+ }
33
+
34
+ setAuthToken(token: string | null) {
35
+ this.authToken = token;
36
+ }
37
+
38
+ private get headers(): Record<string, string> {
39
+ const h: Record<string, string> = { ...JSON_HEADERS };
40
+ if (this.authToken) {
41
+ h['Authorization'] = `Bearer ${this.authToken}`;
42
+ }
43
+ return h;
30
44
  }
31
45
 
32
46
  private get agentsUrl(): string {
@@ -48,7 +62,7 @@ export class AgentsClient {
48
62
  const queryString = params.toString();
49
63
  const url = `${this.agentsUrl}${queryString ? `?${queryString}` : ''}`;
50
64
 
51
- const response = await fetch(url);
65
+ const response = await fetch(url, { headers: this.headers });
52
66
 
53
67
  if (!response.ok) {
54
68
  throw new StacksSDKError(
@@ -64,7 +78,7 @@ export class AgentsClient {
64
78
  * Get an agent by ID
65
79
  */
66
80
  async get(id: string): Promise<Agent> {
67
- const response = await fetch(`${this.agentsUrl}/${id}`);
81
+ const response = await fetch(`${this.agentsUrl}/${id}`, { headers: this.headers });
68
82
 
69
83
  if (!response.ok) {
70
84
  throw new StacksSDKError(
@@ -82,7 +96,7 @@ export class AgentsClient {
82
96
  async create(input: AgentCreateInput): Promise<AgentResponse> {
83
97
  const response = await fetch(this.agentsUrl, {
84
98
  method: 'POST',
85
- headers: JSON_HEADERS,
99
+ headers: this.headers,
86
100
  body: JSON.stringify(input),
87
101
  });
88
102
 
@@ -103,7 +117,7 @@ export class AgentsClient {
103
117
  async update(id: string, input: AgentUpdateInput): Promise<AgentResponse> {
104
118
  const response = await fetch(`${this.agentsUrl}/${id}`, {
105
119
  method: 'PUT',
106
- headers: JSON_HEADERS,
120
+ headers: this.headers,
107
121
  body: JSON.stringify(input),
108
122
  });
109
123
 
@@ -124,6 +138,7 @@ export class AgentsClient {
124
138
  async delete(id: string): Promise<{ success: boolean }> {
125
139
  const response = await fetch(`${this.agentsUrl}/${id}`, {
126
140
  method: 'DELETE',
141
+ headers: this.headers,
127
142
  });
128
143
 
129
144
  if (!response.ok) {
@@ -142,6 +157,7 @@ export class AgentsClient {
142
157
  async enable(id: string): Promise<AgentResponse> {
143
158
  const response = await fetch(`${this.agentsUrl}/${id}/enable`, {
144
159
  method: 'POST',
160
+ headers: this.headers,
145
161
  });
146
162
 
147
163
  if (!response.ok) {
@@ -160,6 +176,7 @@ export class AgentsClient {
160
176
  async disable(id: string): Promise<AgentResponse> {
161
177
  const response = await fetch(`${this.agentsUrl}/${id}/disable`, {
162
178
  method: 'POST',
179
+ headers: this.headers,
163
180
  });
164
181
 
165
182
  if (!response.ok) {
@@ -178,7 +195,7 @@ export class AgentsClient {
178
195
  async execute(id: string, request: AgentExecuteRequest = {}): Promise<AgentExecuteResponse> {
179
196
  const response = await fetch(`${this.agentsUrl}/${id}/execute`, {
180
197
  method: 'POST',
181
- headers: JSON_HEADERS,
198
+ headers: this.headers,
182
199
  body: JSON.stringify(request),
183
200
  });
184
201
 
@@ -199,7 +216,7 @@ export class AgentsClient {
199
216
  // First, generate agent config from prompt
200
217
  const generateResponse = await fetch(`${this.agentsUrl}/from-prompt`, {
201
218
  method: 'POST',
202
- headers: JSON_HEADERS,
219
+ headers: this.headers,
203
220
  body: JSON.stringify(input),
204
221
  });
205
222
 
@@ -142,6 +142,46 @@ export class BillingClient {
142
142
  async hasPaymentMethod(stackId: string, identityId: string): Promise<{ has_payment_method: boolean; card_last_four?: string; card_brand?: string }> {
143
143
  return this.request('GET', `/stacks/${stackId}/identities/${identityId}/billing/payment-method`);
144
144
  }
145
+
146
+ // =========================================================================
147
+ // SOL Payment Methods (additive — Stripe methods above remain unchanged)
148
+ // =========================================================================
149
+
150
+ /**
151
+ * Subscribe to a plan using SOL payment.
152
+ * Client must build and sign the SOL transaction first,
153
+ * then pass the on-chain tx signature here for verification.
154
+ */
155
+ async subscribeSol(
156
+ stackId: string,
157
+ planId: string,
158
+ txSignature: string,
159
+ ): Promise<{ subscription: { id: string; planId: string; planName: string; status: string; tokensGranted: number } }> {
160
+ return this.request('POST', `/stacks/${stackId}/subscribe-sol`, { planId, txSignature });
161
+ }
162
+
163
+ /**
164
+ * One-time prepaid credit via SOL payment.
165
+ */
166
+ async prepaidSol(
167
+ stackId: string,
168
+ amountCents: number,
169
+ txSignature: string,
170
+ scope?: 'global' | 'stack',
171
+ ): Promise<{ alreadyCredited: boolean; tokensCredited?: number; amountCents?: number; paymentRef?: string }> {
172
+ return this.request('POST', `/stacks/${stackId}/prepaid-sol`, { amountCents, txSignature, scope });
173
+ }
174
+
175
+ /**
176
+ * Top up account via x402 payment proof (SOL or Stripe).
177
+ */
178
+ async topup(
179
+ amountCents: number,
180
+ paymentMethod: 'solana' | 'stripe',
181
+ paymentRef: string,
182
+ ): Promise<{ success: boolean; tokensCredited: number; tokenBalance: number }> {
183
+ return this.request('POST', '/account/topup', { amount_cents: amountCents, payment_method: paymentMethod, payment_ref: paymentRef });
184
+ }
145
185
  }
146
186
 
147
187
  /**
@@ -256,12 +256,34 @@ export class TaskManager {
256
256
  const channel = `task:progress:${taskId}`;
257
257
 
258
258
  await redis.subscribe(channel, (message) => {
259
+ let data: unknown;
259
260
  try {
260
- const data = JSON.parse(message);
261
- callback(data);
261
+ data = JSON.parse(message);
262
262
  } catch {
263
- // Ignore parse errors
263
+ return; // not JSON — ignore
264
264
  }
265
+ // Shape-check: Redis pub/sub is a trust boundary. If anything else
266
+ // (a compromised publisher, a misconfigured tenant, or an operator
267
+ // pushing test data) posts to this channel, the message reaches
268
+ // this callback. Drop anything that doesn't match our own
269
+ // publisher's shape before handing it to consumer code — otherwise
270
+ // an attacker with publish access could inject arbitrary objects
271
+ // (prototype keys, unexpected fields) into the UI layer.
272
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return;
273
+ const d = data as Record<string, unknown>;
274
+ if (typeof d.taskId !== 'string' || d.taskId !== taskId) return;
275
+ if (typeof d.status !== 'string') return;
276
+ if (d.progress !== undefined && typeof d.progress !== 'number') return;
277
+ if (d.message !== undefined && typeof d.message !== 'string') return;
278
+ if (d.error !== undefined && typeof d.error !== 'string') return;
279
+ callback({
280
+ taskId: d.taskId,
281
+ status: d.status as TaskStatus,
282
+ progress: d.progress as number | undefined,
283
+ message: d.message as string | undefined,
284
+ result: d.result,
285
+ error: d.error as string | undefined,
286
+ });
265
287
  });
266
288
 
267
289
  return async () => {
@@ -7,7 +7,13 @@ import { DEFAULT_TASK_NETWORK_URL } from '../utils/constants';
7
7
  export interface ForwarderConfig {
8
8
  baseUrl?: string;
9
9
  defaultHeaders?: Record<string, string>;
10
+ /** Request timeout in milliseconds. Applied via AbortSignal to every
11
+ * outbound fetch. Default: 30_000 (30s). Previously declared but not
12
+ * wired — an upstream hang would leak file descriptors indefinitely. */
10
13
  timeout?: number;
14
+ /** Hard cap on inbound JSON body size (bytes) read by `createProxyHandler`.
15
+ * Requests larger than this are rejected with 413. Default: 1 MiB. */
16
+ maxBodyBytes?: number;
11
17
  }
12
18
 
13
19
  export interface RequestOptions {
@@ -18,6 +24,42 @@ export interface RequestOptions {
18
24
  stream?: boolean;
19
25
  }
20
26
 
27
+ const DEFAULT_TIMEOUT_MS = 30_000;
28
+ const DEFAULT_MAX_BODY_BYTES = 1024 * 1024; // 1 MiB
29
+
30
+ /** Headers that are safe to forward from an inbound request to the upstream.
31
+ * `createProxyHandler` previously copied every inbound header — including
32
+ * `cookie`, attacker-set `x-forwarded-for`, and the consumer app's session
33
+ * cookies — to an arbitrary upstream. Only the headers that carry request
34
+ * semantics (auth + content negotiation + a request id for tracing) are
35
+ * preserved now. */
36
+ const FORWARDABLE_REQUEST_HEADERS = new Set([
37
+ 'authorization',
38
+ 'content-type',
39
+ 'accept',
40
+ 'accept-language',
41
+ 'x-request-id',
42
+ 'x-correlation-id',
43
+ 'idempotency-key',
44
+ ]);
45
+
46
+ /** Build the outbound URL by resolving `path` relative to `baseUrl`. Using
47
+ * the URL constructor here (instead of string concatenation) prevents a
48
+ * path like ".evil.com/x" from producing an unintended host.
49
+ * Throws if the resolved URL escapes the baseUrl origin. */
50
+ function resolveUrl(baseUrl: string, path: string): string {
51
+ // Ensure baseUrl ends with '/' so URL() treats it as a directory root.
52
+ const baseForResolve = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;
53
+ // Drop leading '/' on path so it doesn't replace the baseUrl pathname.
54
+ const rel = path.startsWith('/') ? path.slice(1) : path;
55
+ const resolved = new URL(rel, baseForResolve);
56
+ const base = new URL(baseForResolve);
57
+ if (resolved.origin !== base.origin) {
58
+ throw new Error(`forwarder: resolved URL ${resolved.origin} escapes baseUrl origin ${base.origin}`);
59
+ }
60
+ return resolved.toString();
61
+ }
62
+
21
63
  /**
22
64
  * Forward a request to a backend URL
23
65
  */
@@ -29,19 +71,14 @@ export async function forwardRequest(
29
71
  const baseUrl = config.baseUrl || DEFAULT_TASK_NETWORK_URL;
30
72
  const { method = 'GET', headers = {}, body, searchParams, stream } = options;
31
73
 
32
- // Build URL with search params
33
- let url = `${baseUrl}${path}`;
74
+ // Build URL safely, then attach search params.
75
+ const urlObj = new URL(resolveUrl(baseUrl, path));
34
76
  if (searchParams) {
35
- const params = new URLSearchParams();
36
77
  Object.entries(searchParams).forEach(([key, value]) => {
37
78
  if (value !== undefined) {
38
- params.set(key, value);
79
+ urlObj.searchParams.set(key, value);
39
80
  }
40
81
  });
41
- const paramString = params.toString();
42
- if (paramString) {
43
- url += `?${paramString}`;
44
- }
45
82
  }
46
83
 
47
84
  const fetchOptions: RequestInit = {
@@ -50,6 +87,7 @@ export async function forwardRequest(
50
87
  ...config.defaultHeaders,
51
88
  ...headers,
52
89
  },
90
+ signal: AbortSignal.timeout(config.timeout ?? DEFAULT_TIMEOUT_MS),
53
91
  };
54
92
 
55
93
  if (body && method !== 'GET') {
@@ -60,7 +98,7 @@ export async function forwardRequest(
60
98
  fetchOptions.body = JSON.stringify(body);
61
99
  }
62
100
 
63
- const response = await fetch(url, fetchOptions);
101
+ const response = await fetch(urlObj.toString(), fetchOptions);
64
102
 
65
103
  // For streaming responses, return directly
66
104
  if (stream && response.body) {
@@ -83,13 +121,59 @@ export async function forwardJSON<T = unknown>(
83
121
  return { data, status: response.status };
84
122
  }
85
123
 
124
+ /** Read a request body with a hard byte cap. Returns `null` if the body
125
+ * exceeds the cap, so the caller can return 413 without first buffering
126
+ * an attacker-sized payload into memory. */
127
+ async function readBodyCapped(request: Request, maxBytes: number): Promise<unknown | { _tooLarge: true }> {
128
+ const contentLength = request.headers.get('content-length');
129
+ if (contentLength) {
130
+ const n = parseInt(contentLength, 10);
131
+ if (Number.isFinite(n) && n > maxBytes) return { _tooLarge: true };
132
+ }
133
+ if (!request.body) return undefined;
134
+ const reader = request.body.getReader();
135
+ let received = 0;
136
+ const chunks: Uint8Array[] = [];
137
+ // Streaming read with byte cap — aborts as soon as the cap is exceeded.
138
+ // eslint-disable-next-line no-constant-condition
139
+ while (true) {
140
+ const { done, value } = await reader.read();
141
+ if (done) break;
142
+ received += value.byteLength;
143
+ if (received > maxBytes) {
144
+ try { await reader.cancel(); } catch { /* ignore */ }
145
+ return { _tooLarge: true };
146
+ }
147
+ chunks.push(value);
148
+ }
149
+ if (received === 0) return undefined;
150
+ const buf = new Uint8Array(received);
151
+ let offset = 0;
152
+ for (const c of chunks) { buf.set(c, offset); offset += c.byteLength; }
153
+ const text = new TextDecoder().decode(buf);
154
+ if (text.trim() === '') return undefined;
155
+ try {
156
+ return JSON.parse(text);
157
+ } catch {
158
+ return undefined;
159
+ }
160
+ }
161
+
86
162
  /**
87
- * Create a proxy handler that forwards requests
163
+ * Create a proxy handler that forwards requests.
164
+ *
165
+ * SECURITY: only a small whitelist of inbound headers is forwarded (see
166
+ * FORWARDABLE_REQUEST_HEADERS). Everything else — including `cookie`,
167
+ * `x-forwarded-for`, `host` — is stripped so a caller cannot poison the
168
+ * upstream's view of the request or smuggle the consumer app's cookies to
169
+ * a third-party StackNet endpoint.
88
170
  */
89
171
  export function createProxyHandler(
90
172
  path: string | ((req: Request) => string),
91
173
  config: ForwarderConfig = {}
92
174
  ) {
175
+ const maxBodyBytes = config.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
176
+
93
177
  return async (request: Request): Promise<Response> => {
94
178
  const url = new URL(request.url);
95
179
  const targetPath = typeof path === 'function' ? path(request) : path;
@@ -102,17 +186,22 @@ export function createProxyHandler(
102
186
 
103
187
  let body: unknown = undefined;
104
188
  if (request.method !== 'GET' && request.method !== 'HEAD') {
105
- try {
106
- body = await request.json();
107
- } catch {
108
- // No body or not JSON
189
+ const read = await readBodyCapped(request, maxBodyBytes);
190
+ if (read && typeof read === 'object' && (read as { _tooLarge?: boolean })._tooLarge) {
191
+ return Response.json(
192
+ { error: `Request body exceeds ${maxBodyBytes} bytes` },
193
+ { status: 413 },
194
+ );
109
195
  }
196
+ body = read;
110
197
  }
111
198
 
112
- // Extract headers
199
+ // Forward ONLY the whitelisted headers.
113
200
  const requestHeaders: Record<string, string> = {};
114
201
  request.headers.forEach((value, key) => {
115
- requestHeaders[key] = value;
202
+ if (FORWARDABLE_REQUEST_HEADERS.has(key.toLowerCase())) {
203
+ requestHeaders[key] = value;
204
+ }
116
205
  });
117
206
 
118
207
  const response = await forwardRequest(