Unify MCP and agent tool surfaces onto one registry in NovelAgentToolset
Fixes NovelAgentService continuing a conversation under the wrong novel's route, since FindConversationAsync matched by id alone. Then extends NovelAgentToolset to all 45 tools the stdio MCP server offered (tag/location CRUD, character relationships, arc-stage beat pinning, question editing, cross-novel novel listing/creation), tagging each with whether it needs an explicit novel scope so a later MCP adapter can inject it. Renames the toolset's 33 existing schemas from snake_case to camelCase to match .NET/REST convention, since nothing external consumes them. Lays the groundwork to serve this same registry over MCP at /mcp and retire the separate stdio Novelly.Mcp project (docs/plans/api/mcp_http_merge_plan.md).
This commit is contained in:
@@ -100,7 +100,7 @@ public class NovelAgentServiceTests : ServiceTestFixture
|
||||
var novelId = (await Novels.CreateAsync(new CreateNovelRequest("The Salt Road"))).Id;
|
||||
|
||||
var model = new ScriptedModelClient([
|
||||
[ToolUse("t1", "update_character", new { character_id = Guid.NewGuid().ToString(), name = "Ines" })],
|
||||
[ToolUse("t1", "update_character", new { characterId = Guid.NewGuid().ToString(), name = "Ines" })],
|
||||
[new AgentTextBlock("That character does not exist yet — shall I create her?")]
|
||||
]);
|
||||
|
||||
@@ -185,6 +185,42 @@ public class NovelAgentServiceTests : ServiceTestFixture
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Continuing_a_conversation_under_a_different_novel_is_rejected()
|
||||
{
|
||||
var novelAId = (await Novels.CreateAsync(new CreateNovelRequest("The Salt Road"))).Id;
|
||||
var novelBId = (await Novels.CreateAsync(new CreateNovelRequest("A Different Book"))).Id;
|
||||
var model = new ScriptedModelClient([
|
||||
[new AgentTextBlock("First answer.")]
|
||||
]);
|
||||
var agent = BuildAgent(model);
|
||||
|
||||
var first = await agent.SendMessageAsync(novelAId, new SendAgentMessageRequest("Question one."));
|
||||
|
||||
var second = await agent.SendMessageAsync(
|
||||
novelBId, new SendAgentMessageRequest("Question two.", first.ConversationId));
|
||||
|
||||
Assert.That(second, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Continuing_a_conversation_under_its_own_novel_still_works()
|
||||
{
|
||||
var novelId = (await Novels.CreateAsync(new CreateNovelRequest("The Salt Road"))).Id;
|
||||
var model = new ScriptedModelClient([
|
||||
[new AgentTextBlock("First answer.")],
|
||||
[new AgentTextBlock("Second answer.")]
|
||||
]);
|
||||
var agent = BuildAgent(model);
|
||||
|
||||
var first = await agent.SendMessageAsync(novelId, new SendAgentMessageRequest("Question one."));
|
||||
var second = await agent.SendMessageAsync(
|
||||
novelId, new SendAgentMessageRequest("Question two.", first.ConversationId));
|
||||
|
||||
Assert.That(second, Is.Not.Null);
|
||||
Assert.That(second.ConversationId, Is.EqualTo(first.ConversationId));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Every_tool_declares_an_object_schema_and_a_description()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user