refactor: remove register_group legacy surface
This commit is contained in:
@@ -495,7 +495,7 @@ server.tool(
|
||||
'assign_room',
|
||||
`Assign or update a room using room-level settings. Main group only.
|
||||
|
||||
This is the room-level replacement for legacy register_group. If folder is omitted, the host generates one automatically.`,
|
||||
If folder is omitted, the host generates one automatically.`,
|
||||
{
|
||||
jid: z.string().describe('The chat JID (e.g., "120363336345536173@g.us", "tg:-1001234567890", "dc:1234567890123456")'),
|
||||
name: z.string().describe('Display name for the room'),
|
||||
@@ -547,42 +547,6 @@ This is the room-level replacement for legacy register_group. If folder is omitt
|
||||
},
|
||||
);
|
||||
|
||||
server.tool(
|
||||
'register_group',
|
||||
`Register a new chat/group so the agent can respond to messages there. Main group only.
|
||||
|
||||
Use available_groups.json to find the JID for a group. The folder name must be channel-prefixed: "{channel}_{group-name}" (e.g., "whatsapp_family-chat", "telegram_dev-team", "discord_general"). Use lowercase with hyphens for the group name part.`,
|
||||
{
|
||||
jid: z.string().describe('The chat JID (e.g., "120363336345536173@g.us", "tg:-1001234567890", "dc:1234567890123456")'),
|
||||
name: z.string().describe('Display name for the group'),
|
||||
folder: z.string().describe('Channel-prefixed folder name (e.g., "whatsapp_family-chat", "telegram_dev-team")'),
|
||||
trigger: z.string().describe('Trigger word (e.g., "@Andy")'),
|
||||
},
|
||||
async (args: { jid: string; name: string; folder: string; trigger: string }) => {
|
||||
if (!isMain) {
|
||||
return {
|
||||
content: [{ type: 'text' as const, text: 'Only the main group can register new groups.' }],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
|
||||
const data = {
|
||||
type: 'register_group',
|
||||
jid: args.jid,
|
||||
name: args.name,
|
||||
folder: args.folder,
|
||||
trigger: args.trigger,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
writeIpcFile(TASKS_DIR, data);
|
||||
|
||||
return {
|
||||
content: [{ type: 'text' as const, text: `Group "${args.name}" registration requested.` }],
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
// Start the stdio transport
|
||||
const transport = new StdioServerTransport();
|
||||
await server.connect(transport);
|
||||
|
||||
@@ -965,7 +965,7 @@ describe('paired room registration', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('keeps room-level metadata synced on legacy register_group writes', () => {
|
||||
it('keeps room-level metadata synced on setRegisteredGroup helper writes', () => {
|
||||
setRegisteredGroup('dc:room-settings', {
|
||||
name: 'Room Settings Test',
|
||||
folder: 'room-settings-test',
|
||||
|
||||
41
src/index.ts
41
src/index.ts
@@ -216,46 +216,6 @@ function clearSession(
|
||||
}
|
||||
}
|
||||
|
||||
function registerGroup(jid: string, group: RegisteredGroup): void {
|
||||
const assignedGroup = assignRoom(jid, {
|
||||
name: group.name,
|
||||
ownerAgentType: group.agentType,
|
||||
folder: group.folder,
|
||||
trigger: group.trigger,
|
||||
requiresTrigger: group.requiresTrigger,
|
||||
isMain: group.isMain,
|
||||
workDir: group.workDir,
|
||||
addedAt: group.added_at,
|
||||
ownerAgentConfig: group.agentConfig,
|
||||
});
|
||||
if (!assignedGroup) {
|
||||
logger.warn({ jid }, 'Failed to assign room during legacy registration');
|
||||
return;
|
||||
}
|
||||
|
||||
let groupDir: string;
|
||||
try {
|
||||
groupDir = resolveGroupFolderPath(assignedGroup.folder);
|
||||
} catch (err) {
|
||||
logger.warn(
|
||||
{ jid, folder: assignedGroup.folder, err },
|
||||
'Rejecting group registration with invalid folder',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { jid: _ignoredJid, ...storedGroup } = assignedGroup;
|
||||
registeredGroups[jid] = storedGroup;
|
||||
|
||||
// Create group folder
|
||||
fs.mkdirSync(path.join(groupDir, 'logs'), { recursive: true });
|
||||
|
||||
logger.info(
|
||||
{ jid, name: assignedGroup.name, folder: assignedGroup.folder },
|
||||
'Group registered',
|
||||
);
|
||||
}
|
||||
|
||||
function assignRoomForIpc(jid: string, input: AssignRoomInput): void {
|
||||
const assignedGroup = assignRoom(jid, input);
|
||||
if (!assignedGroup) {
|
||||
@@ -521,7 +481,6 @@ async function main(): Promise<void> {
|
||||
},
|
||||
nudgeScheduler: nudgeSchedulerLoop,
|
||||
registeredGroups: () => registeredGroups,
|
||||
registerGroup,
|
||||
assignRoom: assignRoomForIpc,
|
||||
syncGroups: async (force: boolean) => {
|
||||
await Promise.all(
|
||||
|
||||
@@ -60,11 +60,6 @@ beforeEach(() => {
|
||||
sendMessage: async () => {},
|
||||
nudgeScheduler: vi.fn(),
|
||||
registeredGroups: () => groups,
|
||||
registerGroup: (jid, group) => {
|
||||
groups[jid] = group;
|
||||
setRegisteredGroup(jid, group);
|
||||
// Mock the fs.mkdirSync that registerGroup does
|
||||
},
|
||||
assignRoom: (jid, room) => {
|
||||
const assigned = assignRoom(jid, room);
|
||||
if (!assigned) return;
|
||||
@@ -384,13 +379,13 @@ describe('cancel_task authorization', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// --- register_group authorization ---
|
||||
// --- assign_room authorization ---
|
||||
|
||||
describe('register_group authorization', () => {
|
||||
it('non-main group cannot register a group', async () => {
|
||||
describe('assign_room authorization', () => {
|
||||
it('non-main group cannot assign a room', async () => {
|
||||
await processTaskIpc(
|
||||
{
|
||||
type: 'register_group',
|
||||
type: 'assign_room',
|
||||
jid: 'new@g.us',
|
||||
name: 'New Group',
|
||||
folder: 'new-group',
|
||||
@@ -405,10 +400,10 @@ describe('register_group authorization', () => {
|
||||
expect(groups['new@g.us']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('main group cannot register with unsafe folder path', async () => {
|
||||
it('main group cannot assign with unsafe folder path', async () => {
|
||||
await processTaskIpc(
|
||||
{
|
||||
type: 'register_group',
|
||||
type: 'assign_room',
|
||||
jid: 'new@g.us',
|
||||
name: 'New Group',
|
||||
folder: '../../outside',
|
||||
@@ -779,13 +774,13 @@ describe('schedule_task context_mode', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// --- register_group success path ---
|
||||
// --- assign_room success path ---
|
||||
|
||||
describe('register_group success', () => {
|
||||
it('main group can register a new group', async () => {
|
||||
describe('assign_room success', () => {
|
||||
it('main group can assign a new room', async () => {
|
||||
await processTaskIpc(
|
||||
{
|
||||
type: 'register_group',
|
||||
type: 'assign_room',
|
||||
jid: 'new@g.us',
|
||||
name: 'New Group',
|
||||
folder: 'new-group',
|
||||
@@ -796,7 +791,6 @@ describe('register_group success', () => {
|
||||
deps,
|
||||
);
|
||||
|
||||
// Verify group was registered in DB
|
||||
const group = getRegisteredGroup('new@g.us');
|
||||
expect(group).toBeDefined();
|
||||
expect(group!.name).toBe('New Group');
|
||||
@@ -804,10 +798,10 @@ describe('register_group success', () => {
|
||||
expect(group!.trigger).toBe('@Andy');
|
||||
});
|
||||
|
||||
it('register_group auto-fills missing folder and trigger for single rooms', async () => {
|
||||
it('assign_room auto-fills missing folder and trigger for single rooms', async () => {
|
||||
await processTaskIpc(
|
||||
{
|
||||
type: 'register_group',
|
||||
type: 'assign_room',
|
||||
jid: 'partial@g.us',
|
||||
name: 'Partial',
|
||||
},
|
||||
@@ -823,7 +817,7 @@ describe('register_group success', () => {
|
||||
expect(getStoredRoomSettings('partial@g.us')?.roomMode).toBe('single');
|
||||
});
|
||||
|
||||
it('register_group preserves an existing tribunal room mode', async () => {
|
||||
it('assign_room preserves an existing tribunal room mode when room_mode is omitted', async () => {
|
||||
assignRoom('legacy-tribunal@g.us', {
|
||||
name: 'Legacy Tribunal',
|
||||
roomMode: 'tribunal',
|
||||
@@ -833,7 +827,7 @@ describe('register_group success', () => {
|
||||
|
||||
await processTaskIpc(
|
||||
{
|
||||
type: 'register_group',
|
||||
type: 'assign_room',
|
||||
jid: 'legacy-tribunal@g.us',
|
||||
name: 'Legacy Tribunal Renamed',
|
||||
folder: 'legacy-tribunal',
|
||||
@@ -854,9 +848,7 @@ describe('register_group success', () => {
|
||||
'codex',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('assign_room success', () => {
|
||||
it('main group can assign a tribunal room and materialize capability rows', async () => {
|
||||
await processTaskIpc(
|
||||
{
|
||||
|
||||
26
src/ipc.ts
26
src/ipc.ts
@@ -26,7 +26,6 @@ export interface IpcDeps {
|
||||
sendMessage: (jid: string, text: string) => Promise<void>;
|
||||
nudgeScheduler?: () => void;
|
||||
registeredGroups: () => Record<string, RegisteredGroup>;
|
||||
registerGroup: (jid: string, group: RegisteredGroup) => void;
|
||||
assignRoom: (jid: string, room: AssignRoomInput) => void;
|
||||
syncGroups: (force: boolean) => Promise<void>;
|
||||
getAvailableGroups: () => AvailableGroup[];
|
||||
@@ -294,7 +293,7 @@ export async function processTaskIpc(
|
||||
groupFolder?: string;
|
||||
chatJid?: string;
|
||||
targetJid?: string;
|
||||
// For assign_room / register_group
|
||||
// For assign_room
|
||||
jid?: string;
|
||||
name?: string;
|
||||
folder?: string;
|
||||
@@ -304,7 +303,6 @@ export async function processTaskIpc(
|
||||
owner_agent_type?: AgentType;
|
||||
isMain?: boolean;
|
||||
workDir?: string;
|
||||
agentConfig?: RegisteredGroup['agentConfig'];
|
||||
},
|
||||
sourceGroup: string, // Verified identity from IPC directory
|
||||
isMain: boolean, // Verified from directory path
|
||||
@@ -602,8 +600,7 @@ export async function processTaskIpc(
|
||||
break;
|
||||
|
||||
case 'assign_room':
|
||||
case 'register_group':
|
||||
// Only main group can assign/register rooms
|
||||
// Only main group can assign rooms
|
||||
if (!isMain) {
|
||||
logger.warn(
|
||||
{ sourceGroup, type: data.type },
|
||||
@@ -642,28 +639,15 @@ export async function processTaskIpc(
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.type === 'assign_room') {
|
||||
deps.assignRoom(data.jid, {
|
||||
name: data.name,
|
||||
roomMode: data.room_mode,
|
||||
ownerAgentType: data.owner_agent_type,
|
||||
folder: data.folder,
|
||||
trigger: data.trigger,
|
||||
requiresTrigger: data.requiresTrigger,
|
||||
isMain: data.isMain,
|
||||
workDir: data.workDir,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
deps.assignRoom(data.jid, {
|
||||
name: data.name,
|
||||
roomMode: data.room_mode,
|
||||
ownerAgentType: data.owner_agent_type,
|
||||
folder: data.folder,
|
||||
trigger: data.trigger,
|
||||
requiresTrigger: data.requiresTrigger,
|
||||
ownerAgentConfig: data.agentConfig,
|
||||
addedAt: new Date().toISOString(),
|
||||
isMain: data.isMain,
|
||||
workDir: data.workDir,
|
||||
});
|
||||
} else {
|
||||
logger.warn(
|
||||
|
||||
Reference in New Issue
Block a user