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