@zibby/skills 0.1.54 → 0.1.55
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/datasetStore.d.ts +35 -0
- package/dist/datasetStore.js +17 -6
- package/dist/index.js +80 -69
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/datasetStore.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export namespace datasetStoreSkill {
|
|
|
49
49
|
limit?: undefined;
|
|
50
50
|
since?: undefined;
|
|
51
51
|
until?: undefined;
|
|
52
|
+
sql?: undefined;
|
|
53
|
+
params?: undefined;
|
|
52
54
|
};
|
|
53
55
|
required: string[];
|
|
54
56
|
};
|
|
@@ -96,8 +98,41 @@ export namespace datasetStoreSkill {
|
|
|
96
98
|
};
|
|
97
99
|
record?: undefined;
|
|
98
100
|
description?: undefined;
|
|
101
|
+
sql?: undefined;
|
|
102
|
+
params?: undefined;
|
|
99
103
|
};
|
|
100
104
|
required: any[];
|
|
101
105
|
};
|
|
106
|
+
} | {
|
|
107
|
+
name: string;
|
|
108
|
+
description: string;
|
|
109
|
+
input_schema: {
|
|
110
|
+
type: string;
|
|
111
|
+
properties: {
|
|
112
|
+
store: {
|
|
113
|
+
type: string;
|
|
114
|
+
description: string;
|
|
115
|
+
};
|
|
116
|
+
sql: {
|
|
117
|
+
type: string;
|
|
118
|
+
description: string;
|
|
119
|
+
};
|
|
120
|
+
params: {
|
|
121
|
+
type: string;
|
|
122
|
+
description: string;
|
|
123
|
+
};
|
|
124
|
+
record?: undefined;
|
|
125
|
+
description?: undefined;
|
|
126
|
+
agent?: undefined;
|
|
127
|
+
select?: undefined;
|
|
128
|
+
where?: undefined;
|
|
129
|
+
groupBy?: undefined;
|
|
130
|
+
orderBy?: undefined;
|
|
131
|
+
limit?: undefined;
|
|
132
|
+
since?: undefined;
|
|
133
|
+
until?: undefined;
|
|
134
|
+
};
|
|
135
|
+
required: string[];
|
|
136
|
+
};
|
|
102
137
|
})[];
|
|
103
138
|
}
|
package/dist/datasetStore.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{existsSync as c,readFileSync as
|
|
1
|
+
import{existsSync as c,readFileSync as p}from"node:fs";import{homedir as l}from"node:os";import{join as u,dirname as y,resolve as m}from"node:path";import{fileURLToPath as f}from"node:url";function E(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let r=y(f(import.meta.url)),t=m(r,"..","bin","mcp-skill.mjs");return c(t)?t:null}function g(){if(process.env.PROJECT_API_TOKEN)return process.env.PROJECT_API_TOKEN;if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{let r=u(l(),".zibby","config.json");return c(r)&&JSON.parse(p(r,"utf-8")).sessionToken||null}catch{return null}}function h(){return process.env.ZIBBY_ACCOUNT_API_URL?process.env.ZIBBY_ACCOUNT_API_URL.replace(/\/$/,""):(process.env.ZIBBY_ENV||"prod")==="local"?"http://localhost:3001":process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://api-prod.zibby.app"}function T(){return(typeof process.env.WORKFLOW_TYPE=="string"?process.env.WORKFLOW_TYPE.trim():"")||"agent"}function S(){let r={};for(let[t,e]of Object.entries(process.env)){let o=/^ZIBBY_STORE__(.+)$/.exec(t);if(!o)continue;let s=typeof e=="string"?e.trim():"";s&&(r[o[1]]=s)}return r}function a(r){let t=S(),e=Object.keys(t),o=typeof r=="string"?r.trim():"";return o?Object.prototype.hasOwnProperty.call(t,o)?{storeId:t[o],name:o}:{error:`unknown store '${o}'; available: ${e.join(", ")}`}:e.length===1?{storeId:t[e[0]],name:e[0]}:e.length===0?{error:"no stores bound to this agent"}:{error:`multiple stores are bound; pass \`store\` (one of: ${e.join(", ")})`}}async function i(r,t,e){let o=g();if(!o)throw new Error("No backend credential (PROJECT_API_TOKEN). Dataset store is only available inside a Zibby run.");let s=`${h()}/datasets/stores/${encodeURIComponent(r)}/${t}`,n=await fetch(s,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify(e)});if(!n.ok){let d=await n.text().catch(()=>"");throw new Error(`Store ${t} failed (${n.status}): ${d.slice(0,300)}`)}return n.json()}var I={id:"dataset-store",serverName:"dataset_store",allowedTools:["mcp__dataset_store__*"],description:"Dataset store \u2014 a durable, queryable store for structured JSON records; append rows now, run SQL-style aggregations/reports later",promptFragment:`## Dataset Store (durable, queryable structured-record store)
|
|
2
2
|
You have one or more durable stores for STRUCTURED records that survive across
|
|
3
3
|
your stateless runs. Unlike key-value memory (for picking up where you left
|
|
4
4
|
off), this is for accumulating DATA you want to QUERY and AGGREGATE later \u2014 e.g.
|
|
@@ -11,9 +11,20 @@ omit \`store\` and it defaults to that one. You can ONLY write to a bound store
|
|
|
11
11
|
name; any other name is rejected. Each appended record is an arbitrary JSON
|
|
12
12
|
object, auto-tagged with YOUR agent type so you can later filter to your writes.
|
|
13
13
|
|
|
14
|
+
There are TWO kinds of bound store (shown as TYPE in AVAILABLE STORES):
|
|
15
|
+
\u2022 dataset \u2014 append-only structured records you QUERY/AGGREGATE later (analytics).
|
|
16
|
+
\u2022 sqlite \u2014 a real, MUTABLE relational database (a SQLite file per store): CREATE
|
|
17
|
+
TABLE on the fly, INSERT/UPDATE/DELETE, SELECT. Schema + data persist across
|
|
18
|
+
runs. Use this when you need to UPDATE rows / track changing state (e.g. a
|
|
19
|
+
queue with a status column), not just append.
|
|
20
|
+
|
|
14
21
|
Tools:
|
|
15
|
-
- dataset_append: Append ONE structured JSON \`record
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
- dataset_append: (dataset stores) Append ONE structured JSON \`record\`.
|
|
23
|
+
- dataset_query: (dataset stores) SQL-style select/aggregate over appended records.
|
|
24
|
+
- sqlite_exec: (sqlite stores) Run SQL that CHANGES data \u2014 CREATE TABLE / INSERT /
|
|
25
|
+
UPDATE / DELETE (one or more statements). Idempotent DDL: use CREATE TABLE IF
|
|
26
|
+
NOT EXISTS. Returns { rowsModified, wrote }.
|
|
27
|
+
- sqlite_query: (sqlite stores) Run a SELECT (optionally with \`params\` for safe
|
|
28
|
+
binding). Returns { columns, rows }. Read-only \u2014 never changes data.
|
|
29
|
+
Pick the tool that matches the store's TYPE; using a dataset tool on a sqlite
|
|
30
|
+
store (or vice-versa) is rejected.`,resolve(){let r=E();if(!r)return{command:null,args:[],env:{},description:this.description};let t={};for(let e of["PROJECT_API_TOKEN","ZIBBY_ACCOUNT_API_URL","ZIBBY_ENV","ZIBBY_PROD_ACCOUNT_API_URL","ZIBBY_USER_TOKEN","WORKFLOW_TYPE"])process.env[e]&&(t[e]=process.env[e]);for(let e of Object.keys(process.env))/^ZIBBY_STORE__.+$/.test(e)&&process.env[e]&&(t[e]=process.env[e]);return{type:"stdio",command:"node",args:[r,"../dist/datasetStore.js","datasetStoreSkill"],env:t,description:this.description,alwaysLoad:!1}},async handleToolCall(r,t){try{switch(r){case"dataset_append":{if(t?.record==null||typeof t.record!="object"||Array.isArray(t.record))return JSON.stringify({error:"record is required (a JSON object)"});let e=a(t?.store);if(e.error)return JSON.stringify({error:e.error});let o=typeof t?.agent=="string"&&t.agent.trim()?t.agent.trim():T(),s={record:t.record,agent:o};typeof t?.description=="string"&&t.description.trim()&&(s.description=t.description.trim());let n=await i(e.storeId,"append",s);return JSON.stringify({...n,store:e.name,storeId:e.storeId})}case"dataset_query":{let e=a(t?.store);if(e.error)return JSON.stringify({error:e.error});let o={};for(let n of["select","where","groupBy","orderBy","limit","since","until","agent"])t?.[n]!=null&&(o[n]=t[n]);let s=await i(e.storeId,"query",o);return JSON.stringify({...s,store:e.name,storeId:e.storeId})}case"sqlite_exec":case"sqlite_query":{let e=a(t?.store);if(e.error)return JSON.stringify({error:e.error});if(typeof t?.sql!="string"||!t.sql.trim())return JSON.stringify({error:"sql is required (a non-empty SQL string)"});let o={sql:t.sql};Array.isArray(t?.params)&&(o.params=t.params);let s=await i(e.storeId,"sql",o);return JSON.stringify({...s,store:e.name,storeId:e.storeId})}default:return JSON.stringify({error:`Unknown tool: ${r}`})}}catch(e){return JSON.stringify({error:e.message})}},tools:[{name:"dataset_append",description:"Append ONE structured JSON record to a bound store, durably. Records persist across your stateless runs and are auto-tagged with your agent type so you can filter to your own writes later. Use to accumulate data you will query/aggregate (e.g. per-run metrics, processed items). Append ONE record per call.",input_schema:{type:"object",properties:{store:{type:"string",description:'The logical store NAME to write to (e.g. "scorecards"), taken from the AVAILABLE STORES list \u2014 pick by description. NOT an id. If exactly one store is bound you may omit this and it defaults to that store; you can ONLY write to a bound store name.'},record:{type:"object",description:'An arbitrary JSON object \u2014 one row of data. Its keys become queryable fields (e.g. {"repo":"owner/x","stars":1200}). One record per call.'},description:{type:"string",description:"Optional, informational note about this write. The store already exists from deploy, so this is not required and does not create anything."},agent:{type:"string",description:"Optional writing-agent tag. Defaults to your own agent type \u2014 leave unset to auto-tag."}},required:["record"]}},{name:"dataset_query",description:"Run a SQL-style query over a bound store to build reports: select/aggregate (count|sum|avg|min|max), filter, group, order, limit, and bound by month. Returns { columns, rows }. Use this to compute summaries/aggregations from records you appended earlier.",input_schema:{type:"object",properties:{store:{type:"string",description:'The logical store NAME to query (e.g. "scorecards"), taken from the AVAILABLE STORES list \u2014 pick by description. NOT an id. If exactly one store is bound you may omit this and it defaults to that store.'},select:{type:"array",description:"Columns to return. Each item is { field?, agg?, as? }. agg \u2208 count|sum|avg|min|max; omit field for count(*). Omit `select` entirely to return raw rows."},where:{type:"array",description:"Filters, ANDed. Each item is { field, op, value }; op \u2208 eq|ne|gt|gte|lt|lte|like. `field` is a JSON key of the stored record."},groupBy:{type:"array",description:"Field names to group by (array of strings) for aggregation."},orderBy:{type:"array",description:"Sort spec. Each item is { field|as, dir }; dir \u2208 asc|desc."},limit:{type:"number",description:"Maximum number of rows to return."},since:{type:"string",description:"Inclusive lower bound month, 'yyyy-MM' (e.g. '2026-01')."},until:{type:"string",description:"Inclusive upper bound month, 'yyyy-MM' (e.g. '2026-06')."},agent:{type:"string",description:"Filter to records written by one agent namespace. Omit to query across all writers."}},required:[]}},{name:"sqlite_exec",description:"For SQLITE-type stores: run SQL that CHANGES data \u2014 CREATE TABLE (use IF NOT EXISTS), INSERT, UPDATE, DELETE (one or more statements in one call). The store is a real, mutable SQLite database that persists across your stateless runs. Returns { rowsModified, wrote }. Use this to build schema on the fly and to update rows / track changing state (e.g. a queue with a status column).",input_schema:{type:"object",properties:{store:{type:"string",description:"The logical store NAME (a sqlite-type store from AVAILABLE STORES) \u2014 pick by description. NOT an id. If exactly one store is bound you may omit this."},sql:{type:"string",description:'The SQL to run. May contain multiple statements separated by ";". Prefer CREATE TABLE IF NOT EXISTS for idempotent schema.'},params:{type:"array",description:'Optional positional bind params for a SINGLE parameterized statement (safe binding of values), e.g. sql "UPDATE t SET s=? WHERE id=?" with params ["done", 1].'}},required:["sql"]}},{name:"sqlite_query",description:"For SQLITE-type stores: run a read-only SELECT (optionally with `params` for safe binding) against the store's SQLite database. Returns { columns, rows }. Never changes data. Use to read back rows/state you stored earlier.",input_schema:{type:"object",properties:{store:{type:"string",description:"The logical store NAME (a sqlite-type store from AVAILABLE STORES) \u2014 pick by description. NOT an id. If exactly one store is bound you may omit this."},sql:{type:"string",description:"A single SELECT statement. Use ? placeholders + `params` for any values."},params:{type:"array",description:'Optional positional bind params for the SELECT, e.g. ["linkedin_personal"].'}},required:["sql"]}}]};export{I as datasetStoreSkill};
|