1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2026 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Mcp\Extension\Tasks\Server\Store;
15:
16: use Nexus\Mcp\Core\Schema\Request\InputRequest;
17: use Nexus\Mcp\Core\Schema\Result\InputResponse;
18: use Nexus\Mcp\Extension\Tasks\Server\Exception\InputRequestKeyReusedException;
19:
20: /**
21: * Durable storage for task records. `createTask()` MUST make the record visible
22: * to `findTask()` before returning, and the `trySet*` transitions are sticky
23: * once terminal.
24: */
25: interface TaskStoreInterface
26: {
27: /**
28: * Creates a durable record in the `working` status and returns it.
29: *
30: * @param non-empty-string $toolName
31: * @param null|array<array-key, mixed> $arguments
32: */
33: public function createTask(string $toolName, ?array $arguments, ?int $ttlMs, int $pollIntervalMs): TaskRecord;
34:
35: /**
36: * The record for `$taskId`, or `null` when it never existed or its
37: * retention window has lapsed.
38: *
39: * @param non-empty-string $taskId
40: */
41: public function findTask(string $taskId): ?TaskRecord;
42:
43: /**
44: * Returns the task to `working`, clearing its pending input requests.
45: *
46: * @param non-empty-string $taskId
47: *
48: * @return bool `false` when the record is terminal or absent
49: */
50: public function trySetWorking(string $taskId): bool;
51:
52: /**
53: * Completes the task with its stored result payload, a tool error result included.
54: *
55: * @param non-empty-string $taskId
56: * @param array<string, mixed> $result
57: *
58: * @return bool `false` when the record is terminal or absent
59: */
60: public function trySetCompleted(string $taskId, array $result): bool;
61:
62: /**
63: * Fails the task with a protocol-level error payload.
64: *
65: * @param non-empty-string $taskId
66: * @param array<string, mixed> $error
67: * @param null|non-empty-string $statusMessage
68: *
69: * @return bool `false` when the record is terminal or absent
70: */
71: public function trySetFailed(string $taskId, array $error, ?string $statusMessage = null): bool;
72:
73: /**
74: * @param non-empty-string $taskId
75: *
76: * @return bool `false` when the record is terminal or absent
77: */
78: public function trySetCancelled(string $taskId): bool;
79:
80: /**
81: * Parks the task in `input_required` with the given requests and the
82: * continuation token to re-dispatch with, refusing a key already issued
83: * since request keys are unique per task.
84: *
85: * @param non-empty-string $taskId
86: * @param array<int|non-empty-string, InputRequest> $inputRequests
87: *
88: * @return bool `false` when the record is terminal or absent
89: *
90: * @throws InputRequestKeyReusedException
91: */
92: public function trySetInputRequired(string $taskId, array $inputRequests, ?string $requestState): bool;
93:
94: /**
95: * Merges answers into the record, ignoring a response for a key that is not
96: * currently outstanding and accumulating every accepted answer for the next
97: * re-dispatch.
98: *
99: * @param non-empty-string $taskId
100: * @param array<int|non-empty-string, InputResponse> $inputResponses
101: *
102: * @return null|TaskRecord the updated record, or `null` when it is absent
103: */
104: public function resolveInputRequests(string $taskId, array $inputResponses): ?TaskRecord;
105: }
106: