pi-roundtable 0.1.0 → 0.2.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/CHANGELOG.md +138 -0
- package/README.md +6 -4
- package/docs/plugins.md +1448 -66
- package/examples/echo-runtime.test.ts +122 -0
- package/examples/echo-runtime.ts +107 -0
- package/examples/events.test.ts +1 -0
- package/examples/events.ts +2 -2
- package/examples/fake-surface.test.ts +180 -0
- package/examples/fake-surface.ts +109 -0
- package/examples/interactions.test.ts +12 -3
- package/examples/interactions.ts +19 -19
- package/examples/shared-services.test.ts +74 -0
- package/examples/shared-services.ts +60 -0
- package/examples/study-room.test.ts +69 -0
- package/examples/study-room.ts +52 -0
- package/examples/support-desk.test.ts +34 -0
- package/examples/support-desk.ts +40 -0
- package/package.json +9 -2
- package/src/cli/checks/database.ts +11 -30
- package/src/cli/checks/images.ts +19 -0
- package/src/cli/doctor.ts +6 -0
- package/src/cli/main.ts +2 -1
- package/src/core/agents/agent-claim.ts +42 -16
- package/src/core/agents/agent-messages.ts +4 -4
- package/src/core/agents/agent-ports.ts +8 -21
- package/src/core/agents/agent-prompt.ts +3 -1
- package/src/core/agents/agent-store.ts +6 -4
- package/src/core/agents/agent-team-fixture.ts +389 -0
- package/src/core/agents/agent-team.ts +26 -25
- package/src/core/agents/agent-tools.ts +34 -15
- package/src/core/agents/avatar-studio.ts +40 -6
- package/src/core/agents/fallback-avatar.ts +85 -0
- package/src/core/agents/team-editing.ts +49 -10
- package/src/core/agents/team-keys.ts +22 -9
- package/src/core/agents/team-layout.ts +4 -3
- package/src/core/agents/team-lifecycle.ts +28 -2
- package/src/core/agents/team-options.ts +9 -5
- package/src/core/agents/team-status.ts +4 -4
- package/src/core/agents/team-text.ts +8 -6
- package/src/core/agents/team-turn-types.ts +4 -4
- package/src/core/agents/team-turns.ts +6 -5
- package/src/core/builtin/agent-server.ts +187 -121
- package/src/core/builtin/discord-admin.ts +41 -0
- package/src/core/builtin/discord.ts +65 -40
- package/src/core/builtin/modules.ts +67 -58
- package/src/core/builtin/session-tool.ts +24 -0
- package/src/core/builtin/skills.ts +72 -0
- package/src/core/builtin/stores.ts +55 -31
- package/src/core/config/config.ts +45 -4
- package/src/core/config/schema.ts +6 -0
- package/src/core/contract/channels.ts +54 -14
- package/src/core/contract/providers.ts +17 -0
- package/src/core/contract/runtime.ts +138 -0
- package/src/core/contract/services.ts +45 -0
- package/src/core/contract/surface.ts +88 -0
- package/src/core/db/migrations.ts +118 -3
- package/src/core/define-roundtable.ts +70 -46
- package/src/core/define.ts +2 -1
- package/src/core/discord/agent-commands.ts +39 -14
- package/src/core/discord/agent-panel.ts +66 -0
- package/src/core/discord/channel-executor.ts +6 -3
- package/src/core/discord/channel-operations.ts +14 -11
- package/src/core/discord/command-collection.ts +46 -0
- package/src/core/{registry/interactions.ts → discord/compose-commands.ts} +5 -5
- package/src/core/discord/connection.ts +35 -0
- package/src/core/discord/discord-surface.ts +32 -94
- package/src/core/discord/dispatch-threads.ts +2 -2
- package/src/core/discord/inbound-message.ts +99 -0
- package/src/core/discord/interaction-module.ts +57 -1
- package/src/core/discord/owner-cards.ts +4 -4
- package/src/core/discord/owner-command.ts +44 -11
- package/src/core/discord/owner-discord.ts +2 -2
- package/src/core/discord/schedule-commands.ts +21 -18
- package/src/core/discord/stop-button.ts +44 -1
- package/src/core/domain/attachment.ts +12 -8
- package/src/core/domain/conversation.ts +3 -4
- package/src/core/domain/owner-prompts.ts +5 -5
- package/src/core/domain/ports.ts +9 -53
- package/src/core/freeze.ts +9 -0
- package/src/core/host.ts +255 -82
- package/src/core/http/listeners.ts +55 -20
- package/src/core/i18n/agent-panel.ts +4 -0
- package/src/core/i18n/index.ts +12 -2
- package/src/core/i18n/owner.ts +7 -1
- package/src/core/i18n/schedules.ts +12 -6
- package/src/core/identity.ts +1 -1
- package/src/core/judging/effort-judge.ts +25 -3
- package/src/core/log.ts +21 -3
- package/src/core/models.ts +2 -2
- package/src/core/modules/background/background-turns.ts +6 -4
- package/src/core/modules/delegation/delegate.ts +3 -2
- package/src/core/modules/delegation/delegator.ts +15 -13
- package/src/core/modules/delegation/{sol-worker.ts → web-research-worker.ts} +6 -6
- package/src/core/modules/discord-admin/discord-admin.ts +6 -6
- package/src/core/modules/host-shell/shell-policy.ts +8 -3
- package/src/core/modules/memory/owner-memory-store.ts +27 -25
- package/src/core/modules/memory/owner-memory.ts +9 -13
- package/src/core/modules/schedules/recurrence.ts +5 -3
- package/src/core/modules/schedules/schedule-store.ts +11 -11
- package/src/core/modules/schedules/schedule-tools.ts +22 -20
- package/src/core/modules/schedules/scheduler.ts +7 -2
- package/src/core/modules/schedules/schedules.ts +9 -3
- package/src/core/modules/skills/skill-registry.ts +3 -2
- package/src/core/modules/skills/skill-store.ts +2 -15
- package/src/core/modules/skills/skill-tools.ts +10 -4
- package/src/core/ops/error-reporter.ts +1 -1
- package/src/core/plugin.ts +232 -28
- package/src/core/registry/contributions.ts +173 -14
- package/src/core/registry/providers.ts +35 -5
- package/src/core/registry/services.ts +229 -0
- package/src/core/routing/channel-queue.ts +5 -0
- package/src/core/routing/channel-router.ts +21 -7
- package/src/core/routing/conversation-turns.ts +139 -0
- package/src/core/routing/message-text.ts +9 -2
- package/src/core/routing/surface-port.ts +39 -0
- package/src/core/runtime/conversation-sessions.ts +4 -3
- package/src/core/runtime/extensions/confirmation-fixture.ts +11 -0
- package/src/core/runtime/extensions/confirmation-gate.ts +11 -9
- package/src/core/runtime/mcp.ts +1 -1
- package/src/core/runtime/pending-confirmation-store.ts +10 -12
- package/src/core/runtime/pi-agent-runtime.ts +9 -6
- package/src/core/runtime/prompt-slot.ts +8 -3
- package/src/core/runtime/runtime-types.ts +9 -35
- package/src/core/runtime/session-factory.ts +21 -5
- package/src/core/runtime/text-tools.ts +1 -3
- package/src/core/services.ts +238 -90
- package/src/core/sessions.ts +3 -2
- package/src/core/shared/{profile-tools.ts → active-tools.ts} +2 -2
- package/src/core/shared/delegate-tool.ts +4 -3
- package/src/core/shared/schedule-tools.ts +22 -13
- package/src/core/shared/session-messages.ts +1 -1
- package/src/core/speakers.ts +6 -38
- package/src/core/testing/database.ts +1 -7
- package/src/core/testing/eager-catalog.ts +30 -0
- package/src/core/testing/locale.ts +23 -5
- package/src/core/testing/modules.ts +105 -41
- package/src/core/testing/test-host.ts +279 -0
- package/src/core/testing/tool-set.ts +64 -0
- package/src/core/time.ts +6 -1
- package/src/core/tool-set.snapshot.json +288 -0
- package/src/core/tool-tiers.ts +17 -57
- package/src/discord/index.ts +64 -0
- package/src/index.ts +181 -10
- package/src/kit/channels.ts +14 -0
- package/src/kit/domain.ts +18 -0
- package/src/kit/holds.ts +4 -0
- package/src/kit/index.ts +129 -0
- package/src/kit/judging.ts +10 -0
- package/src/kit/memory.ts +3 -0
- package/src/kit/mirror.ts +19 -0
- package/src/kit/presentation.ts +7 -0
- package/src/kit/shell.ts +7 -0
- package/src/kit/skills.ts +8 -0
- package/src/kit/support.ts +21 -0
- package/src/kit/threads.ts +7 -0
- package/src/kit/tools.ts +14 -0
- package/src/kit/worker.ts +16 -0
- package/src/testing.ts +394 -34
- package/examples/guide.test.ts +0 -52
- package/src/cli/add-plugin.test.ts +0 -107
- package/src/cli/checks/basic.test.ts +0 -276
- package/src/cli/checks/database.test.ts +0 -117
- package/src/cli/checks/discord.test.ts +0 -200
- package/src/cli/cli.test.ts +0 -122
- package/src/cli/config-edit.test.ts +0 -130
- package/src/cli/doctor.test.ts +0 -184
- package/src/cli/init.test.ts +0 -127
- package/src/cli/size.test.ts +0 -9
- package/src/cli/templates.test.ts +0 -129
- package/src/cli/testing/fixtures.ts +0 -106
- package/src/core/agents/agent-claim.test.ts +0 -142
- package/src/core/agents/agent-dashboard.test.ts +0 -120
- package/src/core/agents/agent-guild.test.ts +0 -124
- package/src/core/agents/agent-store.test.ts +0 -205
- package/src/core/agents/avatar-studio.test.ts +0 -88
- package/src/core/agents/group-round.test.ts +0 -143
- package/src/core/agents/owner-identity.test.ts +0 -172
- package/src/core/agents/team-turns.test.ts +0 -278
- package/src/core/attachments/attachments.test.ts +0 -85
- package/src/core/boundary.test.ts +0 -45
- package/src/core/builtin/modules.test.ts +0 -127
- package/src/core/config/config.test.ts +0 -135
- package/src/core/contract/discord.ts +0 -33
- package/src/core/db/migrations.test.ts +0 -237
- package/src/core/define-roundtable.test.ts +0 -134
- package/src/core/define.test.ts +0 -144
- package/src/core/discord/agent-commands.test.ts +0 -58
- package/src/core/discord/agent-discord.test.ts +0 -70
- package/src/core/discord/dispatch-thread-host.test.ts +0 -114
- package/src/core/discord/dispatch-threads.test.ts +0 -94
- package/src/core/discord/owner-cards.test.ts +0 -435
- package/src/core/discord/owner-discord.test.ts +0 -325
- package/src/core/domain/expression.ts +0 -21
- package/src/core/domain/profile.ts +0 -32
- package/src/core/drain.test.ts +0 -46
- package/src/core/events.test.ts +0 -81
- package/src/core/holds.test.ts +0 -54
- package/src/core/host.test.ts +0 -536
- package/src/core/http/listeners.test.ts +0 -164
- package/src/core/i18n/i18n.test.ts +0 -139
- package/src/core/identity.test.ts +0 -18
- package/src/core/judging/effort-judge.test.ts +0 -112
- package/src/core/judging/model-judge.test.ts +0 -126
- package/src/core/modules/delegation/delegator.test.ts +0 -170
- package/src/core/modules/memory/owner-memory-store.test.ts +0 -244
- package/src/core/modules/schedules/schedule.test.ts +0 -358
- package/src/core/modules/skills/skill-kind.test.ts +0 -55
- package/src/core/modules/skills/skill-registry.test.ts +0 -376
- package/src/core/ops/error-reporter.test.ts +0 -283
- package/src/core/presentation/card-cadence.ts +0 -41
- package/src/core/presentation/presentation.test.ts +0 -166
- package/src/core/public-entry.test.ts +0 -59
- package/src/core/registry/contributions.test.ts +0 -215
- package/src/core/registry/interactions.test.ts +0 -87
- package/src/core/registry/providers.test.ts +0 -103
- package/src/core/routing/channel-queue.test.ts +0 -31
- package/src/core/routing/channel-router.test.ts +0 -326
- package/src/core/routing/conversation-kind.ts +0 -14
- package/src/core/routing/settle-turn.test.ts +0 -21
- package/src/core/runtime/compaction-tiers.test.ts +0 -227
- package/src/core/runtime/extensions/ask-user.test.ts +0 -114
- package/src/core/runtime/extensions/self-compact-guard.test.ts +0 -50
- package/src/core/runtime/pending-confirmation-store.test.ts +0 -52
- package/src/core/runtime/session-archive.test.ts +0 -20
- package/src/core/runtime/steerable-run.test.ts +0 -264
- package/src/core/runtime/text-tools.test.ts +0 -110
- package/src/core/runtime/turn-answer.test.ts +0 -72
- package/src/core/runtime/worker-task.test.ts +0 -82
- package/src/core/services.test.ts +0 -28
- package/src/core/sessions.test.ts +0 -85
- package/src/core/shared/unix-server.ts +0 -18
- package/src/core/size.test.ts +0 -9
- package/src/core/speakers.test.ts +0 -78
- package/src/core/testing/file-size.ts +0 -34
- package/src/core/time.test.ts +0 -166
- package/src/core/tool-tiers.test.ts +0 -117
- package/src/entries.test.ts +0 -112
- package/src/testing.test.ts +0 -156
|
@@ -2,7 +2,10 @@ import { ScheduleError } from "../../domain/errors.ts";
|
|
|
2
2
|
import { messages } from "../../i18n/index.ts";
|
|
3
3
|
import { timeZone, zonedDate, zonedInstant, zonedStamp } from "../../time.ts";
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export type Weekday = "sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat";
|
|
6
|
+
|
|
7
|
+
/** In the order of `Date#getUTCDay`. */
|
|
8
|
+
const WEEKDAYS: readonly Weekday[] = [
|
|
6
9
|
"sun",
|
|
7
10
|
"mon",
|
|
8
11
|
"tue",
|
|
@@ -10,8 +13,7 @@ export const WEEKDAYS = [
|
|
|
10
13
|
"thu",
|
|
11
14
|
"fri",
|
|
12
15
|
"sat",
|
|
13
|
-
]
|
|
14
|
-
export type Weekday = (typeof WEEKDAYS)[number];
|
|
16
|
+
];
|
|
15
17
|
|
|
16
18
|
/** When a schedule runs, in the configured wall-clock time. */
|
|
17
19
|
export type Recurrence =
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { SQL } from "bun";
|
|
2
2
|
import type { Migration } from "../../db/migrations.ts";
|
|
3
3
|
import type { ChannelKey } from "../../domain/conversation.ts";
|
|
4
|
+
import type { ScheduleStore } from "../../services.ts";
|
|
4
5
|
import type { Tier } from "../../speakers.ts";
|
|
5
6
|
import type { Recurrence } from "./recurrence.ts";
|
|
6
7
|
|
|
7
|
-
/** Owner schedules run the owner agent; party schedules run the channel's party role. */
|
|
8
|
-
export type ScheduleMode = "owner" | "party";
|
|
9
|
-
|
|
10
8
|
export interface Schedule {
|
|
11
9
|
id: number;
|
|
12
10
|
channel: ChannelKey;
|
|
13
|
-
mode
|
|
11
|
+
/** The name of the background target whose conversation runs it; stored in the `mode` column. */
|
|
12
|
+
target: string;
|
|
14
13
|
title: string;
|
|
15
14
|
prompt: string;
|
|
16
15
|
recurrence: Recurrence;
|
|
@@ -26,7 +25,7 @@ export interface Schedule {
|
|
|
26
25
|
|
|
27
26
|
export interface NewSchedule {
|
|
28
27
|
channel: ChannelKey;
|
|
29
|
-
|
|
28
|
+
target: string;
|
|
30
29
|
title: string;
|
|
31
30
|
prompt: string;
|
|
32
31
|
recurrence: Recurrence;
|
|
@@ -46,7 +45,8 @@ export interface ScheduleChange {
|
|
|
46
45
|
interface Row {
|
|
47
46
|
id: string | number;
|
|
48
47
|
channel_key: ChannelKey;
|
|
49
|
-
|
|
48
|
+
/** The target's name; the column keeps the name it had before targets existed. */
|
|
49
|
+
mode: string;
|
|
50
50
|
title: string;
|
|
51
51
|
prompt: string;
|
|
52
52
|
recurrence: string;
|
|
@@ -63,7 +63,7 @@ function toSchedule(row: Row): Schedule {
|
|
|
63
63
|
return {
|
|
64
64
|
id: Number(row.id),
|
|
65
65
|
channel: row.channel_key,
|
|
66
|
-
|
|
66
|
+
target: row.mode,
|
|
67
67
|
title: row.title,
|
|
68
68
|
prompt: row.prompt,
|
|
69
69
|
// pi-lens-ignore: unchecked-throwing-call — this store wrote the JSON; a corrupt row should fail loudly
|
|
@@ -79,7 +79,7 @@ function toSchedule(row: Row): Schedule {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/** Scheduled turns, in the database. A one-time schedule's row is deleted once it fires. */
|
|
82
|
-
export class ScheduleStore {
|
|
82
|
+
export class PgScheduleStore implements ScheduleStore {
|
|
83
83
|
readonly #sql: SQL;
|
|
84
84
|
|
|
85
85
|
private constructor(sql: SQL) {
|
|
@@ -113,15 +113,15 @@ export class ScheduleStore {
|
|
|
113
113
|
};
|
|
114
114
|
|
|
115
115
|
/** The store over the host's migrated pool. */
|
|
116
|
-
static async attach(sql: SQL): Promise<
|
|
117
|
-
return new
|
|
116
|
+
static async attach(sql: SQL): Promise<PgScheduleStore> {
|
|
117
|
+
return new PgScheduleStore(sql);
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
async create(schedule: NewSchedule): Promise<Schedule> {
|
|
121
121
|
const rows: Row[] = await this.#sql`
|
|
122
122
|
INSERT INTO schedules (channel_key, mode, title, prompt, recurrence, next_run,
|
|
123
123
|
created_by_id, created_by_name, created_tier)
|
|
124
|
-
VALUES (${schedule.channel}, ${schedule.
|
|
124
|
+
VALUES (${schedule.channel}, ${schedule.target}, ${schedule.title}, ${schedule.prompt},
|
|
125
125
|
${JSON.stringify(schedule.recurrence)}, ${schedule.nextRun},
|
|
126
126
|
${schedule.createdById}, ${schedule.createdByName}, ${schedule.createdTier})
|
|
127
127
|
RETURNING *`;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { BackgroundTarget } from "../../contract/channels.ts";
|
|
1
2
|
import type { ChannelKey } from "../../domain/conversation.ts";
|
|
2
3
|
import { ScheduleError } from "../../domain/errors.ts";
|
|
3
4
|
import { messages } from "../../i18n/index.ts";
|
|
5
|
+
import type { ScheduleStore } from "../../services.ts";
|
|
4
6
|
import type { ScheduleToolName } from "../../shared/schedule-tools.ts";
|
|
5
7
|
import { type Tier, tierAtLeast } from "../../speakers.ts";
|
|
6
8
|
import { timeZone, zonedStamp } from "../../time.ts";
|
|
@@ -11,22 +13,8 @@ import {
|
|
|
11
13
|
type Recurrence,
|
|
12
14
|
type RecurrenceInput,
|
|
13
15
|
} from "./recurrence.ts";
|
|
14
|
-
import type {
|
|
15
|
-
Schedule,
|
|
16
|
-
ScheduleMode,
|
|
17
|
-
ScheduleStore,
|
|
18
|
-
} from "./schedule-store.ts";
|
|
16
|
+
import type { Schedule } from "./schedule-store.ts";
|
|
19
17
|
|
|
20
|
-
/** Party channels are open to anyone, so their roles get tighter limits than the owner's agent. */
|
|
21
|
-
export const SCHEDULE_LIMITS: Readonly<
|
|
22
|
-
Record<
|
|
23
|
-
ScheduleMode,
|
|
24
|
-
{ perChannel: number; promptChars: number; aheadDays: number }
|
|
25
|
-
>
|
|
26
|
-
> = {
|
|
27
|
-
owner: { perChannel: 20, promptChars: 8_000, aheadDays: 366 },
|
|
28
|
-
party: { perChannel: 5, promptChars: 2_000, aheadDays: 90 },
|
|
29
|
-
};
|
|
30
18
|
const TITLE_CHARS = 80;
|
|
31
19
|
const LIST_PROMPT_PREVIEW = 200;
|
|
32
20
|
const DAY_MS = 86_400_000;
|
|
@@ -37,12 +25,25 @@ export interface ScheduleToolContext {
|
|
|
37
25
|
"create" | "get" | "forChannel" | "update" | "remove"
|
|
38
26
|
>;
|
|
39
27
|
channel: ChannelKey;
|
|
40
|
-
|
|
28
|
+
/** Whose schedules these are; its `schedules` limits apply, and without them nothing is scheduled. */
|
|
29
|
+
target: BackgroundTarget;
|
|
41
30
|
/** Who asked, recorded on created schedules; a scheduled run speaks for its creator. */
|
|
42
31
|
author: { id: string; name: string; tier?: Tier };
|
|
43
32
|
now: Date;
|
|
44
33
|
}
|
|
45
34
|
|
|
35
|
+
/** The limits of the context's target; a target without them may not schedule. */
|
|
36
|
+
function limitsOf(
|
|
37
|
+
ctx: ScheduleToolContext,
|
|
38
|
+
): NonNullable<BackgroundTarget["schedules"]> {
|
|
39
|
+
const { schedules } = ctx.target;
|
|
40
|
+
if (!schedules)
|
|
41
|
+
throw new ScheduleError(
|
|
42
|
+
`schedules are not available for ${ctx.target.name} conversations`,
|
|
43
|
+
);
|
|
44
|
+
return schedules;
|
|
45
|
+
}
|
|
46
|
+
|
|
46
47
|
type Input = Record<string, unknown> & RecurrenceInput;
|
|
47
48
|
|
|
48
49
|
function text(input: Input, name: string, max: number): string {
|
|
@@ -82,7 +83,7 @@ function timing(ctx: ScheduleToolContext, input: Input): [Recurrence, Date] {
|
|
|
82
83
|
throw new ScheduleError(
|
|
83
84
|
`that time has already passed; it is ${zonedStamp(ctx.now)} in ${messages().zoneName(timeZone())} now`,
|
|
84
85
|
);
|
|
85
|
-
const { aheadDays } =
|
|
86
|
+
const { aheadDays } = limitsOf(ctx);
|
|
86
87
|
if (next.getTime() - ctx.now.getTime() > aheadDays * DAY_MS)
|
|
87
88
|
throw new ScheduleError(`the first run must be within ${aheadDays} days`);
|
|
88
89
|
return [recurrence, next];
|
|
@@ -121,9 +122,10 @@ function changeable(ctx: ScheduleToolContext, schedule: Schedule): Schedule {
|
|
|
121
122
|
export async function callScheduleTool(
|
|
122
123
|
ctx: ScheduleToolContext,
|
|
123
124
|
name: ScheduleToolName,
|
|
124
|
-
|
|
125
|
+
rawInput: Record<string, unknown>,
|
|
125
126
|
): Promise<string> {
|
|
126
|
-
const
|
|
127
|
+
const input = rawInput as Input;
|
|
128
|
+
const limits = limitsOf(ctx);
|
|
127
129
|
switch (name) {
|
|
128
130
|
case "schedule_create": {
|
|
129
131
|
const title = text(input, "title", TITLE_CHARS);
|
|
@@ -136,7 +138,7 @@ export async function callScheduleTool(
|
|
|
136
138
|
);
|
|
137
139
|
const created = await ctx.store.create({
|
|
138
140
|
channel: ctx.channel,
|
|
139
|
-
|
|
141
|
+
target: ctx.target.name,
|
|
140
142
|
title,
|
|
141
143
|
prompt,
|
|
142
144
|
recurrence,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ScheduledOutcome } from "../../contract/channels.ts";
|
|
2
2
|
import type { Logger } from "../../log.ts";
|
|
3
|
+
import type { ScheduleStore } from "../../services.ts";
|
|
3
4
|
import { nextRun } from "./recurrence.ts";
|
|
4
|
-
import type { Schedule
|
|
5
|
+
import type { Schedule } from "./schedule-store.ts";
|
|
5
6
|
|
|
6
7
|
export type { ScheduledOutcome };
|
|
7
8
|
|
|
@@ -104,7 +105,11 @@ export class Scheduler {
|
|
|
104
105
|
async #fire(schedule: Schedule, firedAt: Date): Promise<void> {
|
|
105
106
|
const { store, runner, logger } = this.#options;
|
|
106
107
|
logger.info(
|
|
107
|
-
{
|
|
108
|
+
{
|
|
109
|
+
schedule: schedule.id,
|
|
110
|
+
channel: schedule.channel,
|
|
111
|
+
target: schedule.target,
|
|
112
|
+
},
|
|
108
113
|
"schedule firing",
|
|
109
114
|
);
|
|
110
115
|
const outcome = await runner.runScheduled(schedule, firedAt);
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
|
+
import { OWNER_TARGET } from "../../agents/agent-claim.ts";
|
|
3
4
|
import type { ChannelKey } from "../../domain/conversation.ts";
|
|
4
5
|
import { ScheduleError } from "../../domain/errors.ts";
|
|
6
|
+
import { activeLocale } from "../../i18n/index.ts";
|
|
5
7
|
import type { OwnerIdentity } from "../../identity.ts";
|
|
6
8
|
import {
|
|
7
9
|
type ToolInput,
|
|
8
10
|
textToolsExtension,
|
|
9
11
|
} from "../../runtime/text-tools.ts";
|
|
12
|
+
import type { ScheduleStore } from "../../services.ts";
|
|
10
13
|
import {
|
|
11
14
|
type ScheduleToolSpec,
|
|
12
15
|
scheduleToolSpecs,
|
|
13
16
|
} from "../../shared/schedule-tools.ts";
|
|
14
17
|
import type { Speaker } from "../../speakers.ts";
|
|
15
|
-
import
|
|
18
|
+
import { timeZone } from "../../time.ts";
|
|
16
19
|
import { callScheduleTool } from "./schedule-tools.ts";
|
|
17
20
|
|
|
18
21
|
export interface OwnerSchedules {
|
|
@@ -56,7 +59,10 @@ export function schedulesExtension(
|
|
|
56
59
|
speaker: () => Speaker | undefined = () => undefined,
|
|
57
60
|
): ExtensionFactory {
|
|
58
61
|
const { store, owner, channelFor } = schedules;
|
|
59
|
-
const defs = scheduleToolSpecs(
|
|
62
|
+
const defs = scheduleToolSpecs({
|
|
63
|
+
locale: activeLocale(),
|
|
64
|
+
timeZone: timeZone(),
|
|
65
|
+
}).map((base) => {
|
|
60
66
|
const spec = agents ? withAgentOption(base) : base;
|
|
61
67
|
return {
|
|
62
68
|
...spec,
|
|
@@ -70,7 +76,7 @@ export function schedulesExtension(
|
|
|
70
76
|
{
|
|
71
77
|
store,
|
|
72
78
|
channel: target,
|
|
73
|
-
|
|
79
|
+
target: OWNER_TARGET,
|
|
74
80
|
author: speaker() ?? owner,
|
|
75
81
|
now: new Date(),
|
|
76
82
|
},
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mkdirSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { AgentError } from "../../domain/errors.ts";
|
|
4
|
+
import type { SkillRegistry } from "../../services.ts";
|
|
4
5
|
import { planLinkedSkills } from "./skill-link.ts";
|
|
5
6
|
import { skillCatalog, skillListText } from "./skill-listing.ts";
|
|
6
7
|
import {
|
|
@@ -28,8 +29,8 @@ export {
|
|
|
28
29
|
type SkillSource,
|
|
29
30
|
} from "./skill-rules.ts";
|
|
30
31
|
|
|
31
|
-
/** The skill registry and what each agent carries
|
|
32
|
-
export class SkillRegistry {
|
|
32
|
+
/** The skill registry and what each agent carries. */
|
|
33
|
+
export class StoredSkillRegistry implements SkillRegistry {
|
|
33
34
|
readonly #options: SkillRegistryOptions;
|
|
34
35
|
|
|
35
36
|
constructor(options: SkillRegistryOptions) {
|
|
@@ -4,7 +4,7 @@ import type { Migration } from "../../db/migrations.ts";
|
|
|
4
4
|
import { AgentError } from "../../domain/errors.ts";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* A registered skill
|
|
7
|
+
* A registered skill. A linked skill's name and description
|
|
8
8
|
* live in its repository's file; an agent-written one keeps them here.
|
|
9
9
|
*/
|
|
10
10
|
export type SkillEntry =
|
|
@@ -17,7 +17,7 @@ export interface SkillGroup {
|
|
|
17
17
|
skills: string[];
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/** Who lost a removed skill
|
|
20
|
+
/** Who lost a removed skill. */
|
|
21
21
|
export interface Detached {
|
|
22
22
|
agents: string[];
|
|
23
23
|
groups: string[];
|
|
@@ -59,12 +59,6 @@ const toGroup = (row: GroupRow): SkillGroup => ({
|
|
|
59
59
|
skills: row.skills.split(",").filter(Boolean),
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
-
/**
|
|
63
|
-
* The kind an agent-written skill was stored under before it became 'written': the first
|
|
64
|
-
* consumer's own name, spelled from parts so the public tree names no consumer.
|
|
65
|
-
*/
|
|
66
|
-
export const LEGACY_WRITTEN_KIND = ["mer", "lin"].join("");
|
|
67
|
-
|
|
68
62
|
/**
|
|
69
63
|
* Skills, skill groups, and the skills each agent carries, in the database. All of it is
|
|
70
64
|
* also held in memory, because every agent turn resolves its skills and only this process
|
|
@@ -128,13 +122,6 @@ export class SkillStore {
|
|
|
128
122
|
{ table: "agent_skills", key: ["agent", "skill"] },
|
|
129
123
|
]),
|
|
130
124
|
},
|
|
131
|
-
{
|
|
132
|
-
// Skills an agent wrote were stored under the legacy kind; the kind is now 'written'.
|
|
133
|
-
name: "skills-written-kind",
|
|
134
|
-
up: async (sql) => {
|
|
135
|
-
await sql`UPDATE skills SET kind = 'written' WHERE kind = ${LEGACY_WRITTEN_KIND}`;
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
125
|
];
|
|
139
126
|
}
|
|
140
127
|
|
|
@@ -7,7 +7,11 @@ import {
|
|
|
7
7
|
stringList,
|
|
8
8
|
textToolsExtension,
|
|
9
9
|
} from "../../runtime/text-tools.ts";
|
|
10
|
-
import {
|
|
10
|
+
import type { SkillRegistry } from "../../services.ts";
|
|
11
|
+
import {
|
|
12
|
+
MAX_SKILL_BODY_CHARS,
|
|
13
|
+
type StoredSkillRegistry,
|
|
14
|
+
} from "./skill-registry.ts";
|
|
11
15
|
|
|
12
16
|
export const SKILL_LIST_TOOL = "skill_list";
|
|
13
17
|
|
|
@@ -43,7 +47,9 @@ const BODY = Type.String({
|
|
|
43
47
|
});
|
|
44
48
|
|
|
45
49
|
/** skill_list, for the DM and for agents. */
|
|
46
|
-
export function skillListExtension(
|
|
50
|
+
export function skillListExtension(
|
|
51
|
+
registry: Pick<SkillRegistry, "list">,
|
|
52
|
+
): ExtensionFactory {
|
|
47
53
|
return textToolsExtension(
|
|
48
54
|
[
|
|
49
55
|
{
|
|
@@ -75,9 +81,9 @@ export function skillListExtension(registry: SkillRegistry): ExtensionFactory {
|
|
|
75
81
|
);
|
|
76
82
|
}
|
|
77
83
|
|
|
78
|
-
/** The skill tools of an agent session
|
|
84
|
+
/** The skill tools of an agent session. */
|
|
79
85
|
export function skillToolsExtension(
|
|
80
|
-
registry:
|
|
86
|
+
registry: StoredSkillRegistry,
|
|
81
87
|
/** Throws AgentError unless the name is an active agent. */
|
|
82
88
|
checkAgent: (name: string) => void,
|
|
83
89
|
): ExtensionFactory {
|
|
@@ -16,7 +16,7 @@ const FIELD_LIMIT = 200;
|
|
|
16
16
|
const STACK_FRAMES = 8;
|
|
17
17
|
/** pino's own keys, and the ones the report shows apart from the context. */
|
|
18
18
|
const OWN_KEYS = new Set(["level", "time", "pid", "hostname", "msg", "err"]);
|
|
19
|
-
const HEAD_KEYS = ["app", "module"];
|
|
19
|
+
const HEAD_KEYS = ["app", "plugin", "module"];
|
|
20
20
|
const APP_FRAME = /((?:src|shared|worker)\/[^\s():]+\.ts):(\d+)/;
|
|
21
21
|
|
|
22
22
|
/** Where the reports go, known once the Discord surface and the agent team are up. */
|