@agentdeploymentco/bishop 0.4.0 → 0.5.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 +1 @@
|
|
|
1
|
-
import{FETCH_FILE_TOOL as i}from"../harness/principal.js";import{SHARE_FILE_TOOL as a}from"../outgoing.js";const s={Read:e=>e?`Reading ${e}`:"Reading a file",Write:e=>e?`Writing ${e}`:"Writing a file",Edit:e=>e?`Editing ${e}`:"Editing a file",NotebookEdit:e=>e?`Editing ${e}`:"Editing a notebook",Bash:e=>e??"Running a command",BashOutput:()=>"Checking on a command",Glob:e=>e?`Looking for ${e}`:"Looking through files",Grep:e=>e?`Searching for ${e}`:"Searching the code",WebFetch:e=>e?`Reading ${e}`:"Fetching a page",WebSearch:e=>e?`Searching for ${e}`:"Searching the web",Task:e=>e?`Working on ${e}`:"Delegating a subtask",TodoWrite:()=>"Planning",ExitPlanMode:()=>"Finishing up a plan",AskUserQuestion:()=>"Considering options"},l={schedule_create:"Setting up a schedule",schedule_list:"Checking what is scheduled",schedule_delete:"Removing a schedule",[i]:"Fetching a file from this conversation",[a]:"Getting a file ready to send"};function c(e){if(!e.startsWith("mcp__"))return;const[,n,...t]=e.split("__");return n==="bishop"?l[t.join("__")]??"Sorting something out":n?`Calling ${n}`:"Calling a tool"}function u(e){const n=e.replaceAll(/[_-]+/g," ").replaceAll(/([a-z\d])([A-Z])/g,"$1 $2").trim();if(!n)return"Working";const t=n.toLowerCase();return t.charAt(0).toUpperCase()+t.slice(1)}const r=100;function g(e){const n=e.trim();return n.length>r?`${n.slice(0,r-3)}...`:n}function
|
|
1
|
+
import{FETCH_FILE_TOOL as i}from"../harness/principal.js";import{SHARE_FILE_TOOL as a}from"../outgoing.js";const s={Read:e=>e?`Reading ${e}`:"Reading a file",Write:e=>e?`Writing ${e}`:"Writing a file",Edit:e=>e?`Editing ${e}`:"Editing a file",NotebookEdit:e=>e?`Editing ${e}`:"Editing a notebook",Bash:e=>e??"Running a command",BashOutput:()=>"Checking on a command",Glob:e=>e?`Looking for ${e}`:"Looking through files",Grep:e=>e?`Searching for ${e}`:"Searching the code",WebFetch:e=>e?`Reading ${e}`:"Fetching a page",WebSearch:e=>e?`Searching for ${e}`:"Searching the web",Task:e=>e?`Working on ${e}`:"Delegating a subtask",TodoWrite:()=>"Planning",ExitPlanMode:()=>"Finishing up a plan",AskUserQuestion:()=>"Considering options"},l={schedule_create:"Setting up a schedule",schedule_list:"Checking what is scheduled",schedule_update:"Changing a schedule",schedule_delete:"Removing a schedule",[i]:"Fetching a file from this conversation",[a]:"Getting a file ready to send"};function c(e){if(!e.startsWith("mcp__"))return;const[,n,...t]=e.split("__");return n==="bishop"?l[t.join("__")]??"Sorting something out":n?`Calling ${n}`:"Calling a tool"}function u(e){const n=e.replaceAll(/[_-]+/g," ").replaceAll(/([a-z\d])([A-Z])/g,"$1 $2").trim();if(!n)return"Working";const t=n.toLowerCase();return t.charAt(0).toUpperCase()+t.slice(1)}const r=100;function g(e){const n=e.trim();return n.length>r?`${n.slice(0,r-3)}...`:n}function f(e){const n=e.summary?.trim();if(n)return g(n);const t=s[e.name];if(t)return t(e.detail);const o=c(e.name);return o||u(e.name)}function h(e){const n=Math.max(0,Math.round(e/1e3)),t=Math.floor(n/60),o=n%60;return t?`${t}m ${o}s`:`${o}s`}function p(e){return e===1?"Used 1 tool":`Used ${e} tools`}function $(e,n){return`${n?"Worked for":"Stopped after"} ${h(e)}`}export{h as elapsed,u as humanizeToolName,g as summaryPhrase,f as toolPhrase,p as toolTally,$ as turnTally};
|
package/dist/schedule/store.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import{mint as
|
|
2
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, NULL, NULL, 0)`),d=t.prepare(`SELECT ${a} FROM schedules ORDER BY created_at`),s=t.prepare(`SELECT ${a} FROM schedules WHERE id = ?`),o=t.prepare(`SELECT ${a} FROM schedules WHERE enabled = 1 AND next_run_at <= ? ORDER BY next_run_at`),
|
|
1
|
+
import{mint as T}from"../ids.js";function c(t){return{id:t.id,name:t.name,cron:t.cron,tz:t.tz,prompt:t.prompt,destination:{interface:t.interface,handle:t.handle,label:t.label},createdBy:t.created_by,createdAt:t.created_at,enabled:t.enabled===1,nextRunAt:t.next_run_at,...t.last_run_at===null?{}:{lastRunAt:t.last_run_at},...t.last_error===null?{}:{lastError:t.last_error},consecutiveFailures:t.consecutive_failures}}function h(t){const a="id, name, cron, tz, prompt, interface, handle, label, created_by, created_at, enabled, next_run_at, last_run_at, last_error, consecutive_failures",u=t.prepare(`INSERT INTO schedules (${a})
|
|
2
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, ?, NULL, NULL, 0)`),d=t.prepare(`SELECT ${a} FROM schedules ORDER BY created_at`),s=t.prepare(`SELECT ${a} FROM schedules WHERE id = ?`),o=t.prepare(`SELECT ${a} FROM schedules WHERE enabled = 1 AND next_run_at <= ? ORDER BY next_run_at`),i=t.prepare("DELETE FROM schedules WHERE id = ?"),E=t.prepare(`UPDATE schedules
|
|
3
|
+
SET name = ?, cron = ?, tz = ?, prompt = ?, interface = ?, handle = ?, label = ?,
|
|
4
|
+
created_by = ?, next_run_at = ?
|
|
5
|
+
WHERE id = ?`),_=t.prepare("UPDATE schedules SET enabled = ?, next_run_at = ? WHERE id = ?"),p=t.prepare("UPDATE schedules SET next_run_at = ? WHERE id = ?"),R=t.prepare(`UPDATE schedules
|
|
3
6
|
SET last_run_at = ?, last_error = NULL, consecutive_failures = 0
|
|
4
|
-
WHERE id = ?`),
|
|
7
|
+
WHERE id = ?`),f=t.prepare(`UPDATE schedules
|
|
5
8
|
SET last_run_at = ?, last_error = ?, consecutive_failures = consecutive_failures + 1
|
|
6
|
-
WHERE id = ?`),
|
|
9
|
+
WHERE id = ?`),m=t.prepare("UPDATE schedules SET last_error = NULL, consecutive_failures = 0 WHERE id = ?");return{all(){return d.all().map(c)},get(e){const r=s.get(e);return r?c(r):void 0},add(e){const r=T("sch"),n=e.createdAt??Date.now();return u.run(r,e.name,e.cron,e.tz,e.prompt,e.destination.interface,e.destination.handle,e.destination.label,e.createdBy,n,e.nextRunAt),{id:r,...e,createdAt:n,enabled:!0,consecutiveFailures:0}},remove(e){return i.run(e).changes>0},update(e,r){return E.run(r.name,r.cron,r.tz,r.prompt,r.destination.interface,r.destination.handle,r.destination.label,r.createdBy,r.nextRunAt,e).changes>0},setEnabled(e,r,n){const l=s.get(e);return l?(_.run(r?1:0,n??l.next_run_at,e),!0):!1},due(e){return o.all(e).map(c)},setNextRun(e,r){p.run(r,e)},recordSuccess(e,r){R.run(r,e)},clearFailures(e){m.run(e)},recordFailure(e,r,n){return f.run(r,n,e),s.get(e)?.consecutive_failures??0}}}export{h as scheduleStore};
|
package/dist/tools/schedules.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import{z as
|
|
2
|
-
`)}async function
|
|
3
|
-
`),input:{name:
|
|
4
|
-
Next ${
|
|
1
|
+
import{z as a}from"zod";import{BishopError as _}from"../errors.js";import{NO_OUTPUT as D}from"../harness/principal.js";import{log as $}from"../log.js";import{principalLabel as W}from"../principals.js";import{describeTime as v,nextRun as k,systemTimeZone as N,validateCron as x,validateTimeZone as B}from"../schedule/cron.js";import{defineTool as y,ToolRefusal as h}from"./types.js";const Z=20;function z(e){return e.principal.id}function w(e){try{return e()}catch(t){throw t instanceof _?new h(t.message):t}}async function E(e){try{return await e()}catch(t){throw t instanceof _?new h(t.message):t}}function F(e,t,n){const o=[`${e.id} ${e.name}${e.enabled?"":" (disabled)"}`,` runs ${e.cron} (${e.tz})`,` next ${e.enabled?v(e.nextRunAt,t):"never, while it is off"}`,` to ${e.destination.label}`,` prompt ${e.prompt}`,` by ${W(e.createdBy,n)}`];return e.lastError&&o.push(` error ${e.lastError} (${e.consecutiveFailures} in a row)`),o.join(`
|
|
2
|
+
`)}async function A(e,t){const n=await t.destination(),o=z(t);return e.schedules.all().filter(i=>i.createdBy===o||e.sameConversation(i.destination,n))}function C(e,t,n){const o=z(t);if(!e.authorized(o))throw new h(`Bishop can't run a schedule created by ${t.principal.name}, so ${n?"changing this one":"making one"} would write something that never fires. Ask an operator to add it with \`bishop schedules add\`.`);if(n?.createdBy===o)return o;const i=e.schedules.all().filter(c=>c.createdBy===o).length;if(i>=Z)throw new h(`You already have ${i} schedules, which is the limit. Remove one with schedule_delete before ${n?"taking on":"adding"} another.`);return o}function P(e){const t=e.now??Date.now;return y({name:"schedule_create",description:["Runs a prompt on a cron schedule and posts the answer where you say.","Each firing is a fresh session with no memory of the last one, so the prompt has to","carry everything it needs.","",`The prompt must say when to stay quiet, and say that answering ${D} is how.`,"A schedule that reports every time it runs is one people learn to ignore."].join(`
|
|
3
|
+
`),input:{name:a.string().trim().min(1).describe("What a person sees in a list, and an email subject"),cron:a.string().trim().min(1).describe("Five-field cron, or @daily and friends. No more than once every five minutes"),prompt:a.string().trim().min(1).describe("What the agent is asked at each firing, including when to say nothing"),to:a.string().trim().min(1).optional().describe("Where the answer goes: #channel or @person for Slack, or an email address. Leave it out to post back into this conversation."),tz:a.string().trim().min(1).optional().describe("IANA zone the expression is read in, like Europe/London. Defaults to Bishop's")},async run(n,o){const i=C(e,o),c=n.tz,l=c?w(()=>B(c)):N();w(()=>x(n.cron,l));const p=n.to,m=p?await E(()=>e.resolve(p)):await o.destination(),s=e.schedules.add({name:n.name,cron:n.cron,tz:l,prompt:n.prompt,destination:m,createdBy:i,nextRunAt:k(n.cron,l,t())});return $.info({schedule:s.id,name:s.name,cron:s.cron,tz:s.tz,by:s.createdBy,to:m.label},"the agent created a schedule"),`Created ${s.id} "${s.name}", running ${s.cron} (${l}).
|
|
4
|
+
Next ${v(s.nextRunAt,l)}, posting to ${m.label}.`}})}function S(e){return y({name:"schedule_list",description:"Lists the schedules you created, and any that post into this conversation. Not schedules other people aimed elsewhere.",input:{},async run(t,n){const o=await A(e,n);if(o.length===0)return"Nothing is scheduled here, and you have not made any.";const i=N();return`${o.map(c=>F(c,i,e.principals)).join(`
|
|
5
5
|
|
|
6
6
|
`)}
|
|
7
7
|
|
|
8
|
-
Times in ${
|
|
8
|
+
Times in ${i}.`}})}function U(e){const t=e.now??Date.now;return y({name:"schedule_update",description:"Changes a schedule by id and keeps the id. Only ones schedule_list shows you. Anything you leave out stays as it is.",input:{id:a.string().trim().min(1).describe("The id schedule_list reports"),name:a.string().trim().min(1).optional().describe("A new name"),cron:a.string().trim().min(1).optional().describe("A new five-field cron, or @daily and friends. No more than once every five minutes"),prompt:a.string().trim().min(1).optional().describe("A new prompt, whole. It replaces the old one rather than adding to it"),to:a.string().trim().min(1).optional().describe("A new destination: #channel or @person for Slack, or an email address"),tz:a.string().trim().min(1).optional().describe("A new IANA zone, like Europe/London")},async run(n,o){const i=`No schedule ${n.id} that you can change. schedule_list has the ones you can.`;if(!(await A(e,o)).some(b=>b.id===n.id))throw new h(i);const{name:l,cron:p,prompt:m,to:s,tz:g}=n;if([l,p,m,s,g].every(b=>b===void 0))throw new h("Nothing to change. Name at least one of name, cron, prompt, to, or tz.");const L=g?w(()=>B(g)):void 0,O=s?await E(()=>e.resolve(s)):void 0,r=e.schedules.get(n.id);if(!r)throw new h(i);const T=C(e,o,r),u=L??r.tz,f=p??r.cron;w(()=>x(f,u));const j=f!==r.cron||u!==r.tz,d={...r,name:l??r.name,cron:f,tz:u,prompt:m??r.prompt,destination:O??r.destination,createdBy:T,nextRunAt:j?k(f,u,t()):r.nextRunAt};e.schedules.update(r.id,d);const{destination:R}=d;$.info({schedule:r.id,name:d.name,cron:d.cron,tz:d.tz,by:T,to:R.label},"the agent changed a schedule");const I=d.enabled?`Next ${v(d.nextRunAt,u)}`:`It is off, so nothing fires until an operator runs \`bishop schedules enable ${r.id}\``;return`Changed ${r.id} "${d.name}", running ${d.cron} (${u}).
|
|
9
|
+
${I}, posting to ${R.label}.`}})}function q(e){return y({name:"schedule_delete",description:"Removes a schedule by id. Only ones schedule_list shows you.",input:{id:a.string().trim().min(1).describe("The id schedule_list reports")},async run(t,n){const i=(await A(e,n)).find(c=>c.id===t.id);if(!i)throw new h(`No schedule ${t.id} that you can remove. schedule_list has the ones you can.`);return e.schedules.remove(i.id),$.info({schedule:i.id,name:i.name,by:z(n)},"the agent removed a schedule"),`Removed ${i.id} "${i.name}".`}})}function Q(e){return[P(e),S(e),U(e),q(e)]}export{Z as MAX_PER_CREATOR,z as createdBy,Q as scheduleTools};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentdeploymentco/bishop",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "An agent gateway. Connects an agent to Slack and email.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
"check": "npm run lint && npm run typecheck && npm test"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@anthropic-ai/claude-agent-sdk": "0.3.
|
|
44
|
+
"@anthropic-ai/claude-agent-sdk": "0.3.287",
|
|
45
45
|
"@microsoft/teams.apps": "^2.0.16",
|
|
46
46
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
47
|
-
"@openai/codex-sdk": "0.
|
|
47
|
+
"@openai/codex-sdk": "0.160.0",
|
|
48
48
|
"@slack/bolt": "^5.0.0",
|
|
49
49
|
"@slack/web-api": "^8",
|
|
50
50
|
"commander": "^13",
|
|
@@ -59,6 +59,6 @@
|
|
|
59
59
|
"esbuild": "^0.28.2",
|
|
60
60
|
"tsx": "^4",
|
|
61
61
|
"typescript": "^5",
|
|
62
|
-
"vitest": "^
|
|
62
|
+
"vitest": "^5"
|
|
63
63
|
}
|
|
64
64
|
}
|