@agimon-ai/po-team 0.0.0-alpha.35 → 0.0.0-alpha.36

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.
@@ -6067,6 +6067,85 @@ function createTeamNamespace(options) {
6067
6067
  }
6068
6068
  };
6069
6069
  }
6070
+ /** Names come from people and other sessions: keep each on one line so the note stays well formed. */
6071
+ const clean = (text) => text.replace(/\s+/g, " ").trim();
6072
+ const sortedNames = (names) => [...new Set(names.map(clean).filter(Boolean))].toSorted();
6073
+ /**
6074
+ * Stable facts only, sorted, so equal rosters render byte-identical and a change check
6075
+ * appends nothing when nothing moved. Live status stays out: it would change every turn.
6076
+ */
6077
+ function formatTeamRoster({ groups, peers, members }) {
6078
+ const lines = [];
6079
+ const own = sortedNames(groups);
6080
+ if (own.length) lines.push(`Your session groups: ${own.join(", ")}.`);
6081
+ const peerLines = peers.map((peer) => {
6082
+ const shared = sortedNames(peer.sharedGroups);
6083
+ const details = [
6084
+ `session ${peer.sessionId}`,
6085
+ ...peer.profile === void 0 ? [] : [`profile ${clean(peer.profile)}`],
6086
+ ...shared.length ? [`shared groups: ${shared.join(", ")}`] : []
6087
+ ];
6088
+ return `- ${clean(peer.name) || peer.sessionId} (${details.join("; ")})`;
6089
+ }).toSorted();
6090
+ if (peerLines.length) lines.push("Sessions you can message with intercom send, by name or session id:", ...peerLines);
6091
+ const subagentLines = members.filter((member) => member.role !== "main").map((member) => {
6092
+ const details = [member.agent ? `agent ${clean(member.agent)}` : void 0, member.task ? `task: ${clean(member.task.subject)}` : void 0].filter((value) => Boolean(value));
6093
+ return `- ${clean(member.name)}${details.length ? ` (${details.join("; ")})` : ""}`;
6094
+ }).toSorted();
6095
+ if (subagentLines.length) lines.push("Active subagents you can message with intercom:", ...subagentLines);
6096
+ return lines.join("\n");
6097
+ }
6098
+ function teamRosterNote(roster) {
6099
+ return [
6100
+ "<system-reminder>",
6101
+ roster || "You are in no session group and have no peer sessions or active subagents now.",
6102
+ "This replaces any earlier roster note. Use intercom members for live status.",
6103
+ "</system-reminder>"
6104
+ ].join("\n");
6105
+ }
6106
+ /**
6107
+ * Delivers the roster as a history note only when it changed. Never touches the system prompt or the
6108
+ * request tail, so the provider prompt cache keeps every earlier byte. Writes at the next tool step,
6109
+ * or right away when the session is idle; a busy idle write returns undefined and the next boundary retries.
6110
+ */
6111
+ function createTeamRosterDelivery(read) {
6112
+ let delivered = "";
6113
+ let boundary;
6114
+ let tail = Promise.resolve();
6115
+ const deliver = (append) => {
6116
+ tail = tail.then(async () => {
6117
+ const roster = read();
6118
+ if (roster === delivered) return;
6119
+ if (await append({
6120
+ type: "po-team-roster",
6121
+ text: teamRosterNote(roster),
6122
+ display: false
6123
+ }) !== void 0) delivered = roster;
6124
+ }).catch(() => void 0);
6125
+ return tail;
6126
+ };
6127
+ return {
6128
+ attach(session) {
6129
+ if (boundary || !session.registerCheckpointBoundary) return;
6130
+ boundary = session.registerCheckpointBoundary(async (step) => {
6131
+ if (!step.signal?.aborted) await deliver((message) => step.appendMessage(message));
6132
+ });
6133
+ },
6134
+ /** Try an idle write now. */
6135
+ sync() {
6136
+ const current = boundary;
6137
+ return current ? deliver((message) => current.appendMessage(message)) : Promise.resolve();
6138
+ },
6139
+ /** Compaction or navigation dropped the earlier note from context: send the roster again. */
6140
+ reset() {
6141
+ delivered = "";
6142
+ },
6143
+ dispose() {
6144
+ boundary?.dispose();
6145
+ boundary = void 0;
6146
+ }
6147
+ };
6148
+ }
6070
6149
  //#endregion
6071
6150
  //#region src/services/managementActions/index.ts
6072
6151
  /**
@@ -6824,8 +6903,6 @@ const root = (0, _agimon_ai_po_core_extensionFile.defineRoot)(({ context, host:
6824
6903
  return host.context.selection;
6825
6904
  }
6826
6905
  };
6827
- const sessionPeers = /* @__PURE__ */ new Set();
6828
- const stopPeerDiscovery = serverHost.context.sessionCommunication?.onPeerReady((id) => sessionPeers.add(id));
6829
6906
  const telemetry = (0, _agimon_ai_po_core_telemetry.createPoTelemetry)({
6830
6907
  serviceName: "po-team",
6831
6908
  packageName: "@agimon-ai/po-team",
@@ -6949,13 +7026,17 @@ const root = (0, _agimon_ai_po_core_extensionFile.defineRoot)(({ context, host:
6949
7026
  deliveries = delivery.catch(() => void 0);
6950
7027
  return delivery;
6951
7028
  } });
7029
+ const listPeers = () => serverHost.context.sessionCommunication?.listPeers?.() ?? [];
7030
+ const roster = createTeamRosterDelivery(() => formatTeamRoster({
7031
+ groups: serverHost.context.sessionCommunication?.groups ?? [],
7032
+ peers: listPeers(),
7033
+ members: require_teamSnapshot.readActiveTeamSnapshot(channel)?.members ?? []
7034
+ }));
7035
+ const stopPeerDiscovery = serverHost.context.sessionCommunication?.onPeerReady(() => void roster.sync());
6952
7036
  const intercom = createHeadlessIntercomTool(channel, {
6953
7037
  sessionId: execution.sessionId,
6954
7038
  name: () => serverHost.context.sessionCommunication?.sessionName,
6955
- peers: () => [...sessionPeers].filter((id) => serverHost.context.sessionService?.canCommunicate?.(execution.sessionId, id) === true).flatMap((id) => {
6956
- const peer = serverHost.context.sessionCommunication?.describePeer?.(id);
6957
- return peer === void 0 ? [] : [peer];
6958
- }),
7039
+ peers: listPeers,
6959
7040
  canCommunicate: (id) => serverHost.context.sessionService?.canCommunicate?.(execution.sessionId, id) === true,
6960
7041
  delivery: () => (0, _agimon_ai_po_session.readPoSessionDelivery)(context)
6961
7042
  });
@@ -7119,7 +7200,8 @@ const root = (0, _agimon_ai_po_core_extensionFile.defineRoot)(({ context, host:
7119
7200
  intercom,
7120
7201
  directEvents,
7121
7202
  environment: serverHost.context.environment,
7122
- restoreRuns
7203
+ restoreRuns,
7204
+ roster
7123
7205
  },
7124
7206
  services: [
7125
7207
  (context) => {
@@ -7133,6 +7215,8 @@ const root = (0, _agimon_ai_po_core_extensionFile.defineRoot)(({ context, host:
7133
7215
  activities: [activity],
7134
7216
  async onStart() {
7135
7217
  runtime.pollScheduler.start();
7218
+ roster.attach(execution.session);
7219
+ roster.sync();
7136
7220
  telemetry.recordEvent("po_team.session_started", { "team.root_session": (0, _agimon_ai_po_core_childProcess.resolveRootSessionId)(execution.sessionId, environment) === execution.sessionId });
7137
7221
  },
7138
7222
  async onDispose() {
@@ -7142,7 +7226,7 @@ const root = (0, _agimon_ai_po_core_extensionFile.defineRoot)(({ context, host:
7142
7226
  await (0, _agimon_ai_po_core_extensionFile.runCleanups)([
7143
7227
  () => awaitedInline.close(),
7144
7228
  () => stopPeerDiscovery?.(),
7145
- () => sessionPeers.clear(),
7229
+ () => roster.dispose(),
7146
7230
  () => execution.client.setStatus(TEAM_COST_STATUS, void 0),
7147
7231
  () => channel.dispose(),
7148
7232
  () => runtime.completionNotifier.dispose(),
@@ -7466,12 +7550,40 @@ var route_server_default$1 = (context) => createTeamSessionApi(context.root.runt
7466
7550
  //#region src/extensions/workspaces/sessions/(backend)/api/route.server.ts
7467
7551
  var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)(route_server_default$1);
7468
7552
  //#endregion
7553
+ //#region src/extensions/workspaces/sessions/(backend)/hook/agentSettled.server.ts
7554
+ /** A settled, idle session takes a changed roster now, so the next prompt already sees it. */
7555
+ var agentSettled_server_default = (0, _agimon_ai_po_core_extensionFile.defineHook)(({ root }) => ({
7556
+ event: "agent_settled",
7557
+ handle: () => root.roster.sync()
7558
+ }));
7559
+ //#endregion
7560
+ //#region src/extensions/workspaces/sessions/(backend)/hook/sessionCompact.server.ts
7561
+ /** Compaction summarised the earlier roster note away: send the roster again. */
7562
+ var sessionCompact_server_default = (0, _agimon_ai_po_core_extensionFile.defineHook)(({ root }) => ({
7563
+ event: "session_compact",
7564
+ handle: (event) => {
7565
+ if (event.status !== "completed") return;
7566
+ root.roster.reset();
7567
+ return root.roster.sync();
7568
+ }
7569
+ }));
7570
+ //#endregion
7469
7571
  //#region src/extensions/workspaces/sessions/(backend)/hook/sessionStart.server.ts
7470
7572
  var sessionStart_server_default = (0, _agimon_ai_po_core_extensionFile.defineHook)(({ root }) => ({
7471
7573
  event: "session_start",
7472
7574
  handle: () => root.restoreRuns()
7473
7575
  }));
7474
7576
  //#endregion
7577
+ //#region src/extensions/workspaces/sessions/(backend)/hook/sessionTree.server.ts
7578
+ /** Navigating to another branch may leave the roster note behind: send the roster again. */
7579
+ var sessionTree_server_default = (0, _agimon_ai_po_core_extensionFile.defineHook)(({ root }) => ({
7580
+ event: "session_tree",
7581
+ handle: () => {
7582
+ root.roster.reset();
7583
+ return root.roster.sync();
7584
+ }
7585
+ }));
7586
+ //#endregion
7475
7587
  //#region src/extensions/workspaces/sessions/(backend)/resource/codemode-how-to-team.server.ts
7476
7588
  var codemode_how_to_team_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)({
7477
7589
  name: "codemode-how-to-team",
@@ -7482,28 +7594,6 @@ var codemode_how_to_team_server_default = (0, _agimon_ai_po_core_extensionFile.d
7482
7594
  read: () => (0, _agimon_ai_po_core_serverPlugin.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/codemode-how-to-team/SKILL.md")
7483
7595
  });
7484
7596
  //#endregion
7485
- //#region src/extensions/workspaces/sessions/(backend)/resource/_lib/team.server.ts
7486
- /**
7487
- * The roster the model is allowed to see.
7488
- *
7489
- * Reads the public snapshot rather than `channel.current()`: the latter is the raw
7490
- * `TeamMemberContext`, whose `token` is a session capability documented as never
7491
- * leaving the direct context. A context resource is pasted into the system prompt,
7492
- * sent to the provider and persisted, so the raw struct must not be serialized here.
7493
- * `formatTeamContextSnapshot` is the same projection the Pi extension renders.
7494
- */
7495
- var team_server_default$1 = (context) => ({
7496
- name: "po/team",
7497
- kind: "context",
7498
- read: () => {
7499
- const rendered = require_teamSnapshot.formatTeamContextSnapshot(require_teamSnapshot.readActiveTeamSnapshot(context.root.channel));
7500
- return rendered === void 0 || rendered === "(no active team members)" ? "" : rendered;
7501
- }
7502
- });
7503
- //#endregion
7504
- //#region src/extensions/workspaces/sessions/(backend)/resource/team.server.ts
7505
- var team_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)(team_server_default$1);
7506
- //#endregion
7507
7597
  //#region src/extensions/workspaces/sessions/(backend)/tool/intercom.server.ts
7508
7598
  var intercom_server_default = (0, _agimon_ai_po_core_extensionFile.defineServerTool)((context) => context.root.intercom);
7509
7599
  //#endregion
@@ -7543,10 +7633,15 @@ const serverPlugin = (0, _agimon_ai_po_core_serverPlugin.defineServerPlugin)({
7543
7633
  return defined([context.hosted("global") ? void 0 : () => via({ frameType: "subagent_catalog" }, at(subagent_catalog_server_default, context)), context.hosted("global") ? void 0 : () => via({ frameType: "subagent_runs" }, at(subagent_runs_server_default, context))]);
7544
7634
  },
7545
7635
  get hooks() {
7546
- return [via({ event: "session_start" }, at(sessionStart_server_default, contextSession))];
7636
+ return [
7637
+ via({ event: "agent_settled" }, at(agentSettled_server_default, contextSession)),
7638
+ via({ event: "session_compact" }, at(sessionCompact_server_default, contextSession)),
7639
+ via({ event: "session_start" }, at(sessionStart_server_default, contextSession)),
7640
+ via({ event: "session_tree" }, at(sessionTree_server_default, contextSession))
7641
+ ];
7547
7642
  },
7548
7643
  get resources() {
7549
- return [at(codemode_how_to_team_server_default, contextSession), at(team_server_default, contextSession)];
7644
+ return [at(codemode_how_to_team_server_default, contextSession)];
7550
7645
  },
7551
7646
  get tools() {
7552
7647
  return [via({ name: "intercom" }, at(intercom_server_default, contextSession)), via({ name: "subagent" }, at(subagent_server_default, contextSession))];