@stratusagent/agents 0.13.6 → 0.14.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.
- package/dist/credential-env.d.ts +41 -0
- package/dist/credential-env.d.ts.map +1 -0
- package/dist/credential-env.js +77 -0
- package/dist/credential-env.js.map +1 -0
- package/dist/events.d.ts +66 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +180 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/schedules.d.ts +14 -4
- package/dist/schedules.d.ts.map +1 -1
- package/dist/schedules.js +15 -0
- package/dist/schedules.js.map +1 -1
- package/dist/tools/channel.d.ts +44 -0
- package/dist/tools/channel.d.ts.map +1 -0
- package/dist/tools/channel.js +90 -0
- package/dist/tools/channel.js.map +1 -0
- package/dist/tools/credentials.d.ts +1 -0
- package/dist/tools/credentials.d.ts.map +1 -1
- package/dist/tools/credentials.js +16 -4
- package/dist/tools/credentials.js.map +1 -1
- package/dist/tools/gateway-only.d.ts.map +1 -1
- package/dist/tools/gateway-only.js +4 -1
- package/dist/tools/gateway-only.js.map +1 -1
- package/dist/tools/message.d.ts +16 -0
- package/dist/tools/message.d.ts.map +1 -1
- package/dist/tools/message.js +64 -7
- package/dist/tools/message.js.map +1 -1
- package/dist/tools/schedule.d.ts +4 -2
- package/dist/tools/schedule.d.ts.map +1 -1
- package/dist/tools/schedule.js +62 -2
- package/dist/tools/schedule.js.map +1 -1
- package/package.json +2 -2
- package/skills/stratus/SKILL.md +16 -10
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Tool } from '@stratusagent/core';
|
|
2
|
+
export declare const CHANNEL_CREATE_TOOL_NAME = "channel.create";
|
|
3
|
+
/**
|
|
4
|
+
* Creates one conversation through the agent's own channel app. The
|
|
5
|
+
* gateway implements it over the channel contract's `createConversation`,
|
|
6
|
+
* structurally mirrored here the way `ConversationReader` mirrors
|
|
7
|
+
* `readConversation`; rejecting is how a channel says it will not.
|
|
8
|
+
*/
|
|
9
|
+
export type ConversationCreator = (input: {
|
|
10
|
+
agentId: string;
|
|
11
|
+
/** The channel kind, e.g. `slack`. */
|
|
12
|
+
channel: string;
|
|
13
|
+
name: string;
|
|
14
|
+
private?: boolean;
|
|
15
|
+
topic?: string;
|
|
16
|
+
purpose?: string;
|
|
17
|
+
/** Channel-native user ids, or agent ids the channel resolves to their app. */
|
|
18
|
+
invite?: string[];
|
|
19
|
+
}) => Promise<{
|
|
20
|
+
conversation: string;
|
|
21
|
+
name: string;
|
|
22
|
+
invited: string[];
|
|
23
|
+
notInvited: Array<{
|
|
24
|
+
who: string;
|
|
25
|
+
reason: string;
|
|
26
|
+
}>;
|
|
27
|
+
notSet: Array<{
|
|
28
|
+
field: 'topic' | 'purpose';
|
|
29
|
+
reason: string;
|
|
30
|
+
}>;
|
|
31
|
+
}>;
|
|
32
|
+
/**
|
|
33
|
+
* Create a channel and invite people and other agents to it, so an agent
|
|
34
|
+
* can set up a client or project room without a person doing it by hand.
|
|
35
|
+
*
|
|
36
|
+
* `gated`, like `message.send`: a new channel and its invitations are seen
|
|
37
|
+
* by everyone invited, and a channel cannot be taken back by the agent.
|
|
38
|
+
* There is no destination to judge by before the channel exists, so a
|
|
39
|
+
* durable grant is a standing yes to creating channels. The channel's own
|
|
40
|
+
* app does the work with its own token, which never reaches the agent; the
|
|
41
|
+
* channel decides what its app may create.
|
|
42
|
+
*/
|
|
43
|
+
export declare const createChannelCreateTool: (create: ConversationCreator) => Tool;
|
|
44
|
+
//# sourceMappingURL=channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/tools/channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAEpE,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB,KAAK,OAAO,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D,CAAC,CAAC;AAaH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,mBAAmB,KAAG,IAkEpE,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export const CHANNEL_CREATE_TOOL_NAME = 'channel.create';
|
|
2
|
+
const optionalText = (input, key) => {
|
|
3
|
+
const value = input[key];
|
|
4
|
+
if (value === undefined || value === null) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
if (typeof value !== 'string') {
|
|
8
|
+
throw new Error(`${CHANNEL_CREATE_TOOL_NAME}: "${key}" must be a string when given.`);
|
|
9
|
+
}
|
|
10
|
+
return value.trim() || undefined;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Create a channel and invite people and other agents to it, so an agent
|
|
14
|
+
* can set up a client or project room without a person doing it by hand.
|
|
15
|
+
*
|
|
16
|
+
* `gated`, like `message.send`: a new channel and its invitations are seen
|
|
17
|
+
* by everyone invited, and a channel cannot be taken back by the agent.
|
|
18
|
+
* There is no destination to judge by before the channel exists, so a
|
|
19
|
+
* durable grant is a standing yes to creating channels. The channel's own
|
|
20
|
+
* app does the work with its own token, which never reaches the agent; the
|
|
21
|
+
* channel decides what its app may create.
|
|
22
|
+
*/
|
|
23
|
+
export const createChannelCreateTool = (create) => ({
|
|
24
|
+
name: CHANNEL_CREATE_TOOL_NAME,
|
|
25
|
+
description: 'Create a channel through your own app, optionally private, with a topic and purpose, and invite people and other agents to it. '
|
|
26
|
+
+ 'invite takes the channel\'s user ids (for Slack, U…) and other agents\' ids on this host, which resolve to their apps. '
|
|
27
|
+
+ 'Returns the new conversation id. The channel is kept even if some invites or the topic fail: '
|
|
28
|
+
+ 'notInvited and notSet say what did not happen and why, so report those rather than retrying the create. '
|
|
29
|
+
+ 'For Slack, names are lowercase letters, numbers, hyphens and underscores, at most 80 characters.',
|
|
30
|
+
risk: 'gated',
|
|
31
|
+
parameters: {
|
|
32
|
+
type: 'object',
|
|
33
|
+
properties: {
|
|
34
|
+
channel: { type: 'string', description: 'The channel kind to create it in, e.g. "slack".' },
|
|
35
|
+
name: { type: 'string', description: 'The new channel\'s name, without a leading #.' },
|
|
36
|
+
private: { type: 'boolean', description: 'Create a private channel. Public by default.' },
|
|
37
|
+
topic: { type: 'string', description: 'The channel\'s topic.' },
|
|
38
|
+
purpose: { type: 'string', description: 'The channel\'s purpose (its description).' },
|
|
39
|
+
invite: {
|
|
40
|
+
type: 'array',
|
|
41
|
+
items: { type: 'string' },
|
|
42
|
+
description: 'Who to invite: user ids, or agent ids on this host. Your own app is already a member.',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
required: ['channel', 'name'],
|
|
46
|
+
},
|
|
47
|
+
async execute(input, session) {
|
|
48
|
+
const channel = typeof input.channel === 'string' ? input.channel.trim() : '';
|
|
49
|
+
if (!channel) {
|
|
50
|
+
throw new Error(`${CHANNEL_CREATE_TOOL_NAME} requires "channel", the channel kind (e.g. "slack").`);
|
|
51
|
+
}
|
|
52
|
+
const name = typeof input.name === 'string' ? input.name.trim() : '';
|
|
53
|
+
if (!name) {
|
|
54
|
+
throw new Error(`${CHANNEL_CREATE_TOOL_NAME} requires a non-empty "name".`);
|
|
55
|
+
}
|
|
56
|
+
if (input.private !== undefined && typeof input.private !== 'boolean') {
|
|
57
|
+
throw new Error(`${CHANNEL_CREATE_TOOL_NAME}: "private" must be true or false.`);
|
|
58
|
+
}
|
|
59
|
+
const topic = optionalText(input, 'topic');
|
|
60
|
+
const purpose = optionalText(input, 'purpose');
|
|
61
|
+
let invite;
|
|
62
|
+
if (input.invite !== undefined && input.invite !== null) {
|
|
63
|
+
const raw = input.invite;
|
|
64
|
+
if (!Array.isArray(raw) || raw.some((entry) => typeof entry !== 'string' || entry.trim().length === 0)) {
|
|
65
|
+
throw new Error(`${CHANNEL_CREATE_TOOL_NAME}: "invite" must be a list of non-empty ids.`);
|
|
66
|
+
}
|
|
67
|
+
const unique = [...new Set(raw.map((entry) => entry.trim()))];
|
|
68
|
+
invite = unique.length > 0 ? unique : undefined;
|
|
69
|
+
}
|
|
70
|
+
const result = await create({
|
|
71
|
+
agentId: session.agent.id,
|
|
72
|
+
channel,
|
|
73
|
+
name,
|
|
74
|
+
...(input.private === true ? { private: true } : {}),
|
|
75
|
+
...(topic !== undefined ? { topic } : {}),
|
|
76
|
+
...(purpose !== undefined ? { purpose } : {}),
|
|
77
|
+
...(invite !== undefined ? { invite } : {}),
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
created: true,
|
|
81
|
+
channel,
|
|
82
|
+
conversation: result.conversation,
|
|
83
|
+
name: result.name,
|
|
84
|
+
invited: [...result.invited],
|
|
85
|
+
notInvited: result.notInvited.map(({ who, reason }) => ({ who, reason })),
|
|
86
|
+
notSet: result.notSet.map(({ field, reason }) => ({ field, reason })),
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=channel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/tools/channel.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/tools/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAc,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAEzG,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/tools/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAc,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAEzG,eAAO,MAAM,4BAA4B,uBAAuB,CAAC;AAEjE;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,EAC7H,OAAO,EAAE,OAAO,KACb,OAAO,CACR;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CACpH,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,2BAA2B,GAAI,mBAAmB,mBAAmB,KAAG,IAwFnF,CAAC"}
|
|
@@ -16,7 +16,8 @@ export const CREDENTIAL_REQUEST_TOOL_NAME = 'credential.request';
|
|
|
16
16
|
export const createCredentialRequestTool = (requestCredential) => ({
|
|
17
17
|
name: CREDENTIAL_REQUEST_TOOL_NAME,
|
|
18
18
|
description: 'Ask your operator for a named credential you do not hold (for example github.token). They are shown a form to add it, in this conversation where it can show one, or behind a one-time link you are given to pass on; you never see the value, and once they add it the tools that need it can use it from your next reply. Scope "agent" (the default) keeps it yours alone; "shared" stores it once for the fleet, but it is granted only to you: another agent can use it only once its own soul lists the name. '
|
|
19
|
-
+ 'To rotate a key you already hold (expiring, revoked), set replace: true: an approver gets a form in this conversation to enter the new value, which swaps the stored one in place. A replace is never a link, and a shared key needs scope "shared" to say so, since it changes the key for every agent that uses it.'
|
|
19
|
+
+ 'To rotate a key you already hold (expiring, revoked), set replace: true: an approver gets a form in this conversation to enter the new value, which swaps the stored one in place. A replace is never a link, and a shared key needs scope "shared" to say so, since it changes the key for every agent that uses it. '
|
|
20
|
+
+ 'For a key a command or script you run with shell.run reads from an environment variable, set env to that variable (GH_TOKEN, TWILIO_AUTH_TOKEN): the form tells the person your shell will be able to read it, and once they add it your commands have it from your next reply, with no config change or restart.',
|
|
20
21
|
risk: 'safe',
|
|
21
22
|
parameters: {
|
|
22
23
|
type: 'object',
|
|
@@ -28,6 +29,10 @@ export const createCredentialRequestTool = (requestCredential) => ({
|
|
|
28
29
|
type: 'boolean',
|
|
29
30
|
description: 'true to ask for a new value for a key you already hold, replacing the stored one. Form only.',
|
|
30
31
|
},
|
|
32
|
+
env: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'The environment variable your shell commands should read the key from, for a CLI or script that reads its token from one: GH_TOKEN, TWILIO_AUTH_TOKEN. Uppercase, ending in _TOKEN, _KEY, _SECRET, _PASSWORD, _SID or _ID. Omit it for a key only a tool uses.',
|
|
35
|
+
},
|
|
31
36
|
via: {
|
|
32
37
|
type: 'string',
|
|
33
38
|
enum: ['form', 'link'],
|
|
@@ -57,24 +62,31 @@ export const createCredentialRequestTool = (requestCredential) => ({
|
|
|
57
62
|
throw new Error('A replacement is asked for in a form an approver answers, never a link: a link lets whoever holds it change a key every call you make uses. Ask without via, in a conversation that can show a form.');
|
|
58
63
|
}
|
|
59
64
|
const reason = typeof input.reason === 'string' && input.reason.trim().length > 0 ? input.reason.trim() : undefined;
|
|
65
|
+
if (input.env !== undefined && (typeof input.env !== 'string' || input.env.trim().length === 0)) {
|
|
66
|
+
throw new Error('credential.request "env" is the environment variable your shell commands read the key from, like GH_TOKEN; omit it for a key only a tool uses.');
|
|
67
|
+
}
|
|
68
|
+
const env = typeof input.env === 'string' ? input.env.trim() : undefined;
|
|
60
69
|
const asked = await requestCredential({
|
|
61
70
|
name,
|
|
62
71
|
scope,
|
|
63
72
|
...(reason !== undefined ? { reason } : {}),
|
|
64
73
|
...(via !== undefined ? { via } : {}),
|
|
65
74
|
...(replace ? { replace } : {}),
|
|
75
|
+
...(env !== undefined ? { env } : {}),
|
|
66
76
|
}, session);
|
|
67
|
-
const after = replace
|
|
77
|
+
const after = (replace
|
|
68
78
|
? 'You will not see the value; once an approver enters it, it replaces the stored one and your tools use it from your next reply.'
|
|
69
|
-
: 'You will not see the value; once they add it, the tools that need it can use it from your next reply.'
|
|
79
|
+
: 'You will not see the value; once they add it, the tools that need it can use it from your next reply.')
|
|
80
|
+
+ (env !== undefined ? ` Your shell commands will read it as $${env} from then on.` : '');
|
|
70
81
|
if (asked.via === 'form') {
|
|
71
|
-
return { requested: true, requestId: asked.requestId, name, scope, via: 'form', ...(replace ? { replace } : {}), note: `Your operator was asked in this conversation. ${after}` };
|
|
82
|
+
return { requested: true, requestId: asked.requestId, name, scope, via: 'form', ...(replace ? { replace } : {}), ...(env !== undefined ? { env } : {}), note: `Your operator was asked in this conversation. ${after}` };
|
|
72
83
|
}
|
|
73
84
|
return {
|
|
74
85
|
requested: true,
|
|
75
86
|
requestId: asked.requestId,
|
|
76
87
|
name,
|
|
77
88
|
scope,
|
|
89
|
+
...(env !== undefined ? { env } : {}),
|
|
78
90
|
via: 'link',
|
|
79
91
|
link: asked.url,
|
|
80
92
|
expiresAt: asked.expiresAt,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/tools/credentials.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,4BAA4B,GAAG,oBAAoB,CAAC;AAoBjE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,iBAAsC,EAAQ,EAAE,CAAC,CAAC;IAC5F,IAAI,EAAE,4BAA4B;IAClC,WAAW,EAAE,sfAAsf;UAC/f,
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/tools/credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-only.d.ts","sourceRoot":"","sources":["../../src/tools/gateway-only.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gateway-only.d.ts","sourceRoot":"","sources":["../../src/tools/gateway-only.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAWpD,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { CHANNEL_CREATE_TOOL_NAME } from "./channel.js";
|
|
1
2
|
import { CREDENTIAL_REQUEST_TOOL_NAME } from "./credentials.js";
|
|
2
3
|
import { DELEGATE_TOOL_NAME } from "./delegate.js";
|
|
3
4
|
import { MESSAGE_READ_TOOL_NAME, MESSAGE_SEND_TOOL_NAME } from "./message.js";
|
|
4
|
-
import { SCHEDULE_EVERY_TOOL_NAME, SCHEDULE_AT_TOOL_NAME, SCHEDULE_LIST_TOOL_NAME, SCHEDULE_CANCEL_TOOL_NAME, } from "./schedule.js";
|
|
5
|
+
import { SCHEDULE_EVERY_TOOL_NAME, SCHEDULE_AT_TOOL_NAME, SCHEDULE_ON_TOOL_NAME, SCHEDULE_LIST_TOOL_NAME, SCHEDULE_CANCEL_TOOL_NAME, } from "./schedule.js";
|
|
5
6
|
/**
|
|
6
7
|
* The tools only a running gateway registers. Each needs the dispatcher,
|
|
7
8
|
* the store, or the channels, and nothing else in the tree has them — so a
|
|
@@ -22,10 +23,12 @@ import { SCHEDULE_EVERY_TOOL_NAME, SCHEDULE_AT_TOOL_NAME, SCHEDULE_LIST_TOOL_NAM
|
|
|
22
23
|
export const GATEWAY_ONLY_TOOL_NAMES = [
|
|
23
24
|
SCHEDULE_EVERY_TOOL_NAME,
|
|
24
25
|
SCHEDULE_AT_TOOL_NAME,
|
|
26
|
+
SCHEDULE_ON_TOOL_NAME,
|
|
25
27
|
SCHEDULE_LIST_TOOL_NAME,
|
|
26
28
|
SCHEDULE_CANCEL_TOOL_NAME,
|
|
27
29
|
MESSAGE_SEND_TOOL_NAME,
|
|
28
30
|
MESSAGE_READ_TOOL_NAME,
|
|
31
|
+
CHANNEL_CREATE_TOOL_NAME,
|
|
29
32
|
DELEGATE_TOOL_NAME,
|
|
30
33
|
CREDENTIAL_REQUEST_TOOL_NAME,
|
|
31
34
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-only.js","sourceRoot":"","sources":["../../src/tools/gateway-only.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAEvB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,wBAAwB;IACxB,qBAAqB;IACrB,uBAAuB;IACvB,yBAAyB;IACzB,sBAAsB;IACtB,sBAAsB;IACtB,kBAAkB;IAClB,4BAA4B;CAC7B,CAAC"}
|
|
1
|
+
{"version":3,"file":"gateway-only.js","sourceRoot":"","sources":["../../src/tools/gateway-only.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAEvB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,wBAAwB;IACxB,qBAAqB;IACrB,qBAAqB;IACrB,uBAAuB;IACvB,yBAAyB;IACzB,sBAAsB;IACtB,sBAAsB;IACtB,wBAAwB;IACxB,kBAAkB;IAClB,4BAA4B;CAC7B,CAAC"}
|
package/dist/tools/message.d.ts
CHANGED
|
@@ -60,6 +60,14 @@ export declare const MESSAGE_READ_MAX_LIMIT = 200;
|
|
|
60
60
|
* agent pages on with `before`/`after`.
|
|
61
61
|
*/
|
|
62
62
|
export declare const MESSAGE_READ_TEXT_BUDGET = 40000;
|
|
63
|
+
/**
|
|
64
|
+
* The share of `MESSAGE_READ_TEXT_BUDGET` a channel's bookmarks may take,
|
|
65
|
+
* counted first. It holds Slack's limit of 100 at a typical length; what
|
|
66
|
+
* it exists to stop is the people in a channel filling the agent's context
|
|
67
|
+
* with bookmarks. The ones that do not fit are counted, not paged: Slack
|
|
68
|
+
* lists them all in one call.
|
|
69
|
+
*/
|
|
70
|
+
export declare const MESSAGE_READ_BOOKMARK_BUDGET = 16000;
|
|
63
71
|
/**
|
|
64
72
|
* Reads one conversation, or one thread in it, through the agent's own
|
|
65
73
|
* channel app. The gateway implements it over the channel contract's
|
|
@@ -68,6 +76,8 @@ export declare const MESSAGE_READ_TEXT_BUDGET = 40000;
|
|
|
68
76
|
*/
|
|
69
77
|
export type ConversationReader = (input: {
|
|
70
78
|
agentId: string;
|
|
79
|
+
/** The session reading: a direct message is readable only from its own. */
|
|
80
|
+
sessionId: string;
|
|
71
81
|
source: ScheduleDestination;
|
|
72
82
|
thread?: string;
|
|
73
83
|
after?: string;
|
|
@@ -85,6 +95,12 @@ export type ConversationReader = (input: {
|
|
|
85
95
|
files?: string[];
|
|
86
96
|
}>;
|
|
87
97
|
more: boolean;
|
|
98
|
+
bookmarks?: Array<{
|
|
99
|
+
title: string;
|
|
100
|
+
link: string;
|
|
101
|
+
}>;
|
|
102
|
+
bookmarksUnavailable?: string;
|
|
103
|
+
bookmarksOmitted?: number;
|
|
88
104
|
}>;
|
|
89
105
|
/**
|
|
90
106
|
* Read a conversation's recent messages, or one thread — so an agent can
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/tools/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAClH,OAAO,EACL,KAAK,mBAAmB,EAIzB,MAAM,iBAAiB,CAAC;AAEzB,eAAO,MAAM,sBAAsB,iBAAiB,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,mBAAmB,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;CACpD,KAAK,OAAO,CAAC;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,mBAAmB,KAAK,MAAM,GAAG,SAAS,CAAC;AAE/G;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,GAChC,MAAM,iBAAiB,EACvB,UAAS;IAAE,aAAa,CAAC,EAAE,qBAAqB,CAAA;CAAO,KACtD,IAmED,CAAC;AAEH,eAAO,MAAM,sBAAsB,iBAAiB,CAAC;AAErD,yDAAyD;AACzD,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,QAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/tools/message.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/message.js
CHANGED
|
@@ -93,6 +93,14 @@ const MESSAGE_READ_DEFAULT_LIMIT = 50;
|
|
|
93
93
|
* agent pages on with `before`/`after`.
|
|
94
94
|
*/
|
|
95
95
|
export const MESSAGE_READ_TEXT_BUDGET = 40_000;
|
|
96
|
+
/**
|
|
97
|
+
* The share of `MESSAGE_READ_TEXT_BUDGET` a channel's bookmarks may take,
|
|
98
|
+
* counted first. It holds Slack's limit of 100 at a typical length; what
|
|
99
|
+
* it exists to stop is the people in a channel filling the agent's context
|
|
100
|
+
* with bookmarks. The ones that do not fit are counted, not paged: Slack
|
|
101
|
+
* lists them all in one call.
|
|
102
|
+
*/
|
|
103
|
+
export const MESSAGE_READ_BOOKMARK_BUDGET = 16_000;
|
|
96
104
|
const TRUNCATED_MARK = ' [... the rest of this message is not shown]';
|
|
97
105
|
const optionalId = (input, key, tool = MESSAGE_READ_TOOL_NAME) => {
|
|
98
106
|
const value = input[key];
|
|
@@ -105,18 +113,20 @@ const optionalId = (input, key, tool = MESSAGE_READ_TOOL_NAME) => {
|
|
|
105
113
|
return value.trim();
|
|
106
114
|
};
|
|
107
115
|
/** The refusal a direct-message read gets, before any approval prompt. */
|
|
108
|
-
export const directMessageReadRefusal = (destination) => `message.read cannot read ${destination}: it is a direct message, and direct
|
|
116
|
+
export const directMessageReadRefusal = (destination) => `message.read cannot read ${destination}: it is a direct message this conversation is not in, and a direct message is read only from inside it. `
|
|
109
117
|
+ 'This is not a permission, so approval cannot unlock it; do not ask for one or try again. '
|
|
110
118
|
+ 'Read a channel instead, or ask the person to paste what you need.';
|
|
111
119
|
export const createMessageReadTool = (read, options = {}) => ({
|
|
112
120
|
name: MESSAGE_READ_TOOL_NAME,
|
|
113
121
|
description: 'Read recent messages in a channel your app is a member of, or one thread in it. '
|
|
114
|
-
+ 'Direct messages and group DMs cannot be read with this, and approval does not change that. '
|
|
122
|
+
+ 'Direct messages and group DMs cannot be read with this, except the one this conversation is in, and approval does not change that. '
|
|
115
123
|
+ 'Without thread: the top level, newest first. With thread: that thread\'s root and replies, oldest first. '
|
|
116
124
|
+ 'For Slack, ids are channel ids and message ts values; a permalink '
|
|
117
125
|
+ '…/archives/C0123456789/p1791332967606559 is channel C0123456789 and message 1791332967.606559, '
|
|
118
126
|
+ 'and a thread_ts in the link is the thread to read. '
|
|
119
|
-
+ 'When more is true, page on with before (top level) or after (thread) set to the last id returned.'
|
|
127
|
+
+ 'When more is true, page on with before (top level) or after (thread) set to the last id returned. '
|
|
128
|
+
+ 'A top-level read without before or after also returns the channel\'s bookmarks, when it has any; '
|
|
129
|
+
+ 'if bookmarksOmitted is set, say that many were left out rather than guess them.',
|
|
120
130
|
risk: 'gated',
|
|
121
131
|
outputTrust: 'external',
|
|
122
132
|
parameters: {
|
|
@@ -158,14 +168,35 @@ export const createMessageReadTool = (read, options = {}) => ({
|
|
|
158
168
|
: MESSAGE_READ_DEFAULT_LIMIT;
|
|
159
169
|
const result = await read({
|
|
160
170
|
agentId: session.agent.id,
|
|
171
|
+
sessionId: session.id,
|
|
161
172
|
source,
|
|
162
173
|
limit,
|
|
163
174
|
...(thread !== undefined ? { thread } : {}),
|
|
164
175
|
...(after !== undefined ? { after } : {}),
|
|
165
176
|
...(before !== undefined ? { before } : {}),
|
|
166
177
|
});
|
|
167
|
-
|
|
178
|
+
// Bookmarks first, from their own share, in the channel's order.
|
|
179
|
+
const bookmarks = [];
|
|
168
180
|
let used = 0;
|
|
181
|
+
for (const bookmark of result.bookmarks ?? []) {
|
|
182
|
+
// Counted as the list is serialized: each entry with its separator,
|
|
183
|
+
// plus the closing bracket.
|
|
184
|
+
const size = JSON.stringify(bookmark).length + 1;
|
|
185
|
+
if (used + size + 1 > MESSAGE_READ_BOOKMARK_BUDGET) {
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
bookmarks.push({ title: bookmark.title, link: bookmark.link });
|
|
189
|
+
used += size;
|
|
190
|
+
}
|
|
191
|
+
if (bookmarks.length > 0) {
|
|
192
|
+
used += 1;
|
|
193
|
+
}
|
|
194
|
+
// Added to what the adapter itself already left out, if it said.
|
|
195
|
+
const upstreamOmitted = typeof result.bookmarksOmitted === 'number' && Number.isInteger(result.bookmarksOmitted) && result.bookmarksOmitted > 0
|
|
196
|
+
? result.bookmarksOmitted
|
|
197
|
+
: 0;
|
|
198
|
+
const bookmarksOmitted = upstreamOmitted + (result.bookmarks?.length ?? 0) - bookmarks.length;
|
|
199
|
+
const messages = [];
|
|
169
200
|
let more = result.more;
|
|
170
201
|
for (const message of result.messages) {
|
|
171
202
|
const size = JSON.stringify(message).length;
|
|
@@ -177,13 +208,36 @@ export const createMessageReadTool = (read, options = {}) => ({
|
|
|
177
208
|
// One message bigger than the whole budget is cut rather than
|
|
178
209
|
// dropped, or the read could never get past it. Its file list goes
|
|
179
210
|
// too, said by count, since a list can be as long as any text.
|
|
211
|
+
// One that would fit on its own, crowded out only by the bookmarks
|
|
212
|
+
// ahead of it, loses about what they took rather than half.
|
|
180
213
|
if (messages.length === 0) {
|
|
181
214
|
const { files, ...rest } = message;
|
|
182
|
-
const
|
|
215
|
+
const cutTo = (keep) => ({
|
|
183
216
|
...rest,
|
|
184
|
-
text: message.text.slice(0,
|
|
217
|
+
text: message.text.slice(0, Math.max(0, keep)) + TRUNCATED_MARK,
|
|
185
218
|
...(files && files.length > 0 ? { files: [`${files.length} files, not listed`] } : {}),
|
|
186
|
-
};
|
|
219
|
+
});
|
|
220
|
+
let cut = cutTo(MESSAGE_READ_TEXT_BUDGET / 2);
|
|
221
|
+
if (used > 0 && size <= MESSAGE_READ_TEXT_BUDGET) {
|
|
222
|
+
// The longest cut that fits, measured as serialized, since
|
|
223
|
+
// escapes make the text longer and may sit anywhere in it.
|
|
224
|
+
const room = MESSAGE_READ_TEXT_BUDGET - used;
|
|
225
|
+
const fits = (keep) => JSON.stringify(cutTo(keep)).length <= room;
|
|
226
|
+
if (fits(0)) {
|
|
227
|
+
let low = 0;
|
|
228
|
+
let high = message.text.length;
|
|
229
|
+
while (low < high) {
|
|
230
|
+
const middle = Math.ceil((low + high) / 2);
|
|
231
|
+
if (fits(middle)) {
|
|
232
|
+
low = middle;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
high = middle - 1;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
cut = cutTo(low);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
187
241
|
messages.push(cut);
|
|
188
242
|
}
|
|
189
243
|
more = true;
|
|
@@ -194,6 +248,9 @@ export const createMessageReadTool = (read, options = {}) => ({
|
|
|
194
248
|
...(thread !== undefined ? { thread } : {}),
|
|
195
249
|
count: messages.length,
|
|
196
250
|
more,
|
|
251
|
+
...(bookmarks.length > 0 ? { bookmarks } : {}),
|
|
252
|
+
...(bookmarksOmitted > 0 ? { bookmarksOmitted } : {}),
|
|
253
|
+
...(result.bookmarksUnavailable !== undefined ? { bookmarksUnavailable: result.bookmarksUnavailable } : {}),
|
|
197
254
|
messages,
|
|
198
255
|
};
|
|
199
256
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/tools/message.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"message.js","sourceRoot":"","sources":["../../src/tools/message.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/schedule.d.ts
CHANGED
|
@@ -2,14 +2,16 @@ import { type Tool } from '@stratusagent/core';
|
|
|
2
2
|
import { type SchedulerHandle } from '../schedules.ts';
|
|
3
3
|
export declare const SCHEDULE_EVERY_TOOL_NAME = "schedule.every";
|
|
4
4
|
export declare const SCHEDULE_AT_TOOL_NAME = "schedule.at";
|
|
5
|
+
export declare const SCHEDULE_ON_TOOL_NAME = "schedule.on";
|
|
5
6
|
export declare const SCHEDULE_LIST_TOOL_NAME = "schedule.list";
|
|
6
7
|
export declare const SCHEDULE_CANCEL_TOOL_NAME = "schedule.cancel";
|
|
7
8
|
/**
|
|
8
|
-
* The
|
|
9
|
+
* The five `schedule.*` tools over one handle.
|
|
9
10
|
*
|
|
10
11
|
* Risk is split per tool, not per toolset: creating a schedule spends
|
|
11
12
|
* future money unattended and (with a destination) mints a standing
|
|
12
|
-
* permission to speak, so `schedule.every
|
|
13
|
+
* permission to speak, so `schedule.every`, `schedule.at` and `schedule.on`
|
|
14
|
+
* are `gated` —
|
|
13
15
|
* the approval of THAT call is the human decision the whole step leans on.
|
|
14
16
|
* `schedule.list` is a read, and `schedule.cancel` only ever narrows
|
|
15
17
|
* authority — it is the reversal the risk note in the spec names — so both
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../src/tools/schedule.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,IAAI,EACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIL,KAAK,eAAe,EAMrB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../src/tools/schedule.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,IAAI,EACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIL,KAAK,eAAe,EAMrB,MAAM,iBAAiB,CAAC;AAuBzB,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AAEnD,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AAKnD,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAEvD,eAAO,MAAM,yBAAyB,oBAAoB,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,GAAI,WAAW,eAAe,KAAG,IAAI,EAuMpE,CAAC"}
|
package/dist/tools/schedule.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { conversationContextFrom, isTaintedTrust, leastTrusted, sessionWriteTrust, } from '@stratusagent/core';
|
|
2
2
|
import { parseInterval, parseCronExpression, parseScheduleDestinationInput, SCHEDULE_DESTINATION_PARAMETER, describeSchedule, sameConversation, } from "../schedules.js";
|
|
3
|
+
import { DEFAULT_EVENT_MAX_PER_HOUR, parseEventFilter, parseQuietHours } from "../events.js";
|
|
3
4
|
const TOP_LEVEL_PARAMETER = {
|
|
4
5
|
type: 'boolean',
|
|
5
6
|
description: 'Report at the top of the destination channel even when you set this from a thread in it. Default false: a schedule set from a thread reports into that thread.',
|
|
@@ -20,14 +21,18 @@ const originThreadFor = (session, destination) => {
|
|
|
20
21
|
};
|
|
21
22
|
export const SCHEDULE_EVERY_TOOL_NAME = 'schedule.every';
|
|
22
23
|
export const SCHEDULE_AT_TOOL_NAME = 'schedule.at';
|
|
24
|
+
export const SCHEDULE_ON_TOOL_NAME = 'schedule.on';
|
|
25
|
+
/** The most turns an hour an event trigger may ask for: one every 30 seconds. */
|
|
26
|
+
const MAX_EVENT_TRIGGER_PER_HOUR = 120;
|
|
23
27
|
export const SCHEDULE_LIST_TOOL_NAME = 'schedule.list';
|
|
24
28
|
export const SCHEDULE_CANCEL_TOOL_NAME = 'schedule.cancel';
|
|
25
29
|
/**
|
|
26
|
-
* The
|
|
30
|
+
* The five `schedule.*` tools over one handle.
|
|
27
31
|
*
|
|
28
32
|
* Risk is split per tool, not per toolset: creating a schedule spends
|
|
29
33
|
* future money unattended and (with a destination) mints a standing
|
|
30
|
-
* permission to speak, so `schedule.every
|
|
34
|
+
* permission to speak, so `schedule.every`, `schedule.at` and `schedule.on`
|
|
35
|
+
* are `gated` —
|
|
31
36
|
* the approval of THAT call is the human decision the whole step leans on.
|
|
32
37
|
* `schedule.list` is a read, and `schedule.cancel` only ever narrows
|
|
33
38
|
* authority — it is the reversal the risk note in the spec names — so both
|
|
@@ -124,6 +129,61 @@ export const createScheduleTools = (scheduler) => {
|
|
|
124
129
|
return create(session, { kind: 'at', at: parsed.toISOString() }, input);
|
|
125
130
|
},
|
|
126
131
|
},
|
|
132
|
+
{
|
|
133
|
+
name: SCHEDULE_ON_TOOL_NAME,
|
|
134
|
+
description: 'Set an event trigger for yourself: when a delivery from an operator-configured event source (like "github") passes your filter, run your prompt with the event appended. '
|
|
135
|
+
+ 'The filter uses the CloudEvents dialects exact, prefix, suffix, all, any and not over attributes such as type, subject, actor and author; a key like "data.review.body" matches a string inside the event\'s data. '
|
|
136
|
+
+ 'The event text is from outside, so the turn runs labeled external. Needs human approval once; firings then run unattended.',
|
|
137
|
+
risk: 'gated',
|
|
138
|
+
parameters: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: {
|
|
141
|
+
source: { type: 'string', description: 'The event source id the operator configured, e.g. "github".' },
|
|
142
|
+
filter: {
|
|
143
|
+
type: 'object',
|
|
144
|
+
description: 'One filter expression with exactly one dialect key, e.g. { "all": [ { "exact": { "actor": "chatgpt-codex-connector[bot]" } }, { "prefix": { "type": "com.github.pull_request_review" } } ] }.',
|
|
145
|
+
},
|
|
146
|
+
prompt: { type: 'string', description: 'The instruction each firing runs, phrased to stand alone. The event follows it.' },
|
|
147
|
+
quietHours: {
|
|
148
|
+
type: 'object',
|
|
149
|
+
description: 'Optional daily window in which firings are held and then sent together, e.g. { "from": "22:00", "to": "07:00", "timeZone": "America/New_York" }.',
|
|
150
|
+
properties: {
|
|
151
|
+
from: { type: 'string', description: 'Start, HH:MM on a 24-hour clock.' },
|
|
152
|
+
to: { type: 'string', description: 'End, HH:MM on a 24-hour clock.' },
|
|
153
|
+
timeZone: { type: 'string', description: 'IANA time zone, e.g. "America/New_York".' },
|
|
154
|
+
},
|
|
155
|
+
required: ['from', 'to', 'timeZone'],
|
|
156
|
+
},
|
|
157
|
+
maxPerHour: { type: 'number', description: `Most turns an hour this trigger may start (default ${DEFAULT_EVENT_MAX_PER_HOUR}, at most ${MAX_EVENT_TRIGGER_PER_HOUR}).` },
|
|
158
|
+
destination: SCHEDULE_DESTINATION_PARAMETER,
|
|
159
|
+
topLevel: TOP_LEVEL_PARAMETER,
|
|
160
|
+
},
|
|
161
|
+
required: ['source', 'filter', 'prompt'],
|
|
162
|
+
},
|
|
163
|
+
async execute(input, session) {
|
|
164
|
+
const source = typeof input.source === 'string' ? input.source.trim() : '';
|
|
165
|
+
if (!source) {
|
|
166
|
+
throw new Error('schedule.on needs a "source": the id of an event source the operator configured, like "github".');
|
|
167
|
+
}
|
|
168
|
+
if (input.filter === undefined) {
|
|
169
|
+
throw new Error('schedule.on needs a "filter": one expression such as { "exact": { "type": "com.github.pull_request_review.submitted" } }.');
|
|
170
|
+
}
|
|
171
|
+
const filter = parseEventFilter(input.filter);
|
|
172
|
+
const quietHours = input.quietHours !== undefined ? parseQuietHours(input.quietHours) : undefined;
|
|
173
|
+
const maxPerHour = input.maxPerHour;
|
|
174
|
+
if (maxPerHour !== undefined
|
|
175
|
+
&& (typeof maxPerHour !== 'number' || !Number.isInteger(maxPerHour) || maxPerHour < 1 || maxPerHour > MAX_EVENT_TRIGGER_PER_HOUR)) {
|
|
176
|
+
throw new Error(`"maxPerHour" must be a whole number from 1 to ${MAX_EVENT_TRIGGER_PER_HOUR}.`);
|
|
177
|
+
}
|
|
178
|
+
return create(session, {
|
|
179
|
+
kind: 'event',
|
|
180
|
+
source,
|
|
181
|
+
filter,
|
|
182
|
+
...(quietHours !== undefined ? { quietHours } : {}),
|
|
183
|
+
...(maxPerHour !== undefined ? { maxPerHour: maxPerHour } : {}),
|
|
184
|
+
}, input);
|
|
185
|
+
},
|
|
186
|
+
},
|
|
127
187
|
{
|
|
128
188
|
name: SCHEDULE_LIST_TOOL_NAME,
|
|
129
189
|
description: 'List your own schedules: cadence, prompt, destination, and when each fires next.',
|