pi-roundtable 0.23.2 → 0.24.1

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.
@@ -91,8 +91,13 @@ export const MODES: ServiceKey<ConversationModes> =
91
91
  export const THREADS: ServiceKey<DispatchThreads> =
92
92
  serviceKey<DispatchThreads>("roundtable.threads");
93
93
  /** The agent server: its team, its directory, the runtime that runs every agent turn. Provided by the agent-server plugin. */
94
- export const AGENTS: ServiceKey<AgentServer> =
95
- serviceKey<AgentServer>("roundtable.agents");
94
+ export const AGENTS: ServiceKey<AgentServer> = serviceKey<AgentServer>(
95
+ "roundtable.agents",
96
+ {
97
+ absent:
98
+ "This host has no agent server: its configuration says agentServer: false, or it has neither discord nor agents. Remove agentServer: false and configure discord or agents, or drop the plugin that needs the agent server.",
99
+ },
100
+ );
96
101
  /** Scheduled turns, stored. Provided by the `schedule-store` plugin. */
97
102
  export const SCHEDULES: ServiceKey<ScheduleStore> = serviceKey<ScheduleStore>(
98
103
  "roundtable.schedules",
@@ -153,6 +158,20 @@ export interface AgentServer {
153
158
  };
154
159
  /** Agents' pictures. */
155
160
  avatars: AvatarStudio;
161
+ /** Where the agents' files are: the directories their shell and file tools run in. */
162
+ workspace: AgentWorkspace;
163
+ }
164
+
165
+ /**
166
+ * The directories the agents work in, as configured. Every agent shares them: the core has no
167
+ * workspace per agent. Read-only data, so a plugin that shows or serves the files can find them;
168
+ * the directories may not exist yet.
169
+ */
170
+ export interface AgentWorkspace {
171
+ /** The shell's shared working directory (`config.workDir`), where agents write without a hold. */
172
+ readonly workDir: string;
173
+ /** The agents' scratch dir (TMPDIR), when the host sets one; writes there are unheld too. */
174
+ readonly scratchDir?: string;
156
175
  }
157
176
 
158
177
  /** Agent pictures: rendered from the agent's character, kept and served by content hash. */
@@ -1,5 +1,5 @@
1
1
  import { readFile, realpath, stat } from "node:fs/promises";
2
- import { basename, isAbsolute, relative, resolve } from "node:path";
2
+ import { basename, isAbsolute, relative, resolve, sep } from "node:path";
3
3
 
4
4
  /** Where a session may read files by path: its shared workspace and its scratch dir. */
5
5
  export interface WorkspaceRoots {
@@ -23,10 +23,13 @@ export interface WorkspaceFile {
23
23
  size: number;
24
24
  }
25
25
 
26
- /** Whether `child` is `parent` or inside it. */
27
- function within(parent: string, child: string): boolean {
26
+ /** Whether `child` is `parent` or inside it, judged by the paths alone (resolve symlinks first). */
27
+ export function within(parent: string, child: string): boolean {
28
28
  const rel = relative(parent, child);
29
- return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
29
+ return (
30
+ rel === "" ||
31
+ (rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute(rel))
32
+ );
30
33
  }
31
34
 
32
35
  async function realRoot(root: string): Promise<string | undefined> {
package/src/index.ts CHANGED
@@ -333,6 +333,7 @@ export type {
333
333
  AgentDirectory,
334
334
  AgentServer,
335
335
  AgentTeam,
336
+ AgentWorkspace,
336
337
  AvatarStudio,
337
338
  BackgroundTurns,
338
339
  DelegationRequest,
package/src/kit/index.ts CHANGED
@@ -206,3 +206,4 @@ export {
206
206
  runWorkerTask,
207
207
  workTimeout,
208
208
  } from "./worker.ts";
209
+ export { within } from "./workspace.ts";
@@ -0,0 +1,3 @@
1
+ // Path helper for plugins that serve files from the agents' workspace; see the plugin guide.
2
+
3
+ export { within } from "../core/shared/workspace-files.ts";
package/src/testing.ts CHANGED
@@ -2,6 +2,7 @@ import { mkdtempSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import type { SQL } from "bun";
5
+ import { CATALOG } from "./characters/index.ts";
5
6
  import { agentClaim } from "./core/agents/agent-claim.ts";
6
7
  import { ownerAttachmentDir } from "./core/attachments/attachment-dir.ts";
7
8
  import { attachmentPort } from "./core/attachments/attachment-port.ts";
@@ -453,6 +454,7 @@ export async function testPlugin(
453
454
  locale: "en",
454
455
  timeZone: "UTC",
455
456
  now: () => new Date(),
457
+ characterSkins: CATALOG.skins,
456
458
  ...options.env,
457
459
  };
458
460
  // What the agent server does with the slot: the provider's runtime serves `context.turns`.