mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-15 17:00:59 +00:00
feat(coding-agent): add set_session_name RPC command (#1075)
- Add set_session_name command with empty name validation - Expose sessionName in get_state response - Add setSessionName() to AgentSession and RpcClient - Document in docs/rpc.md
This commit is contained in:
parent
cb08758696
commit
e20583aac8
6 changed files with 86 additions and 1 deletions
|
|
@ -154,6 +154,7 @@ Response:
|
|||
"followUpMode": "one-at-a-time",
|
||||
"sessionFile": "/path/to/session.jsonl",
|
||||
"sessionId": "abc123",
|
||||
"sessionName": "my-feature-work",
|
||||
"autoCompactionEnabled": true,
|
||||
"messageCount": 5,
|
||||
"pendingMessageCount": 0
|
||||
|
|
@ -161,7 +162,7 @@ Response:
|
|||
}
|
||||
```
|
||||
|
||||
The `model` field is a full [Model](#model) object or `null`.
|
||||
The `model` field is a full [Model](#model) object or `null`. The `sessionName` field is the display name set via `set_session_name`, or omitted if not set.
|
||||
|
||||
#### get_messages
|
||||
|
||||
|
|
@ -612,6 +613,25 @@ Response:
|
|||
|
||||
Returns `{"text": null}` if no assistant messages exist.
|
||||
|
||||
#### set_session_name
|
||||
|
||||
Set a display name for the current session. The name appears in session listings and helps identify sessions.
|
||||
|
||||
```json
|
||||
{"type": "set_session_name", "name": "my-feature-work"}
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"type": "response",
|
||||
"command": "set_session_name",
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
The current session name is available via `get_state` in the `sessionName` field.
|
||||
|
||||
### Commands
|
||||
|
||||
#### get_commands
|
||||
|
|
|
|||
|
|
@ -590,6 +590,11 @@ export class AgentSession {
|
|||
return this.sessionManager.getSessionId();
|
||||
}
|
||||
|
||||
/** Current session display name, if set */
|
||||
get sessionName(): string | undefined {
|
||||
return this.sessionManager.getSessionName();
|
||||
}
|
||||
|
||||
/** Scoped models for cycling (from --models flag) */
|
||||
get scopedModels(): ReadonlyArray<{ model: Model<any>; thinkingLevel: ThinkingLevel }> {
|
||||
return this._scopedModels;
|
||||
|
|
@ -2181,6 +2186,13 @@ export class AgentSession {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a display name for the current session.
|
||||
*/
|
||||
setSessionName(name: string): void {
|
||||
this.sessionManager.appendSessionInfo(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fork from a specific entry.
|
||||
* Emits before_fork/fork session events to extensions.
|
||||
|
|
|
|||
|
|
@ -362,6 +362,13 @@ export class RpcClient {
|
|||
return this.getData<{ text: string | null }>(response).text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the session display name.
|
||||
*/
|
||||
async setSessionName(name: string): Promise<void> {
|
||||
await this.send({ type: "set_session_name", name });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all messages in the session.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -349,6 +349,7 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|||
followUpMode: session.followUpMode,
|
||||
sessionFile: session.sessionFile,
|
||||
sessionId: session.sessionId,
|
||||
sessionName: session.sessionName,
|
||||
autoCompactionEnabled: session.autoCompactionEnabled,
|
||||
messageCount: session.messages.length,
|
||||
pendingMessageCount: session.pendingMessageCount,
|
||||
|
|
@ -490,6 +491,15 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|||
return success(id, "get_last_assistant_text", { text });
|
||||
}
|
||||
|
||||
case "set_session_name": {
|
||||
const name = command.name.trim();
|
||||
if (!name) {
|
||||
return error(id, "set_session_name", "Session name cannot be empty");
|
||||
}
|
||||
session.setSessionName(name);
|
||||
return success(id, "set_session_name");
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// Messages
|
||||
// =================================================================
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ export type RpcCommand =
|
|||
| { id?: string; type: "fork"; entryId: string }
|
||||
| { id?: string; type: "get_fork_messages" }
|
||||
| { id?: string; type: "get_last_assistant_text" }
|
||||
| { id?: string; type: "set_session_name"; name: string }
|
||||
|
||||
// Messages
|
||||
| { id?: string; type: "get_messages" }
|
||||
|
|
@ -96,6 +97,7 @@ export interface RpcSessionState {
|
|||
followUpMode: "all" | "one-at-a-time";
|
||||
sessionFile?: string;
|
||||
sessionId: string;
|
||||
sessionName?: string;
|
||||
autoCompactionEnabled: boolean;
|
||||
messageCount: number;
|
||||
pendingMessageCount: number;
|
||||
|
|
@ -185,6 +187,7 @@ export type RpcResponse =
|
|||
success: true;
|
||||
data: { text: string | null };
|
||||
}
|
||||
| { id?: string; type: "response"; command: "set_session_name"; success: true }
|
||||
|
||||
// Messages
|
||||
| { id?: string; type: "response"; command: "get_messages"; success: true; data: { messages: AgentMessage[] } }
|
||||
|
|
|
|||
|
|
@ -282,4 +282,37 @@ describe.skipIf(!process.env.ANTHROPIC_API_KEY && !process.env.ANTHROPIC_OAUTH_T
|
|||
text = await client.getLastAssistantText();
|
||||
expect(text).toContain("test123");
|
||||
}, 90000);
|
||||
|
||||
test("should set and get session name", async () => {
|
||||
await client.start();
|
||||
|
||||
// Initially undefined
|
||||
let state = await client.getState();
|
||||
expect(state.sessionName).toBeUndefined();
|
||||
|
||||
// Set name
|
||||
await client.setSessionName("my-test-session");
|
||||
|
||||
// Verify via state
|
||||
state = await client.getState();
|
||||
expect(state.sessionName).toBe("my-test-session");
|
||||
|
||||
// Wait for file writes
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
|
||||
// Verify session_info entry in session file
|
||||
const sessionsPath = join(sessionDir, "sessions");
|
||||
const sessionDirs = readdirSync(sessionsPath);
|
||||
const cwdSessionDir = join(sessionsPath, sessionDirs[0]);
|
||||
const sessionFiles = readdirSync(cwdSessionDir).filter((f) => f.endsWith(".jsonl"));
|
||||
const sessionContent = readFileSync(join(cwdSessionDir, sessionFiles[0]), "utf8");
|
||||
const entries = sessionContent
|
||||
.trim()
|
||||
.split("\n")
|
||||
.map((line) => JSON.parse(line));
|
||||
|
||||
const sessionInfoEntries = entries.filter((e: { type: string }) => e.type === "session_info");
|
||||
expect(sessionInfoEntries.length).toBe(1);
|
||||
expect(sessionInfoEntries[0].name).toBe("my-test-session");
|
||||
}, 30000);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue