tinker-agent 2.3.0 → 2.5.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.
@@ -1,6 +1,7 @@
1
1
  import type { ToolCall } from "../agent/types";
2
2
  import type { ImageAssetRef } from "../image/image-types";
3
- import type { SessionId } from "../ids/runtime-id";
3
+ import type { MessageId, SessionId } from "../ids/runtime-id";
4
+ import type { ContextUsageSource } from "../model/model-request-preflight";
4
5
  import type {
5
6
  RecallGetPage,
6
7
  RecallSearchFilters,
@@ -310,6 +311,85 @@ export type RecallGetRawResult =
310
311
 
311
312
  export type RecallRawResult = RecallSearchRawResult | RecallGetRawResult;
312
313
 
314
+ export type ContextMaintenancePressure = "normal" | "high" | "critical";
315
+
316
+ export type ContextSwapCandidate = {
317
+ candidateId: MessageId;
318
+ label: string;
319
+ ordinal: number;
320
+ savingsBytes: number;
321
+ };
322
+
323
+ export type ContextSwapScheduledCandidate = {
324
+ candidateId: MessageId;
325
+ savingsBytes: number;
326
+ };
327
+
328
+ export type ContextSwapRejectedCandidate = {
329
+ candidateId: MessageId;
330
+ reason: string;
331
+ };
332
+
333
+ type ContextMaintenanceFailure<TOperation extends "status" | "candidates" | "swap"> = {
334
+ ok: false;
335
+ operation: TOperation;
336
+ error: string;
337
+ };
338
+
339
+ export type ContextStatusRawResult =
340
+ | {
341
+ ok: true;
342
+ operation: "status";
343
+ usedInputTokens: number;
344
+ inputBudgetTokens: number;
345
+ pressure: ContextMaintenancePressure;
346
+ triggerTokens: number;
347
+ source: ContextUsageSource;
348
+ }
349
+ | ContextMaintenanceFailure<"status">;
350
+
351
+ export type ContextSwapCandidatesRawResult =
352
+ | {
353
+ ok: true;
354
+ operation: "candidates";
355
+ total: number;
356
+ candidates: readonly ContextSwapCandidate[];
357
+ }
358
+ | ContextMaintenanceFailure<"candidates">;
359
+
360
+ export type ContextSwapRawResult =
361
+ | {
362
+ ok: true;
363
+ operation: "swap";
364
+ scheduled: readonly ContextSwapScheduledCandidate[];
365
+ rejected: readonly ContextSwapRejectedCandidate[];
366
+ note: string;
367
+ }
368
+ | {
369
+ ok: false;
370
+ operation: "swap";
371
+ scheduled: readonly ContextSwapScheduledCandidate[];
372
+ rejected: readonly ContextSwapRejectedCandidate[];
373
+ error?: string;
374
+ };
375
+
376
+ export type ContextMaintenanceRawResult =
377
+ | ContextStatusRawResult
378
+ | ContextSwapCandidatesRawResult
379
+ | ContextSwapRawResult;
380
+
381
+ export type ContextMaintenanceHandle = {
382
+ status(call: ToolCall): Promise<ContextStatusRawResult>;
383
+ candidates(
384
+ call: ToolCall,
385
+ input: { readonly limit: number; readonly offset: number },
386
+ ): Promise<ContextSwapCandidatesRawResult>;
387
+ swap(
388
+ call: ToolCall,
389
+ input: { readonly candidateIds: readonly MessageId[] },
390
+ ): Promise<ContextSwapRawResult>;
391
+ };
392
+
313
393
  export type MemorySearchRawResult =
314
394
  | {
315
395
  ok: true;
@@ -425,6 +505,7 @@ export type ToolRawResultByKind = {
425
505
  web_search: WebSearchRawResult;
426
506
  web_fetch: WebFetchRawResult;
427
507
  recall: RecallRawResult;
508
+ context_maintenance: ContextMaintenanceRawResult;
428
509
  memory_search: MemorySearchRawResult;
429
510
  memory_get: MemoryGetRawResult;
430
511
  wait: WaitRawResult;
@@ -472,6 +553,7 @@ export function defineToolExecutor<TKind extends ToolRawResultKind>(
472
553
 
473
554
  export type ToolExecutionContext = {
474
555
  signal: AbortSignal;
556
+ contextMaintenance?: ContextMaintenanceHandle;
475
557
  confirmBashCommand?: (request: {
476
558
  command: string;
477
559
  reason: string;
@@ -170,6 +170,15 @@ export function reduceTuiProjection(
170
170
  }),
171
171
  );
172
172
  }
173
+ case "context.pressure_notice.sent":
174
+ return updateActiveTurn(state, event, policy, (turn) =>
175
+ appendTurnItem(turn, {
176
+ id: `turn-${event.turnId}-pressure-notice-${event.eventSequence}`,
177
+ label: "context notice",
178
+ text: `input pressure ${event.data.pressure} (${event.data.usedInputTokens}/${event.data.inputBudgetTokens} tokens) — model notified to self-manage`,
179
+ status: "text",
180
+ }),
181
+ );
173
182
  case "model.request.started":
174
183
  return updateActiveTurn(state, event, policy, (turn) =>
175
184
  event.data.attemptNumber === 1
@@ -883,6 +892,19 @@ function toolRawResultSummary(name: string, args: unknown, raw: ToolRawResult):
883
892
  return raw.mode === "search"
884
893
  ? `${base} -> ${raw.page.hits.length} historical match${raw.page.hits.length === 1 ? "" : "es"}`
885
894
  : `${base} -> ${raw.page.returnedBytes} historical bytes`;
895
+ case "context_maintenance":
896
+ if (!raw.ok) {
897
+ return raw.operation === "swap"
898
+ ? `${base} -> 0 scheduled, ${raw.rejected.length} rejected`
899
+ : base;
900
+ }
901
+ if (raw.operation === "status") {
902
+ return `${base} -> ${raw.pressure}, ${raw.usedInputTokens}/${raw.inputBudgetTokens} tokens`;
903
+ }
904
+ if (raw.operation === "candidates") {
905
+ return `${base} -> ${raw.candidates.length}/${raw.total} candidates`;
906
+ }
907
+ return `${base} -> ${raw.scheduled.length} scheduled, ${raw.rejected.length} rejected`;
886
908
  case "memory_search":
887
909
  if (!raw.ok) {
888
910
  return base;
@@ -980,6 +1002,7 @@ function toolRawResultBashDetail(raw: ToolRawResult): Pick<TimelineItem, "bash">
980
1002
  case "web_search":
981
1003
  case "web_fetch":
982
1004
  case "recall":
1005
+ case "context_maintenance":
983
1006
  case "memory_search":
984
1007
  case "memory_get":
985
1008
  case "wait":
@@ -1021,6 +1044,7 @@ function toolRawResultDiff(
1021
1044
  case "web_search":
1022
1045
  case "web_fetch":
1023
1046
  case "recall":
1047
+ case "context_maintenance":
1024
1048
  case "memory_search":
1025
1049
  case "memory_get":
1026
1050
  case "wait":