tinker-agent 2.6.0 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -1
- package/package.json +1 -1
- package/src/agent/loop.ts +22 -0
- package/src/agent/runtime-session.ts +158 -0
- package/src/cli/tui-runner.tsx +14 -1
- package/src/events/stdout-event-printer.ts +14 -0
- package/src/events/types.ts +9 -0
- package/src/memory/contracts.ts +46 -0
- package/src/memory/memory-coordinator.ts +445 -4
- package/src/memory/memory-create-tool.ts +117 -0
- package/src/memory/memory-delete-tool.ts +88 -0
- package/src/memory/memory-store.ts +239 -0
- package/src/memory/memory-update-tool.ts +142 -0
- package/src/observation/observation-builder.ts +70 -0
- package/src/session/session-tool-result-codec.ts +4 -0
- package/src/tools/ask-user.ts +100 -0
- package/src/tools/registry.ts +30 -0
- package/src/tools/types.ts +71 -0
- package/src/tui/app.tsx +33 -5
- package/src/tui/components/ask-user.tsx +61 -0
- package/src/tui/components/footer.tsx +14 -1
- package/src/tui/components/resume-session-picker.tsx +118 -37
- package/src/tui/event-store.ts +57 -0
- package/src/tui/tui-session-controller.ts +8 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,28 @@ All notable user-facing changes to Tinker are documented here. The project follo
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [2.7.0] - 2026-09-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Add `AskUser`, an interactive tool that lets the agent pause on a material
|
|
13
|
+
ambiguity and present two to six complete choices in the TUI before resuming
|
|
14
|
+
the same turn with the selected answer.
|
|
15
|
+
- Add model-accessible `MemoryCreate`, `MemoryUpdate`, and `MemoryDelete` tools
|
|
16
|
+
for explicitly maintaining global memories shared across sessions and
|
|
17
|
+
workspaces.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Redesign the session resume picker as a compact table, making session metadata
|
|
22
|
+
easier to scan while preserving keyboard navigation and search.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Give the long-history PTY resume fixture enough time on slower Linux CI
|
|
27
|
+
runners, avoiding a false timeout while the model is still producing the
|
|
28
|
+
expected response.
|
|
29
|
+
|
|
8
30
|
## [2.6.0] - 2026-09-03
|
|
9
31
|
|
|
10
32
|
### Added
|
|
@@ -324,7 +346,8 @@ All notable user-facing changes to Tinker are documented here. The project follo
|
|
|
324
346
|
- First formal npm release under the `tinker-agent` package name with the `tinker`
|
|
325
347
|
executable.
|
|
326
348
|
|
|
327
|
-
[Unreleased]: https://github.com/ishowshao/tinker/compare/v2.
|
|
349
|
+
[Unreleased]: https://github.com/ishowshao/tinker/compare/v2.7.0...HEAD
|
|
350
|
+
[2.7.0]: https://github.com/ishowshao/tinker/releases/tag/v2.7.0
|
|
328
351
|
[2.6.0]: https://github.com/ishowshao/tinker/releases/tag/v2.6.0
|
|
329
352
|
[2.5.0]: https://github.com/ishowshao/tinker/releases/tag/v2.5.0
|
|
330
353
|
[2.4.0]: https://github.com/ishowshao/tinker/releases/tag/v2.4.0
|
package/package.json
CHANGED
package/src/agent/loop.ts
CHANGED
|
@@ -384,6 +384,28 @@ export async function runAgent(input: RunAgentInput): Promise<RunAgentResult> {
|
|
|
384
384
|
});
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
+
if (toolCalls.some((call) => call.name === "AskUser") && toolCalls.length !== 1) {
|
|
388
|
+
const detail =
|
|
389
|
+
"AskUser must be the only tool call in an assistant response. Call it alone on the next iteration.";
|
|
390
|
+
const completions = toolCalls.map((call, index) => {
|
|
391
|
+
requireCallInIteration(call, iteration, index + 1);
|
|
392
|
+
return {
|
|
393
|
+
call,
|
|
394
|
+
kind: "synthetic" as const,
|
|
395
|
+
reason: "failed_active" as const,
|
|
396
|
+
detail,
|
|
397
|
+
};
|
|
398
|
+
});
|
|
399
|
+
input.ledger.commitToolCompletions(completions);
|
|
400
|
+
await input.runtimeSession.append({
|
|
401
|
+
type: "agent.iteration.finished",
|
|
402
|
+
...iteration,
|
|
403
|
+
data: { outcome: "continue", toolCallCount: toolCalls.length },
|
|
404
|
+
});
|
|
405
|
+
input.runtimeSession.finishIterationForContinuation(iteration);
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
|
|
387
409
|
for (let callIndex = 0; callIndex < toolCalls.length; callIndex += 1) {
|
|
388
410
|
const call = requireToolCall(toolCalls, callIndex);
|
|
389
411
|
requireCallInIteration(call, iteration, callIndex + 1);
|
|
@@ -80,6 +80,8 @@ import {
|
|
|
80
80
|
type ContextStatusRawResult,
|
|
81
81
|
type ContextSwapCandidatesRawResult,
|
|
82
82
|
type ContextSwapRawResult,
|
|
83
|
+
type AskUserRequest,
|
|
84
|
+
type AskUserResponse,
|
|
83
85
|
type ToolExecutor,
|
|
84
86
|
} from "../tools/types";
|
|
85
87
|
import type { TurnUndoResult } from "../tools/turn-undo-manager";
|
|
@@ -202,9 +204,20 @@ export type RuntimeSession = {
|
|
|
202
204
|
subscribeBashGuard(listener: () => void): () => void;
|
|
203
205
|
setYoloMode(enabled: boolean): void;
|
|
204
206
|
resolveBashConfirmation(decision: "allow" | "deny"): Promise<void>;
|
|
207
|
+
askUser(): AskUserSnapshot;
|
|
208
|
+
subscribeAskUser(listener: () => void): () => void;
|
|
209
|
+
resolveAskUser(response: AskUserResolution): Promise<void>;
|
|
205
210
|
dispose(reason: SessionDisposeReason): Promise<void>;
|
|
206
211
|
};
|
|
207
212
|
|
|
213
|
+
export type AskUserSnapshot = {
|
|
214
|
+
readonly pending?: AskUserRequest;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export type AskUserResolution =
|
|
218
|
+
| { readonly outcome: "selected"; readonly selectedIndex: number }
|
|
219
|
+
| { readonly outcome: "dismissed" };
|
|
220
|
+
|
|
208
221
|
export type BashGuardSource = "default" | "environment" | "cli" | "session";
|
|
209
222
|
|
|
210
223
|
export type BashGuardSnapshot = {
|
|
@@ -322,8 +335,12 @@ type CommonRuntimeSessionInput = {
|
|
|
322
335
|
toolingConfig?: PublicToolingConfig;
|
|
323
336
|
memorySearch?: ToolExecutor;
|
|
324
337
|
memoryGet?: ToolExecutor;
|
|
338
|
+
memoryCreate?: ToolExecutor;
|
|
339
|
+
memoryUpdate?: ToolExecutor;
|
|
340
|
+
memoryDelete?: ToolExecutor;
|
|
325
341
|
completedTurnHook?: CompletedTurnHook;
|
|
326
342
|
enableTurnUndo?: boolean;
|
|
343
|
+
enableAskUser?: boolean;
|
|
327
344
|
bashGuard?: {
|
|
328
345
|
readonly mode: "guard" | "yolo";
|
|
329
346
|
readonly source: Exclude<BashGuardSource, "session">;
|
|
@@ -490,6 +507,16 @@ class DefaultRuntimeSession implements RuntimeSession {
|
|
|
490
507
|
private bashGuardSource: BashGuardSource;
|
|
491
508
|
private bashGuardSnapshot: BashGuardSnapshot;
|
|
492
509
|
private readonly bashGuardListeners = new Set<() => void>();
|
|
510
|
+
private askUserSnapshot: AskUserSnapshot = Object.freeze({});
|
|
511
|
+
private readonly askUserListeners = new Set<() => void>();
|
|
512
|
+
private pendingAskUser?: {
|
|
513
|
+
readonly request: AskUserRequest;
|
|
514
|
+
readonly startedAt: number;
|
|
515
|
+
readonly call: ToolCallIdentity;
|
|
516
|
+
readonly resolve: (response: AskUserResponse) => void;
|
|
517
|
+
readonly reject: (error: unknown) => void;
|
|
518
|
+
readonly removeAbortListener: () => void;
|
|
519
|
+
};
|
|
493
520
|
private assistantTextDeltaSinkDisabled = false;
|
|
494
521
|
private pendingBashConfirmation?: {
|
|
495
522
|
readonly command: string;
|
|
@@ -695,6 +722,15 @@ class DefaultRuntimeSession implements RuntimeSession {
|
|
|
695
722
|
...(input.enableTurnUndo === true ? { enableTurnUndo: true } : {}),
|
|
696
723
|
webFetchRefiner: input.webFetchRefiner,
|
|
697
724
|
toolingConfig: input.toolingConfig,
|
|
725
|
+
...(input.enableAskUser === true
|
|
726
|
+
? {
|
|
727
|
+
askUser: (
|
|
728
|
+
call: ToolCallIdentity,
|
|
729
|
+
request: AskUserRequest,
|
|
730
|
+
signal: AbortSignal,
|
|
731
|
+
) => session.requestUserAnswer(call, request, signal),
|
|
732
|
+
}
|
|
733
|
+
: {}),
|
|
698
734
|
bashGuard: {
|
|
699
735
|
surface: input.bashGuard?.surface ?? "one-shot",
|
|
700
736
|
confirm: (call, request, signal) =>
|
|
@@ -704,6 +740,15 @@ class DefaultRuntimeSession implements RuntimeSession {
|
|
|
704
740
|
? {}
|
|
705
741
|
: { memorySearch: input.memorySearch }),
|
|
706
742
|
...(input.memoryGet === undefined ? {} : { memoryGet: input.memoryGet }),
|
|
743
|
+
...(input.memoryCreate === undefined
|
|
744
|
+
? {}
|
|
745
|
+
: { memoryCreate: input.memoryCreate }),
|
|
746
|
+
...(input.memoryUpdate === undefined
|
|
747
|
+
? {}
|
|
748
|
+
: { memoryUpdate: input.memoryUpdate }),
|
|
749
|
+
...(input.memoryDelete === undefined
|
|
750
|
+
? {}
|
|
751
|
+
: { memoryDelete: input.memoryDelete }),
|
|
707
752
|
...(session.skillCatalog.skills.size === 0
|
|
708
753
|
? {}
|
|
709
754
|
: {
|
|
@@ -1204,6 +1249,119 @@ class DefaultRuntimeSession implements RuntimeSession {
|
|
|
1204
1249
|
}
|
|
1205
1250
|
}
|
|
1206
1251
|
|
|
1252
|
+
askUser(): AskUserSnapshot {
|
|
1253
|
+
return this.askUserSnapshot;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
subscribeAskUser(listener: () => void): () => void {
|
|
1257
|
+
this.askUserListeners.add(listener);
|
|
1258
|
+
return () => this.askUserListeners.delete(listener);
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
async resolveAskUser(response: AskUserResolution): Promise<void> {
|
|
1262
|
+
const pending = this.pendingAskUser;
|
|
1263
|
+
if (pending === undefined) {
|
|
1264
|
+
throw new Error("No AskUser question is pending.");
|
|
1265
|
+
}
|
|
1266
|
+
let result: AskUserResponse;
|
|
1267
|
+
if (response.outcome === "selected") {
|
|
1268
|
+
if (!Number.isSafeInteger(response.selectedIndex)) {
|
|
1269
|
+
throw new Error("AskUser selectedIndex must be an integer.");
|
|
1270
|
+
}
|
|
1271
|
+
const option = pending.request.options[response.selectedIndex];
|
|
1272
|
+
if (option === undefined) {
|
|
1273
|
+
throw new Error("AskUser selectedIndex is out of range.");
|
|
1274
|
+
}
|
|
1275
|
+
result = { outcome: "selected", answer: option.description };
|
|
1276
|
+
} else {
|
|
1277
|
+
result = { outcome: "dismissed" };
|
|
1278
|
+
}
|
|
1279
|
+
this.pendingAskUser = undefined;
|
|
1280
|
+
this.askUserSnapshot = Object.freeze({});
|
|
1281
|
+
pending.removeAbortListener();
|
|
1282
|
+
await this.append({
|
|
1283
|
+
type: "tool.user_question.resolved",
|
|
1284
|
+
...pending.call,
|
|
1285
|
+
data: {
|
|
1286
|
+
...result,
|
|
1287
|
+
durationMs: Date.now() - pending.startedAt,
|
|
1288
|
+
},
|
|
1289
|
+
});
|
|
1290
|
+
pending.resolve(result);
|
|
1291
|
+
this.notifyAskUserListeners();
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
private async requestUserAnswer(
|
|
1295
|
+
call: ToolCallIdentity,
|
|
1296
|
+
request: AskUserRequest,
|
|
1297
|
+
signal: AbortSignal,
|
|
1298
|
+
): Promise<AskUserResponse> {
|
|
1299
|
+
if (this.pendingAskUser !== undefined) {
|
|
1300
|
+
throw new Error("Another AskUser question is already pending.");
|
|
1301
|
+
}
|
|
1302
|
+
if (this.pendingBashConfirmation !== undefined) {
|
|
1303
|
+
throw new Error("Cannot ask the user while a Bash confirmation is pending.");
|
|
1304
|
+
}
|
|
1305
|
+
if (signal.aborted) {
|
|
1306
|
+
throw cancellationError(signal);
|
|
1307
|
+
}
|
|
1308
|
+
const startedAt = Date.now();
|
|
1309
|
+
await this.append({
|
|
1310
|
+
type: "tool.user_question.requested",
|
|
1311
|
+
...call,
|
|
1312
|
+
data: request,
|
|
1313
|
+
});
|
|
1314
|
+
return new Promise<AskUserResponse>((resolve, reject) => {
|
|
1315
|
+
const onAbort = () => {
|
|
1316
|
+
const pending = this.pendingAskUser;
|
|
1317
|
+
if (pending?.call.toolCallId !== call.toolCallId) {
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1320
|
+
this.pendingAskUser = undefined;
|
|
1321
|
+
this.askUserSnapshot = Object.freeze({});
|
|
1322
|
+
void this.append({
|
|
1323
|
+
type: "tool.user_question.resolved",
|
|
1324
|
+
...call,
|
|
1325
|
+
data: {
|
|
1326
|
+
outcome: "cancelled",
|
|
1327
|
+
durationMs: Date.now() - startedAt,
|
|
1328
|
+
},
|
|
1329
|
+
}).finally(() => {
|
|
1330
|
+
reject(cancellationError(signal));
|
|
1331
|
+
this.notifyAskUserListeners();
|
|
1332
|
+
});
|
|
1333
|
+
};
|
|
1334
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1335
|
+
const immutableRequest = Object.freeze({
|
|
1336
|
+
question: request.question,
|
|
1337
|
+
options: Object.freeze(
|
|
1338
|
+
request.options.map((option) =>
|
|
1339
|
+
Object.freeze({ description: option.description }),
|
|
1340
|
+
),
|
|
1341
|
+
),
|
|
1342
|
+
});
|
|
1343
|
+
this.pendingAskUser = {
|
|
1344
|
+
request: immutableRequest,
|
|
1345
|
+
startedAt,
|
|
1346
|
+
call,
|
|
1347
|
+
resolve,
|
|
1348
|
+
reject,
|
|
1349
|
+
removeAbortListener: () => signal.removeEventListener("abort", onAbort),
|
|
1350
|
+
};
|
|
1351
|
+
this.askUserSnapshot = Object.freeze({ pending: immutableRequest });
|
|
1352
|
+
this.notifyAskUserListeners();
|
|
1353
|
+
if (signal.aborted) {
|
|
1354
|
+
onAbort();
|
|
1355
|
+
}
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
private notifyAskUserListeners(): void {
|
|
1360
|
+
for (const listener of this.askUserListeners) {
|
|
1361
|
+
listener();
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1207
1365
|
async importImage(
|
|
1208
1366
|
sourcePath: string,
|
|
1209
1367
|
signal: AbortSignal,
|
package/src/cli/tui-runner.tsx
CHANGED
|
@@ -118,6 +118,7 @@ export async function runTui(options: RunTuiOptions): Promise<void> {
|
|
|
118
118
|
),
|
|
119
119
|
toolingConfig: options.publicConfig.tooling,
|
|
120
120
|
enableTurnUndo: true,
|
|
121
|
+
enableAskUser: true,
|
|
121
122
|
bashGuard: {
|
|
122
123
|
mode: sessionConfig.bashGuardMode,
|
|
123
124
|
source: sessionConfig.bashGuardSource,
|
|
@@ -134,6 +135,18 @@ export async function runTui(options: RunTuiOptions): Promise<void> {
|
|
|
134
135
|
workspaceRoot,
|
|
135
136
|
sessionId,
|
|
136
137
|
}),
|
|
138
|
+
memoryCreate: memoryCoordinator.createCreateToolExecutor({
|
|
139
|
+
workspaceRoot,
|
|
140
|
+
sessionId,
|
|
141
|
+
}),
|
|
142
|
+
memoryUpdate: memoryCoordinator.createUpdateToolExecutor({
|
|
143
|
+
workspaceRoot,
|
|
144
|
+
sessionId,
|
|
145
|
+
}),
|
|
146
|
+
memoryDelete: memoryCoordinator.createDeleteToolExecutor({
|
|
147
|
+
workspaceRoot,
|
|
148
|
+
sessionId,
|
|
149
|
+
}),
|
|
137
150
|
completedTurnHook: memoryCoordinator,
|
|
138
151
|
}),
|
|
139
152
|
};
|
|
@@ -323,7 +336,6 @@ export async function runTui(options: RunTuiOptions): Promise<void> {
|
|
|
323
336
|
} finally {
|
|
324
337
|
instance?.unmount();
|
|
325
338
|
restoreStdin();
|
|
326
|
-
memoryCoordinator?.dispose();
|
|
327
339
|
if (controller !== undefined) {
|
|
328
340
|
try {
|
|
329
341
|
await controller.dispose(disposeReason);
|
|
@@ -337,6 +349,7 @@ export async function runTui(options: RunTuiOptions): Promise<void> {
|
|
|
337
349
|
);
|
|
338
350
|
}
|
|
339
351
|
}
|
|
352
|
+
memoryCoordinator?.dispose();
|
|
340
353
|
}
|
|
341
354
|
|
|
342
355
|
if (primaryError !== undefined) {
|
|
@@ -140,6 +140,16 @@ export class StdoutEventPrinter implements EventSink {
|
|
|
140
140
|
`tool.confirmation.resolved toolCallId=${event.toolCallId} decision=${event.data.decision} durationMs=${event.data.durationMs}\n`,
|
|
141
141
|
);
|
|
142
142
|
break;
|
|
143
|
+
case "tool.user_question.requested":
|
|
144
|
+
this.stdout.write(
|
|
145
|
+
`tool.user_question.requested toolCallId=${event.toolCallId} question=${JSON.stringify(event.data.question)} options=${event.data.options.length}\n`,
|
|
146
|
+
);
|
|
147
|
+
break;
|
|
148
|
+
case "tool.user_question.resolved":
|
|
149
|
+
this.stdout.write(
|
|
150
|
+
`tool.user_question.resolved toolCallId=${event.toolCallId} outcome=${event.data.outcome} durationMs=${event.data.durationMs}\n`,
|
|
151
|
+
);
|
|
152
|
+
break;
|
|
143
153
|
case "mcp.server.connected":
|
|
144
154
|
this.stdout.write(
|
|
145
155
|
`mcp.server.connected name=${event.data.serverName} tools=${event.data.toolCount}\n`,
|
|
@@ -235,7 +245,11 @@ function formatToolRawResult(call: ToolCall, raw: ToolRawResult): string[] {
|
|
|
235
245
|
case "context_maintenance":
|
|
236
246
|
case "memory_search":
|
|
237
247
|
case "memory_get":
|
|
248
|
+
case "memory_create":
|
|
249
|
+
case "memory_update":
|
|
250
|
+
case "memory_delete":
|
|
238
251
|
case "wait":
|
|
252
|
+
case "ask_user":
|
|
239
253
|
case "mcp":
|
|
240
254
|
case "generic":
|
|
241
255
|
return [];
|
package/src/events/types.ts
CHANGED
|
@@ -351,6 +351,14 @@ export type AgentEventDataMap = {
|
|
|
351
351
|
decision: "allow" | "deny" | "cancelled";
|
|
352
352
|
durationMs: number;
|
|
353
353
|
};
|
|
354
|
+
"tool.user_question.requested": {
|
|
355
|
+
question: string;
|
|
356
|
+
options: readonly { description: string }[];
|
|
357
|
+
};
|
|
358
|
+
"tool.user_question.resolved":
|
|
359
|
+
| { outcome: "selected"; answer: string; durationMs: number }
|
|
360
|
+
| { outcome: "dismissed"; durationMs: number }
|
|
361
|
+
| { outcome: "cancelled"; durationMs: number };
|
|
354
362
|
"agent.iteration.finished": {
|
|
355
363
|
outcome: "continue" | "completed";
|
|
356
364
|
toolCallCount: number;
|
|
@@ -448,6 +456,7 @@ export type AgentEventInput =
|
|
|
448
456
|
"tool.started" | "tool.raw_result" | "tool.finished" | "tool.observation"
|
|
449
457
|
>
|
|
450
458
|
| ToolEventInput<"tool.confirmation.requested" | "tool.confirmation.resolved">
|
|
459
|
+
| ToolEventInput<"tool.user_question.requested" | "tool.user_question.resolved">
|
|
451
460
|
| ToolEventInput<
|
|
452
461
|
"bash.task.backgrounded" | "bash.task.stopping" | "bash.task.finished"
|
|
453
462
|
>;
|
package/src/memory/contracts.ts
CHANGED
|
@@ -2,6 +2,9 @@ import type { SessionId, TurnId } from "../ids/runtime-id";
|
|
|
2
2
|
|
|
3
3
|
export const MEMORY_SEARCH_TOOL_NAME = "MemorySearch" as const;
|
|
4
4
|
export const MEMORY_GET_TOOL_NAME = "MemoryGet" as const;
|
|
5
|
+
export const MEMORY_CREATE_TOOL_NAME = "MemoryCreate" as const;
|
|
6
|
+
export const MEMORY_UPDATE_TOOL_NAME = "MemoryUpdate" as const;
|
|
7
|
+
export const MEMORY_DELETE_TOOL_NAME = "MemoryDelete" as const;
|
|
5
8
|
export const MEMORY_SCHEMA_VERSION = 2 as const;
|
|
6
9
|
export const MAX_MEMORY_TEXT_BYTES = 512;
|
|
7
10
|
export const MAX_MEMORY_SUMMARY_BYTES = 4_096;
|
|
@@ -112,6 +115,35 @@ export type StoredMemoryRecord = StoredMemorySummary & {
|
|
|
112
115
|
readonly sourceTurnId: string;
|
|
113
116
|
};
|
|
114
117
|
|
|
118
|
+
export type StoredMemoryMutationRecord = StoredMemoryRecord & {
|
|
119
|
+
readonly embedding: Float32Array;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export type MemoryUpdateStoreResult =
|
|
123
|
+
| {
|
|
124
|
+
readonly ok: true;
|
|
125
|
+
readonly memoryId: string;
|
|
126
|
+
}
|
|
127
|
+
| {
|
|
128
|
+
readonly ok: false;
|
|
129
|
+
readonly code: "memory_not_found";
|
|
130
|
+
}
|
|
131
|
+
| {
|
|
132
|
+
readonly ok: false;
|
|
133
|
+
readonly code: "memory_duplicate";
|
|
134
|
+
readonly conflictMemoryId: string;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export type MemoryDeleteStoreResult =
|
|
138
|
+
| {
|
|
139
|
+
readonly ok: true;
|
|
140
|
+
readonly memoryId: string;
|
|
141
|
+
}
|
|
142
|
+
| {
|
|
143
|
+
readonly ok: false;
|
|
144
|
+
readonly code: "memory_not_found";
|
|
145
|
+
};
|
|
146
|
+
|
|
115
147
|
export type MemoryExtractionRejectedCounts = {
|
|
116
148
|
readonly duplicate: number;
|
|
117
149
|
readonly secret: number;
|
|
@@ -175,10 +207,24 @@ export type MemoryGetDiagnostic = {
|
|
|
175
207
|
readonly ms: number;
|
|
176
208
|
};
|
|
177
209
|
|
|
210
|
+
export type MemoryMutationDiagnostic = {
|
|
211
|
+
readonly at: string;
|
|
212
|
+
readonly kind: "create" | "update" | "delete";
|
|
213
|
+
readonly outcome: "ok" | "failed" | "skipped";
|
|
214
|
+
readonly reason: string | null;
|
|
215
|
+
readonly workspace: string;
|
|
216
|
+
readonly sessionId: string;
|
|
217
|
+
readonly turnId: string;
|
|
218
|
+
readonly toolCallId: string;
|
|
219
|
+
readonly memoryId: string | null;
|
|
220
|
+
readonly ms: number;
|
|
221
|
+
};
|
|
222
|
+
|
|
178
223
|
export type MemoryDiagnostic =
|
|
179
224
|
| MemoryExtractionDiagnostic
|
|
180
225
|
| MemorySearchDiagnostic
|
|
181
226
|
| MemoryGetDiagnostic
|
|
227
|
+
| MemoryMutationDiagnostic
|
|
182
228
|
| MemoryInitDiagnostic;
|
|
183
229
|
|
|
184
230
|
export class MemoryError extends Error {
|