@stratusagent/agents 0.11.4 → 0.11.5
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/define.d.ts +22 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +64 -0
- package/dist/define.js.map +1 -0
- package/dist/frontmatter.d.ts +65 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +260 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/identity.d.ts +139 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +259 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +11 -654
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -1641
- package/dist/index.js.map +1 -1
- package/dist/router.d.ts +18 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +44 -0
- package/dist/router.js.map +1 -0
- package/dist/schedules.d.ts +163 -0
- package/dist/schedules.d.ts.map +1 -0
- package/dist/schedules.js +215 -0
- package/dist/schedules.js.map +1 -0
- package/dist/skills.d.ts +135 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +167 -0
- package/dist/skills.js.map +1 -0
- package/dist/soul.d.ts +44 -0
- package/dist/soul.d.ts.map +1 -0
- package/dist/soul.js +98 -0
- package/dist/soul.js.map +1 -0
- package/dist/tools/delegate.d.ts +93 -0
- package/dist/tools/delegate.d.ts.map +1 -0
- package/dist/tools/delegate.js +223 -0
- package/dist/tools/delegate.js.map +1 -0
- package/dist/tools/gateway-only.d.ts +19 -0
- package/dist/tools/gateway-only.d.ts.map +1 -0
- package/dist/tools/gateway-only.js +29 -0
- package/dist/tools/gateway-only.js.map +1 -0
- package/dist/tools/memory.d.ts +51 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +306 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/message.d.ts +26 -0
- package/dist/tools/message.d.ts.map +1 -0
- package/dist/tools/message.js +46 -0
- package/dist/tools/message.js.map +1 -0
- package/dist/tools/schedule.d.ts +20 -0
- package/dist/tools/schedule.d.ts.map +1 -0
- package/dist/tools/schedule.js +146 -0
- package/dist/tools/schedule.js.map +1 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,655 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
*/
|
|
13
|
-
export declare const generateAgentName: (seed?: string) => string;
|
|
14
|
-
/**
|
|
15
|
-
* Derive an avatar theme from a name: a stable hue and a small palette in
|
|
16
|
-
* the shared Stratus house style. Consumers (CLI, web, macOS) draw the
|
|
17
|
-
* actual image from this so the agent looks the same on every surface.
|
|
18
|
-
*/
|
|
19
|
-
export declare const generateAvatarTheme: (name: string) => AvatarTheme;
|
|
20
|
-
/**
|
|
21
|
-
* The shape an id is *minted* in: lowercase alphanumerics and internal
|
|
22
|
-
* hyphens, starting with an alphanumeric. Everything `slugify` produces
|
|
23
|
-
* matches it, so every id this module derives does.
|
|
24
|
-
*
|
|
25
|
-
* Not what validation enforces. A hand-written `id:` predates any shape
|
|
26
|
-
* rule and `Ava_1` was as valid as `ava` — see `isValidAgentId`.
|
|
27
|
-
*/
|
|
28
|
-
export declare const AGENT_ID_PATTERN: RegExp;
|
|
29
|
-
/**
|
|
30
|
-
* How long an id we *build* is allowed to get. A construction bound, not a
|
|
31
|
-
* validation rule — `isValidAgentId` deliberately does not check it.
|
|
32
|
-
*
|
|
33
|
-
* Every id derived from a long name predates this bound, and enforcing it
|
|
34
|
-
* retroactively drops working agents off the roster, while trimming them
|
|
35
|
-
* silently re-keys their sessions, memory, and credentials to an id nobody
|
|
36
|
-
* has ever used. So the bound applies where an id is minted fresh and
|
|
37
|
-
* nothing is keyed to it yet, and nowhere else. File systems still have
|
|
38
|
-
* limits, and an id long enough to hit them fails at the join with a name
|
|
39
|
-
* that says so.
|
|
40
|
-
*/
|
|
41
|
-
export declare const MAX_AGENT_ID_LENGTH = 64;
|
|
42
|
-
/**
|
|
43
|
-
* Whether `id` is safe to key an agent's resources and paths by.
|
|
44
|
-
*
|
|
45
|
-
* Ids are not labels. They key sessions, memory, credentials, Slack channel
|
|
46
|
-
* tokens, and every per-agent path on disk — and an explicit frontmatter
|
|
47
|
-
* `id` is untrusted input: a soul file travels with a repository, and in
|
|
48
|
-
* the hosted profile it comes from a tenant. `id: ../../escape` reaches
|
|
49
|
-
* every one of those joins intact, so it is stopped once here rather than
|
|
50
|
-
* defended at each of them.
|
|
51
|
-
*
|
|
52
|
-
* **Unsafe is the rule, not un-sluglike.** Nothing before this checked an
|
|
53
|
-
* explicit id at all, so `Ava_1`, `team.alpha`, and `AVA` are all out there
|
|
54
|
-
* keying real sessions and real credentials. Holding them to the shape ids
|
|
55
|
-
* are minted in would not make anything safer — none of them can leave
|
|
56
|
-
* their directory — and `loadRosterSouls` degrades a soul that will not
|
|
57
|
-
* parse to a warning, so the only thing it would accomplish is dropping
|
|
58
|
-
* those agents off the roster on upgrade, quietly, while their data stays
|
|
59
|
-
* behind under the old id. Reserving the slug shape for ids nobody has
|
|
60
|
-
* chosen yet costs nothing; imposing it on ids people are already using
|
|
61
|
-
* costs them their agent.
|
|
62
|
-
*
|
|
63
|
-
* Rejected, never sanitized: rewriting `../../escape` into `escape` hands
|
|
64
|
-
* back an agent nobody asked for, keyed to resources nobody named.
|
|
65
|
-
*/
|
|
66
|
-
export declare const isValidAgentId: (id: string) => boolean;
|
|
67
|
-
/**
|
|
68
|
-
* Whether a `delegates` entry is one the soul can hold: any agent id, or
|
|
69
|
-
* the wildcard — the same rule as {@link isValidAgentId}, so every agent a
|
|
70
|
-
* roster can hold can be named as a target. Exported so the control API
|
|
71
|
-
* refuses a bad entry as the client's error rather than discovering it in
|
|
72
|
-
* the soul round-trip.
|
|
73
|
-
*/
|
|
74
|
-
export declare const isValidDelegateEntry: (entry: string) => boolean;
|
|
75
|
-
/**
|
|
76
|
-
* How much of a new session id is the *client's* to spend, on top of the
|
|
77
|
-
* agent id it addresses.
|
|
78
|
-
*
|
|
79
|
-
* Every id in circulation is a colon-joined address that embeds the agent
|
|
80
|
-
* id — `web:<agentId>:<uuid>` from the dashboard, a channel key of
|
|
81
|
-
* `<channel>:<agentId>:<team>:<conversation>:<thread>`, with a bare UUID
|
|
82
|
-
* from the CLI the one exception. So a flat cap is the wrong shape: agent
|
|
83
|
-
* ids are deliberately unbounded (see {@link isValidAgentId}), and a flat
|
|
84
|
-
* 200 refused every dashboard conversation for an agent whose id ran past
|
|
85
|
-
* 159 characters — an agent that stays on the roster and simply stops being
|
|
86
|
-
* chattable, which is the quiet-breakage failure the unbounded rule exists
|
|
87
|
-
* to avoid.
|
|
88
|
-
*
|
|
89
|
-
* Budgeting the composition instead keeps the bound meaningful without
|
|
90
|
-
* capping the agent id through the back door. It cannot be gamed to widen
|
|
91
|
-
* itself: the allowance comes from an agent id already checked against the
|
|
92
|
-
* roster, not from the caller's own string.
|
|
93
|
-
*/
|
|
94
|
-
export declare const MAX_SESSION_ID_LENGTH = 200;
|
|
95
|
-
/**
|
|
96
|
-
* Whether `id` may open a *new* conversation.
|
|
97
|
-
*
|
|
98
|
-
* Session ids are client-minted and a `POST` to an unknown one creates it,
|
|
99
|
-
* so this is the only thing standing between an HTTP caller and a durable
|
|
100
|
-
* row. `undefined`, `null`, and a bare space have all reached the session
|
|
101
|
-
* table through that door — the dashboard shipped the first of them.
|
|
102
|
-
*
|
|
103
|
-
* **Checked where an id is minted, never where one is used.** An id already
|
|
104
|
-
* in the store addresses a real conversation, whatever shape it is, and
|
|
105
|
-
* re-validating on read would lock someone out of their own history to
|
|
106
|
-
* enforce a rule that postdates it. Same reasoning as
|
|
107
|
-
* {@link MAX_AGENT_ID_LENGTH}, which is why the length bound lives here and
|
|
108
|
-
* not in {@link isValidAgentId}.
|
|
109
|
-
*
|
|
110
|
-
* `agentId` is the agent the id addresses, when the caller knows it — every
|
|
111
|
-
* client convention embeds it, so its length is part of the budget rather
|
|
112
|
-
* than something the bound gets to cap. The allowance applies only to an id
|
|
113
|
-
* that actually contains it, since those are the characters being paid for;
|
|
114
|
-
* a bare UUID and an unrelated string are both held to
|
|
115
|
-
* {@link MAX_SESSION_ID_LENGTH} alone, as they are when `agentId` is
|
|
116
|
-
* omitted.
|
|
117
|
-
*
|
|
118
|
-
* Shape is deliberately not enforced. Every id above is a legitimate
|
|
119
|
-
* address, and no pattern admitting all of them excludes `undefined` — so
|
|
120
|
-
* the safety rule, a bound, and {@link STRINGIFIED_NOTHING} are what catch
|
|
121
|
-
* the real mistakes. Rejected, never sanitized: trimming an id hands the
|
|
122
|
-
* caller back a conversation at an address it never asked for.
|
|
123
|
-
*/
|
|
124
|
-
export declare const isValidSessionId: (id: string, agentId?: string) => boolean;
|
|
125
|
-
/**
|
|
126
|
-
* A freshly minted id, bounded — `base` trimmed so that appending `suffix`
|
|
127
|
-
* still fits, with any hyphen left dangling by the trim removed.
|
|
128
|
-
*
|
|
129
|
-
* Only for ids nothing is keyed to yet: a generated agent's
|
|
130
|
-
* name-plus-suffix, and `agent new` retrying a filename collision. Both mint
|
|
131
|
-
* an id in the same breath as the agent, so trimming takes nothing away.
|
|
132
|
-
* Shared rather than re-derived so the two do not each own half of the bound
|
|
133
|
-
* and drift. An id derived from a name someone chose does *not* come through
|
|
134
|
-
* here — that name may already have an agent behind it.
|
|
135
|
-
*/
|
|
136
|
-
export declare const agentIdWithSuffix: (base: string, suffix?: string) => string;
|
|
137
|
-
export interface DefineAgentInput {
|
|
138
|
-
name?: string;
|
|
139
|
-
id?: string;
|
|
140
|
-
instructions?: string;
|
|
141
|
-
tools?: string[];
|
|
142
|
-
skills?: string[];
|
|
143
|
-
credentials?: string[];
|
|
144
|
-
delegates?: string[];
|
|
145
|
-
/** See `AgentDefinition.listens`. */
|
|
146
|
-
listens?: ListensMode;
|
|
147
|
-
avatar?: AvatarTheme;
|
|
148
|
-
/** Seed for deterministic identity generation (used in tests). */
|
|
149
|
-
seed?: string;
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* One-call agent creation. Everything is optional: with no input you get a
|
|
153
|
-
* fresh identity with a human-ish name and a matching avatar theme.
|
|
154
|
-
* Explicitly named agents keep a clean, predictable slug id.
|
|
155
|
-
*/
|
|
156
|
-
export declare const defineAgent: (input?: DefineAgentInput) => AgentDefinition;
|
|
157
|
-
/**
|
|
158
|
-
* Whether `agent` may delegate to the agent with id `targetId`. Exact ids
|
|
159
|
-
* or `*`; no namespace globs, because agent ids have no namespaces. Omitted
|
|
160
|
-
* is nobody — see `AgentDefinition.delegates`.
|
|
161
|
-
*/
|
|
162
|
-
export declare const isDelegateAllowed: (agent: Pick<AgentDefinition, "delegates">, targetId: string) => boolean;
|
|
163
|
-
/**
|
|
164
|
-
* A parsed soul file: the agent it defines plus optional runtime hints.
|
|
165
|
-
* Souls are markdown with frontmatter — the frontmatter carries structured
|
|
166
|
-
* identity (name, tools, credentials, provider, model) and the body is the
|
|
167
|
-
* persona itself, written in prose.
|
|
168
|
-
*/
|
|
169
|
-
export interface ParsedSoul {
|
|
170
|
-
agent: AgentDefinition;
|
|
171
|
-
/** Provider the soul prefers (e.g. "anthropic"). Runtimes may override. */
|
|
172
|
-
provider?: string;
|
|
173
|
-
/** Model the soul prefers (e.g. "claude-opus-5"). Runtimes may override. */
|
|
174
|
-
model?: string;
|
|
175
|
-
}
|
|
176
|
-
export interface ParseSoulOptions {
|
|
177
|
-
/** Seed for deterministic identity generation when the soul has no name. */
|
|
178
|
-
seed?: string;
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Parse a soul file (markdown with optional frontmatter) into an agent
|
|
182
|
-
* definition. The body becomes the agent's instructions; a missing name is
|
|
183
|
-
* generated, so the smallest possible soul is just prose.
|
|
184
|
-
*/
|
|
185
|
-
export declare const parseSoul: (source: string, options?: ParseSoulOptions) => ParsedSoul;
|
|
186
|
-
export declare const formatSoul: (soul: ParsedSoul) => string;
|
|
187
|
-
/**
|
|
188
|
-
* The shape a skill id is written in — the Agent Skills spec's rule for
|
|
189
|
-
* `name`, which is also the directory name: lowercase letters and digits
|
|
190
|
-
* in hyphen-separated runs (`web-research`), at most 64 characters, no
|
|
191
|
-
* leading, trailing, or doubled hyphen. One pattern for the manifest's
|
|
192
|
-
* declared ids, the operator directory's folder names, and install-time
|
|
193
|
-
* validation — two copies would drift into two answers to what a valid
|
|
194
|
-
* id is.
|
|
195
|
-
*/
|
|
196
|
-
export declare const SKILL_ID_PATTERN: RegExp;
|
|
197
|
-
/** The spec's ceiling on `name`, and so on a skill id. */
|
|
198
|
-
export declare const SKILL_ID_MAX_LENGTH = 64;
|
|
199
|
-
export declare const isValidSkillId: (id: string) => boolean;
|
|
200
|
-
/**
|
|
201
|
-
* Whether an id that is already on this machine — a directory under
|
|
202
|
-
* `~/.stratus/skills/`, a plugin manifest's declared id — is served.
|
|
203
|
-
* Wider than `isValidSkillId` on purpose: the spec's rule arrived after
|
|
204
|
-
* some of these were written, and tightening the *loader* would silently
|
|
205
|
-
* drop an enabled procedure from an agent on upgrade. Installing and
|
|
206
|
-
* validating use the strict rule; loading uses this one, and warns.
|
|
207
|
-
*/
|
|
208
|
-
export declare const isLoadableSkillId: (id: string) => boolean;
|
|
209
|
-
/** What a skill id refusal says, everywhere one is refused. */
|
|
210
|
-
export declare const SKILL_ID_RULE = "Skill ids are lowercase letters, digits, and single hyphens (web-research), at most 64 characters.";
|
|
211
|
-
/** The spec's ceiling on `description`. */
|
|
212
|
-
export declare const SKILL_DESCRIPTION_MAX_LENGTH = 1024;
|
|
213
|
-
/** The spec's ceiling on `compatibility`. */
|
|
214
|
-
export declare const SKILL_COMPATIBILITY_MAX_LENGTH = 500;
|
|
215
|
-
/**
|
|
216
|
-
* A parsed `SKILL.md`: the one-line identity that reaches the system
|
|
217
|
-
* prompt, and the body that only ever travels through `skill.read`.
|
|
218
|
-
*/
|
|
219
|
-
export interface ParsedSkillDocument {
|
|
220
|
-
/**
|
|
221
|
-
* The skill's name — under the spec, its id, and equal to its directory
|
|
222
|
-
* name. Optional here because loading stays tolerant of what is already
|
|
223
|
-
* installed; the registered skill falls back to its id.
|
|
224
|
-
*/
|
|
225
|
-
name?: string;
|
|
226
|
-
/**
|
|
227
|
-
* When to reach for this skill — what routing runs on, so it earns its
|
|
228
|
-
* place by saying when, not what the body contains.
|
|
229
|
-
*/
|
|
230
|
-
description: string;
|
|
231
|
-
/** The spec's `license`: a name, or a bundled file. Informational. */
|
|
232
|
-
license?: string;
|
|
233
|
-
/**
|
|
234
|
-
* The spec's `compatibility`: what the skill needs from its environment,
|
|
235
|
-
* in prose — for the operator installing it, since nothing here can act
|
|
236
|
-
* on it.
|
|
237
|
-
*/
|
|
238
|
-
compatibility?: string;
|
|
239
|
-
/** The spec's `metadata:` map, verbatim — every value a string. */
|
|
240
|
-
metadata?: Record<string, string>;
|
|
241
|
-
/** `metadata.version`, or the legacy top-level key. Informational. */
|
|
242
|
-
version?: string;
|
|
243
|
-
/**
|
|
244
|
-
* Toolset globs the procedure expects (`browser.*`), from
|
|
245
|
-
* `metadata.requires` (space-separated) or the legacy top-level list.
|
|
246
|
-
* Advisory — see `Skill.requires`.
|
|
247
|
-
*/
|
|
248
|
-
requires?: string[];
|
|
249
|
-
/**
|
|
250
|
-
* Top-level keys outside the spec, in file order — the legacy Stratus
|
|
251
|
-
* keys and other hosts' fields alike. What validation warns about.
|
|
252
|
-
*/
|
|
253
|
-
unknownKeys: string[];
|
|
254
|
-
body: string;
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Parse a `SKILL.md` — the same frontmatter dialect souls use (`key: value`
|
|
258
|
-
* scalars, block lists), plus the spec's `metadata:` map. The body is the
|
|
259
|
-
* procedure itself, markdown, untouched.
|
|
260
|
-
*
|
|
261
|
-
* `description` is required: it is the only thing the model sees before
|
|
262
|
-
* deciding to load the body, and a skill without one is unreachable by the
|
|
263
|
-
* mechanism that makes skills cheap. Everything the spec constrains beyond
|
|
264
|
-
* presence — the name rule, the length ceilings — is
|
|
265
|
-
* `validateSkillDocument`'s, so that loading what is already installed
|
|
266
|
-
* stays lenient while installing is strict.
|
|
267
|
-
*/
|
|
268
|
-
export declare const parseSkillDocument: (source: string) => ParsedSkillDocument;
|
|
269
|
-
export interface ValidateSkillDocumentOptions {
|
|
270
|
-
/**
|
|
271
|
-
* The directory the skill sits in (its basename), which the spec
|
|
272
|
-
* requires `name` to equal. Omit where the directory is circumstance
|
|
273
|
-
* rather than identity — a repository whose root is the skill, checked
|
|
274
|
-
* out wherever git put it.
|
|
275
|
-
*/
|
|
276
|
-
directoryName?: string;
|
|
277
|
-
/**
|
|
278
|
-
* What to suggest when `name` is missing — the directory name, or for a
|
|
279
|
-
* root skill the repository's. Only ever read for the error text.
|
|
280
|
-
*/
|
|
281
|
-
suggestedName?: string;
|
|
282
|
-
}
|
|
283
|
-
/** What `validateSkillDocument` found: errors refuse an install, warnings ride along. */
|
|
284
|
-
export interface SkillValidation {
|
|
285
|
-
errors: string[];
|
|
286
|
-
warnings: string[];
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Check a parsed `SKILL.md` against the Agent Skills spec — the checks
|
|
290
|
-
* `skills-ref validate` runs, so a skill that passes here passes there:
|
|
291
|
-
* `name` present, shaped like an id, equal to the directory name;
|
|
292
|
-
* `description` and `compatibility` under their ceilings. Errors are what
|
|
293
|
-
* refuses an install. Top-level keys the spec does not define are
|
|
294
|
-
* warnings, not errors: the reference validator refuses them, but the
|
|
295
|
-
* ecosystem's skills carry other hosts' fields routinely, and refusing a
|
|
296
|
-
* skill over a field that changes nothing here fails the whole point of
|
|
297
|
-
* conforming. The legacy Stratus keys get their own warning, naming the
|
|
298
|
-
* `metadata:` form that ports.
|
|
299
|
-
*
|
|
300
|
-
* Loading never calls this — an installed skill keeps loading whatever
|
|
301
|
-
* the spec says today. Installing always does.
|
|
302
|
-
*/
|
|
303
|
-
export declare const validateSkillDocument: (document: ParsedSkillDocument, options?: ValidateSkillDocumentOptions) => SkillValidation;
|
|
304
|
-
export interface LazySkillInput {
|
|
305
|
-
/** The id the skill registers under — qualified for a plugin's skill. */
|
|
306
|
-
id: string;
|
|
307
|
-
/** The parsed document, from the load-time read that validated the file. */
|
|
308
|
-
document: ParsedSkillDocument;
|
|
309
|
-
/** Re-read the file's source. Called on demand; the registry caches. */
|
|
310
|
-
read: () => Promise<string>;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* A `Skill` whose body stays on disk until somebody asks. The identity
|
|
314
|
-
* comes from the load-time parse (which is also what validated the file);
|
|
315
|
-
* `load()` re-reads rather than closing over the body, so an
|
|
316
|
-
* enabled-but-unused skill costs its description line and nothing else —
|
|
317
|
-
* in the prompt and in memory.
|
|
318
|
-
*/
|
|
319
|
-
export declare const createLazySkill: ({ id, document, read }: LazySkillInput) => Skill;
|
|
320
|
-
export declare const MEMORY_TOOL_NAME = "memory.remember";
|
|
321
|
-
/**
|
|
322
|
-
* A tool that lets an agent write to its own long-term memory. Entries are
|
|
323
|
-
* keyed by the session's agent id, so what one agent learns stays exclusively
|
|
324
|
-
* that agent's knowledge — and follows it to every channel and thread.
|
|
325
|
-
*/
|
|
326
|
-
export declare const createRememberTool: (store: AgentMemoryStore) => Tool;
|
|
327
|
-
export declare const RECALL_TOOL_NAME = "memory.recall";
|
|
328
|
-
/**
|
|
329
|
-
* Searches the agent's own long-term memory. `safe` by the same rule as
|
|
330
|
-
* `memory.remember`: reading what this agent already knows. The query is
|
|
331
|
-
* literal text — the store does whatever escaping its backend needs, so no
|
|
332
|
-
* query a model writes is ever a syntax error; matching nothing is a normal
|
|
333
|
-
* result, because an agent that has learned nothing yet is the ordinary
|
|
334
|
-
* starting state, not a broken tool.
|
|
335
|
-
*/
|
|
336
|
-
export declare const createRecallTool: (store: AgentMemoryStore) => Tool;
|
|
337
|
-
export declare const FORGET_TOOL_NAME = "memory.forget";
|
|
338
|
-
/**
|
|
339
|
-
* Retires one of the agent's own memories, by id. Tombstoned rather than
|
|
340
|
-
* deleted — which is what makes `safe` defensible for it: the entry stops
|
|
341
|
-
* being live but does not stop existing, so an operator can still see what
|
|
342
|
-
* an agent chose to drop.
|
|
343
|
-
*/
|
|
344
|
-
export declare const createForgetTool: (store: AgentMemoryStore) => Tool;
|
|
345
|
-
export declare const DELEGATE_TOOL_NAME = "agent.delegate";
|
|
346
|
-
/**
|
|
347
|
-
* Metadata a delegated sub-session carries: which agent delegated, and the
|
|
348
|
-
* session at the root of the chain. Written by `agent.delegate` and read by
|
|
349
|
-
* the gateway's restart sweep, which is why the keys are named here rather
|
|
350
|
-
* than spelled twice — a sub-session's parent is a turn in some other
|
|
351
|
-
* process's memory, and after a restart nothing can consume its reply.
|
|
352
|
-
*/
|
|
353
|
-
export declare const DELEGATED_BY_METADATA_KEY = "delegatedBy";
|
|
354
|
-
export declare const ROOT_SESSION_ID_METADATA_KEY = "rootSessionId";
|
|
355
|
-
export declare const DELEGATION_DEPTH_METADATA_KEY = "delegationDepth";
|
|
356
|
-
/**
|
|
357
|
-
* The segment `agent.delegate` mints into every sub-session's id —
|
|
358
|
-
* `<parent>:delegate:<agent>:<depth>:<suffix>`. The second half of what
|
|
359
|
-
* identifies a sub-session, beside the metadata above: the gateway refuses
|
|
360
|
-
* the metadata keys at its public door, but rows written before it did
|
|
361
|
-
* cannot be told apart by their metadata alone, and a caller who wrote
|
|
362
|
-
* `delegatedBy` onto a session of its own would not also have minted an
|
|
363
|
-
* id in this shape.
|
|
364
|
-
*/
|
|
365
|
-
export declare const DELEGATED_SESSION_ID_MARKER = ":delegate:";
|
|
366
|
-
/**
|
|
367
|
-
* Whether this session is a delegated sub-session — one whose reply is
|
|
368
|
-
* consumed by a parent turn's `agent.delegate` call and by nothing else.
|
|
369
|
-
* Both halves are required: the metadata `agent.delegate` writes, and the
|
|
370
|
-
* id shape it mints.
|
|
371
|
-
*/
|
|
372
|
-
export declare const isDelegatedSession: (session: Pick<Session, "id" | "metadata">) => boolean;
|
|
373
|
-
/**
|
|
374
|
-
* The id of the session whose `agent.delegate` call started this one, read
|
|
375
|
-
* off the id shape above — the text before the last marker, since a nested
|
|
376
|
-
* sub-session embeds its parent's id whole. Undefined for an id that was
|
|
377
|
-
* not minted that way.
|
|
378
|
-
*/
|
|
379
|
-
export declare const delegatingSessionIdOf: (sessionId: string) => string | undefined;
|
|
380
|
-
/**
|
|
381
|
-
* The id of the `agent.delegate` call in `parent` that is still awaiting
|
|
382
|
-
* `child`, or undefined when none is.
|
|
383
|
-
*
|
|
384
|
-
* The one thing about a delegation nothing outside the runner can forge:
|
|
385
|
-
* a caller can name a session in the sub-session id shape and write the
|
|
386
|
-
* metadata keys, but only the runner writes assistant tool calls, and only
|
|
387
|
-
* a delegation in flight leaves one with no result behind it. Matched to
|
|
388
|
-
* the child and not merely counted, because a parent can be inside one
|
|
389
|
-
* delegation while an earlier sub-session of its — continued from outside
|
|
390
|
-
* under a version that kept the markers — is parked on something of its
|
|
391
|
-
* own. The call names its target and its prompt, and `agent.delegate`
|
|
392
|
-
* made the prompt the child's first user message. Read against the
|
|
393
|
-
* transcript order so a re-used call id cannot make a later call look
|
|
394
|
-
* answered.
|
|
395
|
-
*/
|
|
396
|
-
export declare const outstandingDelegationFor: (parent: Pick<Session, "messages">, child: Pick<Session, "agent" | "messages">) => string | undefined;
|
|
397
|
-
/**
|
|
398
|
-
* `metadata` with the delegation markers removed — what a sub-session
|
|
399
|
-
* carries once it has been addressed from outside. The delegation ended
|
|
400
|
-
* with the turn that awaited it; a conversation somebody continues on the
|
|
401
|
-
* same id afterwards is an ordinary one, and must not be closed as an
|
|
402
|
-
* orphan by a later restart.
|
|
403
|
-
*/
|
|
404
|
-
export declare const withoutDelegation: (metadata: JsonObject) => JsonObject;
|
|
405
|
-
/**
|
|
406
|
-
* Runs a delegated sub-session. A plain runner works when every agent
|
|
407
|
-
* shares one provider; a host with per-agent provider routing (the
|
|
408
|
-
* gateway) supplies its own dispatcher so the target runs on the
|
|
409
|
-
* target's resolved provider and credentials — never the delegator's.
|
|
410
|
-
*/
|
|
411
|
-
export type DelegateDispatch = (input: {
|
|
412
|
-
sessionId: string;
|
|
413
|
-
agent: AgentDefinition;
|
|
414
|
-
userMessage: string;
|
|
415
|
-
metadata: JsonObject;
|
|
416
|
-
/** The parent turn's abort signal — a cancelled parent cancels the delegated run too. */
|
|
417
|
-
signal?: AbortSignal;
|
|
418
|
-
}) => Promise<Session>;
|
|
419
|
-
export type DelegateToolOptions = {
|
|
420
|
-
registry: AgentRegistry;
|
|
421
|
-
/** Maximum delegation depth to stop orchestrator loops. Default 3. */
|
|
422
|
-
maxDepth?: number;
|
|
423
|
-
} & ({
|
|
424
|
-
runner: AgentRunner;
|
|
425
|
-
dispatch?: never;
|
|
426
|
-
} | {
|
|
427
|
-
dispatch: DelegateDispatch;
|
|
428
|
-
runner?: never;
|
|
429
|
-
});
|
|
430
|
-
/**
|
|
431
|
-
* The orchestrator primitive: a tool that runs another agent in its own
|
|
432
|
-
* sub-session (with that agent's memory, tool allowlist, and credentials)
|
|
433
|
-
* and returns its final reply as the tool result.
|
|
434
|
-
*/
|
|
435
|
-
export declare const createDelegateTool: ({ registry, runner, dispatch, maxDepth, }: DelegateToolOptions) => Tool;
|
|
436
|
-
export interface AgentRouteRule {
|
|
437
|
-
/** Regex or predicate matched against the routing key (e.g. channel or message). */
|
|
438
|
-
match: RegExp | ((input: string) => boolean);
|
|
439
|
-
agent: AgentDefinition;
|
|
440
|
-
}
|
|
441
|
-
export interface AgentRouter {
|
|
442
|
-
route(input: string): AgentDefinition;
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Route inbound work (a channel name, a message, a thread key) to an agent.
|
|
446
|
-
* The Slack transport will feed channel/mention strings through this so the
|
|
447
|
-
* same person consistently answers in the same places.
|
|
448
|
-
*/
|
|
449
|
-
export declare const createAgentRouter: (rules: AgentRouteRule[], fallback: AgentDefinition) => AgentRouter;
|
|
450
|
-
/** Register a set of agents and get the registry back. */
|
|
451
|
-
export declare const createAgentTeam: (agents: AgentDefinition[]) => AgentRegistry;
|
|
452
|
-
/**
|
|
453
|
-
* Where a schedule reports, or a `message.send` speaks: a channel kind plus
|
|
454
|
-
* a channel-native id — the same convention approver lists use, because
|
|
455
|
-
* mapping through a Stratus identity adds a lookup that can only be wrong.
|
|
456
|
-
*/
|
|
457
|
-
export interface ScheduleDestination {
|
|
458
|
-
/** Channel kind, e.g. 'slack' — which adapter must do the talking. */
|
|
459
|
-
channel: string;
|
|
460
|
-
/** Channel-native conversation id (Slack: `C…`/`G…`/`D…`). */
|
|
461
|
-
to: string;
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* The one string form of a destination, `<channel>:<native id>`, used
|
|
465
|
-
* everywhere a destination is *compared*: `Tool.destinationFor`, the
|
|
466
|
-
* permission policy's pre-authorization check, and the schedule row it is
|
|
467
|
-
* checked against. One canonicalization, or two writers of `slack:C01` and
|
|
468
|
-
* `SLACK:C01` would disagree about the same channel.
|
|
469
|
-
*/
|
|
470
|
-
export declare const canonicalDestination: (destination: ScheduleDestination) => string;
|
|
471
|
-
/**
|
|
472
|
-
* When a schedule runs. Three shapes rather than one string, because the
|
|
473
|
-
* three are advanced differently: an interval adds itself to the previous
|
|
474
|
-
* slot, a cron expression is searched forward, and a one-shot has no next
|
|
475
|
-
* at all.
|
|
476
|
-
*/
|
|
477
|
-
export type ScheduleCadence = {
|
|
478
|
-
kind: 'every';
|
|
479
|
-
intervalMs: number;
|
|
480
|
-
} | {
|
|
481
|
-
kind: 'cron';
|
|
482
|
-
expression: string;
|
|
483
|
-
} | {
|
|
484
|
-
kind: 'at';
|
|
485
|
-
at: string;
|
|
486
|
-
};
|
|
487
|
-
/** One durable schedule, exactly as the human approved it. */
|
|
488
|
-
export interface ScheduleRecord {
|
|
489
|
-
id: string;
|
|
490
|
-
agentId: string;
|
|
491
|
-
cadence: ScheduleCadence;
|
|
492
|
-
/** The user message each firing dispatches — the payload of the feature. */
|
|
493
|
-
prompt: string;
|
|
494
|
-
/**
|
|
495
|
-
* Where firings are pre-authorized to report. Absent for a silent
|
|
496
|
-
* schedule, whose firings face the gate like any inbound turn.
|
|
497
|
-
*/
|
|
498
|
-
destination?: ScheduleDestination;
|
|
499
|
-
createdAt: string;
|
|
500
|
-
/** The session whose turn created it, for the audit trail. */
|
|
501
|
-
createdBy?: string;
|
|
502
|
-
/**
|
|
503
|
-
* The trust label of the session that set the schedule. The prompt is
|
|
504
|
-
* that session's text, so each firing's "sender" is the agent's past
|
|
505
|
-
* self at that label — a tainted session must not launder attacker text
|
|
506
|
-
* into a fresh, trusted firing. Absent on a schedule set before
|
|
507
|
-
* provenance was tracked, and a firing reads that as `unknown`.
|
|
508
|
-
*/
|
|
509
|
-
trust?: TrustLevel;
|
|
510
|
-
/**
|
|
511
|
-
* The next slot, ISO-8601. Consumed — advanced — BEFORE the dispatch, so
|
|
512
|
-
* a daemon that dies mid-firing can never run the same window twice.
|
|
513
|
-
* Absent for a spent one-shot: it will not fire again and its row stays
|
|
514
|
-
* only until the firing it pre-authorized has finished.
|
|
515
|
-
*/
|
|
516
|
-
nextFireAt?: string;
|
|
517
|
-
lastFiredAt?: string;
|
|
518
|
-
/**
|
|
519
|
-
* The session id of the most recent firing. What the restart sweep uses
|
|
520
|
-
* to tell a spent one-shot whose turn is parked on a human (keep the row
|
|
521
|
-
* — it is the approval's scope) from one whose turn is over (delete it).
|
|
522
|
-
*/
|
|
523
|
-
lastSessionId?: string;
|
|
524
|
-
}
|
|
525
|
-
/** `every` strings: a positive integer and one unit — `90s`, `10m`, `2h`, `1d`. */
|
|
526
|
-
export declare const parseInterval: (text: string) => number | undefined;
|
|
527
|
-
interface CronFields {
|
|
528
|
-
minutes: Set<number>;
|
|
529
|
-
hours: Set<number>;
|
|
530
|
-
daysOfMonth: Set<number>;
|
|
531
|
-
months: Set<number>;
|
|
532
|
-
daysOfWeek: Set<number>;
|
|
533
|
-
/**
|
|
534
|
-
* Whether the day fields were written as anything but `*`. Standard cron
|
|
535
|
-
* semantics: when BOTH are restricted, a day matches if EITHER does —
|
|
536
|
-
* `0 0 1 * 1` is "the 1st, and every Monday", not "the 1st when it is a
|
|
537
|
-
* Monday".
|
|
538
|
-
*/
|
|
539
|
-
domRestricted: boolean;
|
|
540
|
-
dowRestricted: boolean;
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* Five fields — minute, hour, day-of-month, month, day-of-week — with `*`,
|
|
544
|
-
* lists, ranges, and steps. Numbers only; day-of-week 0-7 with both 0 and 7
|
|
545
|
-
* as Sunday. Evaluated in the daemon's local time, which is what "every
|
|
546
|
-
* morning at 7" means to the person whose machine it is.
|
|
547
|
-
*/
|
|
548
|
-
export declare const parseCronExpression: (expression: string) => CronFields;
|
|
549
|
-
/**
|
|
550
|
-
* The slot after `after`, or undefined when there is none — a one-shot
|
|
551
|
-
* already past, or a cron expression that matches no real date. One
|
|
552
|
-
* implementation, because the scheduler advancing a fired slot and the
|
|
553
|
-
* creation path computing the first one must never disagree.
|
|
554
|
-
*/
|
|
555
|
-
export declare const nextFireAfter: (cadence: ScheduleCadence, after: Date) => Date | undefined;
|
|
556
|
-
/** One line for a human: `every 30m`, `cron 0 7 * * *`, `once at 2026-…`. */
|
|
557
|
-
export declare const describeCadence: (cadence: ScheduleCadence) => string;
|
|
558
|
-
/**
|
|
559
|
-
* Metadata a firing's session carries. The schedule id is what the
|
|
560
|
-
* permission carve-out resolves the approved destination from, and
|
|
561
|
-
* `scheduled: true` is what lets a renderer say a turn arrived from a
|
|
562
|
-
* schedule rather than a person.
|
|
563
|
-
*/
|
|
564
|
-
export declare const SCHEDULE_ID_METADATA_KEY = "scheduleId";
|
|
565
|
-
export declare const SCHEDULED_TURN_METADATA_KEY = "scheduled";
|
|
566
|
-
export declare const SCHEDULE_EVERY_TOOL_NAME = "schedule.every";
|
|
567
|
-
export declare const SCHEDULE_AT_TOOL_NAME = "schedule.at";
|
|
568
|
-
export declare const SCHEDULE_LIST_TOOL_NAME = "schedule.list";
|
|
569
|
-
export declare const SCHEDULE_CANCEL_TOOL_NAME = "schedule.cancel";
|
|
570
|
-
export declare const MESSAGE_SEND_TOOL_NAME = "message.send";
|
|
571
|
-
/**
|
|
572
|
-
* The tools only a running gateway registers. Each needs the dispatcher,
|
|
573
|
-
* the store, or the channels, and nothing else in the tree has them — so a
|
|
574
|
-
* soul naming one is correct while a host without them cannot call it,
|
|
575
|
-
* which is a different thing from a name that does not exist. `stratus
|
|
576
|
-
* run` reads this to say which it is rather than reporting a daemon soul's
|
|
577
|
-
* `schedule.*` as a typo.
|
|
578
|
-
*
|
|
579
|
-
* It lives here, with the names, rather than in `@stratusagent/gateway`
|
|
580
|
-
* where the registrations are: the CLI imports the gateway only through
|
|
581
|
-
* `await import`, because `bin.ts` has to load the CLI to print the Node
|
|
582
|
-
* version message and the gateway pulls in `node:sqlite` at module scope.
|
|
583
|
-
* A static import for a list of strings would have made the floor guard
|
|
584
|
-
* fail with the exact builtin-module error it exists to replace. The
|
|
585
|
-
* gateway's own test pins this set against what it actually registers,
|
|
586
|
-
* which holds the two together better than proximity would.
|
|
587
|
-
*/
|
|
588
|
-
export declare const GATEWAY_ONLY_TOOL_NAMES: readonly string[];
|
|
589
|
-
export interface ScheduleCreateInput {
|
|
590
|
-
agentId: string;
|
|
591
|
-
cadence: ScheduleCadence;
|
|
592
|
-
prompt: string;
|
|
593
|
-
destination?: ScheduleDestination;
|
|
594
|
-
/** The session whose turn asked, for the audit trail. */
|
|
595
|
-
createdBy?: string;
|
|
596
|
-
/** That session's trust label at the time — see `ScheduleRecord.trust`. */
|
|
597
|
-
trust?: TrustLevel;
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* The gateway-supplied handle the schedule tools close over — the same
|
|
601
|
-
* pattern as `agent.delegate`'s dispatcher, because the scheduler needs the
|
|
602
|
-
* store, the roster, and the channels, and none of those are this package's
|
|
603
|
-
* to hold. `create` owns every refusal that needs daemon knowledge: the
|
|
604
|
-
* interval floor, and a destination the agent's channel cannot address —
|
|
605
|
-
* checked NOW, while a person is present to hear why, not at 6am.
|
|
606
|
-
*/
|
|
607
|
-
export interface SchedulerHandle {
|
|
608
|
-
create(input: ScheduleCreateInput): Promise<ScheduleRecord>;
|
|
609
|
-
list(agentId: string): Promise<ScheduleRecord[]>;
|
|
610
|
-
/** True when a schedule of this agent's was cancelled; false when nothing matched. */
|
|
611
|
-
cancel(agentId: string, scheduleId: string): Promise<boolean>;
|
|
612
|
-
}
|
|
613
|
-
/**
|
|
614
|
-
* One schedule as a surface shows it — the CLI table, the control API's
|
|
615
|
-
* listing, and the tool results all render this one projection, so the
|
|
616
|
-
* operator's view and the agent's cannot drift.
|
|
617
|
-
*/
|
|
618
|
-
export declare const describeSchedule: (record: ScheduleRecord) => JsonObject;
|
|
619
|
-
/**
|
|
620
|
-
* The four `schedule.*` tools over one handle.
|
|
621
|
-
*
|
|
622
|
-
* Risk is split per tool, not per toolset: creating a schedule spends
|
|
623
|
-
* future money unattended and (with a destination) mints a standing
|
|
624
|
-
* permission to speak, so `schedule.every` and `schedule.at` are `gated` —
|
|
625
|
-
* the approval of THAT call is the human decision the whole step leans on.
|
|
626
|
-
* `schedule.list` is a read, and `schedule.cancel` only ever narrows
|
|
627
|
-
* authority — it is the reversal the risk note in the spec names — so both
|
|
628
|
-
* are `safe`: a headless agent that set a bad schedule must be able to
|
|
629
|
-
* undo it without waiting for the human whose absence is the problem.
|
|
630
|
-
*/
|
|
631
|
-
export declare const createScheduleTools: (scheduler: SchedulerHandle) => Tool[];
|
|
632
|
-
/**
|
|
633
|
-
* Delivers one outbound message through the agent's channel. The gateway
|
|
634
|
-
* implements it over the channel contract's `resolveOutbound`; rejecting is
|
|
635
|
-
* the way to say a destination cannot be served.
|
|
636
|
-
*/
|
|
637
|
-
export type OutboundMessenger = (input: {
|
|
638
|
-
agentId: string;
|
|
639
|
-
destination: ScheduleDestination;
|
|
640
|
-
text: string;
|
|
641
|
-
}) => Promise<void>;
|
|
642
|
-
/**
|
|
643
|
-
* Post to a channel or DM outside the current conversation — what makes a
|
|
644
|
-
* scheduled turn observable.
|
|
645
|
-
*
|
|
646
|
-
* `gated`, and deliberately not `safe` the way `agent.delegate` is: the
|
|
647
|
-
* delegate stays inside the fleet, under every per-agent allowlist and the
|
|
648
|
-
* same approval policy, while this speaks to people who did not ask. The
|
|
649
|
-
* unattended path is the schedule carve-out — `destinationFor` names where
|
|
650
|
-
* this call would speak, and the policy allows it exactly when the firing's
|
|
651
|
-
* schedule was approved with that destination.
|
|
652
|
-
*/
|
|
653
|
-
export declare const createMessageSendTool: (send: OutboundMessenger) => Tool;
|
|
654
|
-
export {};
|
|
1
|
+
export { AVATAR_STYLE, generateAgentName, generateAvatarTheme, AGENT_ID_PATTERN, MAX_AGENT_ID_LENGTH, isValidAgentId, isValidDelegateEntry, MAX_SESSION_ID_LENGTH, isValidSessionId, agentIdWithSuffix, } from './identity.ts';
|
|
2
|
+
export { type DefineAgentInput, defineAgent } from './define.ts';
|
|
3
|
+
export { isDelegateAllowed, type ParsedSoul, type ParseSoulOptions, parseSoul, formatSoul, } from './soul.ts';
|
|
4
|
+
export { SKILL_ID_PATTERN, SKILL_ID_MAX_LENGTH, isValidSkillId, isLoadableSkillId, SKILL_ID_RULE, SKILL_DESCRIPTION_MAX_LENGTH, SKILL_COMPATIBILITY_MAX_LENGTH, type ParsedSkillDocument, parseSkillDocument, type ValidateSkillDocumentOptions, type SkillValidation, validateSkillDocument, type LazySkillInput, createLazySkill, } from './skills.ts';
|
|
5
|
+
export { type ScheduleDestination, canonicalDestination, type ScheduleCadence, type ScheduleRecord, parseInterval, parseCronExpression, nextFireAfter, describeCadence, SCHEDULE_ID_METADATA_KEY, SCHEDULED_TURN_METADATA_KEY, type ScheduleCreateInput, type SchedulerHandle, describeSchedule, } from './schedules.ts';
|
|
6
|
+
export { type AgentRouteRule, type AgentRouter, createAgentRouter, createAgentTeam, } from './router.ts';
|
|
7
|
+
export { MEMORY_TOOL_NAME, createRememberTool, RECALL_TOOL_NAME, createRecallTool, FORGET_TOOL_NAME, createForgetTool, PIN_TOOL_NAME, createPinTool, type MemoryToolOptions, } from './tools/memory.ts';
|
|
8
|
+
export { DELEGATE_TOOL_NAME, DELEGATED_BY_METADATA_KEY, ROOT_SESSION_ID_METADATA_KEY, DELEGATION_DEPTH_METADATA_KEY, DELEGATED_SESSION_ID_MARKER, isDelegatedSession, delegatingSessionIdOf, outstandingDelegationFor, withoutDelegation, type DelegateDispatch, type DelegateToolOptions, createDelegateTool, } from './tools/delegate.ts';
|
|
9
|
+
export { SCHEDULE_EVERY_TOOL_NAME, SCHEDULE_AT_TOOL_NAME, SCHEDULE_LIST_TOOL_NAME, SCHEDULE_CANCEL_TOOL_NAME, createScheduleTools, } from './tools/schedule.ts';
|
|
10
|
+
export { MESSAGE_SEND_TOOL_NAME, type OutboundMessenger, createMessageSendTool, } from './tools/message.ts';
|
|
11
|
+
export { GATEWAY_ONLY_TOOL_NAMES } from './tools/gateway-only.ts';
|
|
655
12
|
//# sourceMappingURL=index.d.ts.map
|