Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions app/Domain/Memory/Actions/StoreMemoryAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ private function normalizeRejectedAlternatives(array $raw): array
*/
private function storeChunk(
string $teamId,
string $agentId,
?string $agentId,
string $chunk,
string $sourceType,
?string $projectId,
Expand Down Expand Up @@ -225,7 +225,7 @@ private function storeChunk(
*/
private function evaluateWriteGate(
string $teamId,
string $agentId,
?string $agentId,
string $contentHash,
string $embedding,
): WriteGateResult {
Expand Down Expand Up @@ -304,7 +304,7 @@ private function handleUpdate(
string $newContent,
string $newEmbedding,
string $teamId,
string $agentId,
?string $agentId,
float $newConfidence,
float $newImportance,
array $newTags,
Expand Down Expand Up @@ -347,7 +347,7 @@ private function handleUpdate(

private function handleAdd(
string $teamId,
string $agentId,
?string $agentId,
string $chunk,
string $embedding,
string $contentHash,
Expand Down Expand Up @@ -409,7 +409,7 @@ private function handleAdd(
/**
* LLM-assisted merge of two related facts.
*/
private function mergeContent(string $existing, string $new, string $teamId, string $agentId): ?string
private function mergeContent(string $existing, string $new, string $teamId, ?string $agentId): ?string
{
if (! $this->gateway) {
return null;
Expand Down
22 changes: 22 additions & 0 deletions tests/Unit/Domain/Memory/Actions/StoreMemoryActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ public function test_chunk_content_splits_long_content_by_paragraphs(): void
$this->assertStringContainsString('A', $chunks[0]);
}

public function test_team_level_memory_accepts_a_null_agent_id(): void
{
// execute() advertises `?string $agentId`, but storeChunk() and the
// write-gate helpers below it declared a non-nullable `string`. Every
// team-scoped write — DistillTeamEventsAction passes `agentId: null`
// explicitly — therefore threw a TypeError that execute()'s catch
// swallowed into a Log::warning, so nothing was ever stored and no
// error surfaced. Production had 0 rows in `memories`.
$action = new StoreMemoryAction;

foreach (['storeChunk', 'evaluateWriteGate', 'handleUpdate', 'handleAdd', 'mergeContent'] as $name) {
$param = collect((new \ReflectionMethod($action, $name))->getParameters())
->firstWhere(fn (\ReflectionParameter $p) => $p->getName() === 'agentId');

$this->assertNotNull($param, "{$name}() should take an \$agentId");
$this->assertTrue(
$param->getType()?->allowsNull(),
"{$name}() must accept a null \$agentId — team-scoped memories have no agent",
);
}
}

public function test_execute_returns_empty_array_when_content_is_empty(): void
{
$action = new StoreMemoryAction;
Expand Down
Loading