fix(mcp): SessionArtifact passes description as metadata array

AgentSession::addArtifact expects ?array $metadata in the third
argument slot; the MCP tool was passing the optional description
string directly, producing a TypeError whenever a caller supplied a
non-null description. Wrap the description into a metadata array so
the call matches the model signature, and add a feature test that
exercises the MCP handler end-to-end to prevent regression.

Closes tasks.lthn.sh/view.php?id=95

Co-authored-by: Codex <noreply@openai.com>
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Snider 2026-04-23 18:04:28 +01:00
parent 5e2aecd68a
commit 3f5f4d15fe
2 changed files with 41 additions and 5 deletions

View file

@ -70,11 +70,10 @@ class SessionArtifact extends AgentTool
return $this->error('Session not found');
}
$session->addArtifact(
$path,
$action,
$this->optional($args, 'description')
);
$description = $this->optional($args, 'description');
$metadata = $description !== null ? ['description' => $description] : null;
$session->addArtifact($path, $action, $metadata);
return $this->success(['artifact' => $path]);
}

View file

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
use Core\Mod\Agentic\Mcp\Tools\Agent\Session\SessionArtifact;
use Core\Mod\Agentic\Models\AgentSession;
it('records artifact descriptions as metadata without throwing a type error', function () {
$workspace = createWorkspace();
$session = AgentSession::start(null, AgentSession::AGENT_OPUS, $workspace);
$tool = new SessionArtifact;
$payload = [
'session_id' => $session->session_id,
'path' => 'docs/session-artifact.md',
'action' => 'modified',
'description' => 'some narrative text',
'metadata' => null,
];
$result = null;
expect(function () use ($tool, $payload, $session, &$result): void {
$result = $tool->handle($payload, ['session_id' => $session->session_id]);
})->not->toThrow(TypeError::class);
expect($result)->toBeArray()
->and($result['success'])->toBeTrue()
->and($result['artifact'])->toBe('docs/session-artifact.md');
$artifacts = $session->fresh()->artifacts;
expect($artifacts)->toHaveCount(1)
->and($artifacts[0]['path'])->toBe('docs/session-artifact.md')
->and($artifacts[0]['action'])->toBe('modified')
->and($artifacts[0]['metadata'])->toBe(['description' => 'some narrative text']);
});