tinker-agent 2.1.0 → 2.2.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
CHANGED
|
@@ -5,6 +5,21 @@ All notable user-facing changes to Tinker are documented here. The project follo
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [2.2.0] - 2026-08-29
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Log raw vector cosine scores in `MemorySearch` diagnostics, making hybrid
|
|
13
|
+
recall ranking easier to inspect and tune.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Restyle the prompt-input footer status line with a muted color palette:
|
|
18
|
+
model name, workspace path, Git branch, and cache hit rate each get a soft
|
|
19
|
+
accent color, and normal-pressure context usage now renders in a cool gray
|
|
20
|
+
instead of plain dim. Red and yellow remain reserved for context-pressure
|
|
21
|
+
warnings.
|
|
22
|
+
|
|
8
23
|
## [2.1.0] - 2026-08-29
|
|
9
24
|
|
|
10
25
|
### Added
|
|
@@ -249,7 +264,8 @@ All notable user-facing changes to Tinker are documented here. The project follo
|
|
|
249
264
|
- First formal npm release under the `tinker-agent` package name with the `tinker`
|
|
250
265
|
executable.
|
|
251
266
|
|
|
252
|
-
[Unreleased]: https://github.com/ishowshao/tinker/compare/v2.
|
|
267
|
+
[Unreleased]: https://github.com/ishowshao/tinker/compare/v2.2.0...HEAD
|
|
268
|
+
[2.2.0]: https://github.com/ishowshao/tinker/releases/tag/v2.2.0
|
|
253
269
|
[2.1.0]: https://github.com/ishowshao/tinker/releases/tag/v2.1.0
|
|
254
270
|
[2.0.0]: https://github.com/ishowshao/tinker/releases/tag/v2.0.0
|
|
255
271
|
[1.11.0]: https://github.com/ishowshao/tinker/releases/tag/v1.11.0
|
package/package.json
CHANGED
package/src/memory/contracts.ts
CHANGED
|
@@ -14,6 +14,7 @@ export const MAX_MEMORY_KEYWORDS = 8;
|
|
|
14
14
|
export const MAX_MEMORY_KEYWORD_BYTES = 128;
|
|
15
15
|
export const MEMORY_RRF_K = 60;
|
|
16
16
|
export const MEMORY_EXTRACTION_QUEUE_CAPACITY = 64;
|
|
17
|
+
export const MEMORY_SEARCH_DIAGNOSTIC_VECTOR_SCORES_LIMIT = 10;
|
|
17
18
|
|
|
18
19
|
export type MemoryEmbeddingKind = "openai-compatible";
|
|
19
20
|
|
|
@@ -146,6 +147,7 @@ export type MemorySearchDiagnostic = {
|
|
|
146
147
|
readonly ftsReturned: number;
|
|
147
148
|
readonly degraded: MemoryRecallDegraded | null;
|
|
148
149
|
readonly scores: readonly number[];
|
|
150
|
+
readonly vectorScores: readonly number[];
|
|
149
151
|
readonly ms: number;
|
|
150
152
|
};
|
|
151
153
|
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
MEMORY_GET_TOOL_NAME,
|
|
22
22
|
MEMORY_RECALL_CANDIDATE_LIMIT,
|
|
23
23
|
MEMORY_RRF_K,
|
|
24
|
+
MEMORY_SEARCH_DIAGNOSTIC_VECTOR_SCORES_LIMIT,
|
|
24
25
|
MEMORY_SEARCH_LIMIT,
|
|
25
26
|
MEMORY_SEARCH_TOOL_NAME,
|
|
26
27
|
MemoryError,
|
|
@@ -470,6 +471,9 @@ export class MemoryCoordinator implements CompletedTurnHook {
|
|
|
470
471
|
ftsReturned: ftsMatches.length,
|
|
471
472
|
degraded,
|
|
472
473
|
scores: fused.map((match) => roundScore(match.score)),
|
|
474
|
+
vectorScores: vectorMatches
|
|
475
|
+
.slice(0, MEMORY_SEARCH_DIAGNOSTIC_VECTOR_SCORES_LIMIT)
|
|
476
|
+
.map((match) => roundScore(match.score)),
|
|
473
477
|
ms: elapsedMs(startedAt),
|
|
474
478
|
}),
|
|
475
479
|
);
|
|
@@ -688,6 +692,7 @@ function searchDiagnostic(input: {
|
|
|
688
692
|
readonly ftsReturned?: number;
|
|
689
693
|
readonly degraded?: MemoryRecallDegraded | null;
|
|
690
694
|
readonly scores?: readonly number[];
|
|
695
|
+
readonly vectorScores?: readonly number[];
|
|
691
696
|
readonly ms: number;
|
|
692
697
|
}): MemorySearchDiagnostic {
|
|
693
698
|
return Object.freeze({
|
|
@@ -704,6 +709,7 @@ function searchDiagnostic(input: {
|
|
|
704
709
|
ftsReturned: input.ftsReturned ?? 0,
|
|
705
710
|
degraded: input.degraded ?? null,
|
|
706
711
|
scores: Object.freeze([...(input.scores ?? [])]),
|
|
712
|
+
vectorScores: Object.freeze([...(input.vectorScores ?? [])]),
|
|
707
713
|
ms: input.ms,
|
|
708
714
|
});
|
|
709
715
|
}
|
|
@@ -741,30 +741,42 @@ export function PromptInput(props: PromptInputProps) {
|
|
|
741
741
|
</Box>
|
|
742
742
|
{showSuggestions ? null : (
|
|
743
743
|
<Box>
|
|
744
|
-
<Text
|
|
745
|
-
{props.modelName}
|
|
746
|
-
{props.reasoningEffort === undefined ? null :
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
744
|
+
<Text>
|
|
745
|
+
<Text color={FOOTER_COLORS.model}>{props.modelName}</Text>
|
|
746
|
+
{props.reasoningEffort === undefined ? null : (
|
|
747
|
+
<Text dimColor> {props.reasoningEffort}</Text>
|
|
748
|
+
)}
|
|
749
|
+
<Text dimColor> · </Text>
|
|
750
|
+
<Text color={FOOTER_COLORS.workspacePath}>
|
|
751
|
+
{formatWorkspacePath(props.workspaceRoot)}
|
|
752
|
+
</Text>
|
|
753
|
+
{props.gitBranch === undefined ? null : (
|
|
754
|
+
<>
|
|
755
|
+
<Text dimColor> · </Text>
|
|
756
|
+
<Text color={FOOTER_COLORS.gitBranch}>{props.gitBranch}</Text>
|
|
757
|
+
</>
|
|
758
|
+
)}
|
|
759
|
+
{state.phase.kind === "idle" ? null : (
|
|
760
|
+
<>
|
|
761
|
+
<Text dimColor> · </Text>
|
|
762
|
+
<Text dimColor>{phaseLabel(state.phase)}</Text>
|
|
763
|
+
</>
|
|
764
|
+
)}
|
|
765
|
+
{props.contextUsage === undefined ? null : (
|
|
766
|
+
<>
|
|
767
|
+
<Text dimColor> · </Text>
|
|
768
|
+
<Text color={contextColor(props.contextUsage.pressure)}>
|
|
769
|
+
{formatContextUsageLine(props.contextUsage)}
|
|
770
|
+
</Text>
|
|
771
|
+
</>
|
|
772
|
+
)}
|
|
773
|
+
{cacheRate === undefined ? null : (
|
|
774
|
+
<>
|
|
775
|
+
<Text dimColor> · </Text>
|
|
776
|
+
<Text color={FOOTER_COLORS.cacheRate}>{cacheRate}</Text>
|
|
777
|
+
</>
|
|
778
|
+
)}
|
|
750
779
|
</Text>
|
|
751
|
-
{props.contextUsage === undefined ? null : (
|
|
752
|
-
<>
|
|
753
|
-
<Text dimColor> · </Text>
|
|
754
|
-
<Text
|
|
755
|
-
color={contextColor(props.contextUsage.pressure)}
|
|
756
|
-
dimColor={props.contextUsage.pressure === "normal"}
|
|
757
|
-
>
|
|
758
|
-
{formatContextUsageLine(props.contextUsage)}
|
|
759
|
-
</Text>
|
|
760
|
-
</>
|
|
761
|
-
)}
|
|
762
|
-
{cacheRate === undefined ? null : (
|
|
763
|
-
<>
|
|
764
|
-
<Text dimColor> · </Text>
|
|
765
|
-
<Text dimColor>{cacheRate}</Text>
|
|
766
|
-
</>
|
|
767
|
-
)}
|
|
768
780
|
</Box>
|
|
769
781
|
)}
|
|
770
782
|
{showFileSuggestions ? (
|
|
@@ -962,14 +974,25 @@ function fileMentionReplacement(
|
|
|
962
974
|
: `${filePath} `;
|
|
963
975
|
}
|
|
964
976
|
|
|
977
|
+
// Decorative palette for the footer status line, kept muted so it reads
|
|
978
|
+
// softly against the dim separators. Red and yellow are deliberately
|
|
979
|
+
// excluded: they stay reserved for context-pressure warnings.
|
|
980
|
+
const FOOTER_COLORS = {
|
|
981
|
+
model: "#7b9cc4",
|
|
982
|
+
workspacePath: "#6fa8a8",
|
|
983
|
+
gitBranch: "#a08fbd",
|
|
984
|
+
cacheRate: "#7aa37e",
|
|
985
|
+
contextUsage: "#8a9199",
|
|
986
|
+
} as const;
|
|
987
|
+
|
|
965
988
|
function contextColor(
|
|
966
989
|
pressure: ContextUsageSnapshot["pressure"],
|
|
967
|
-
): "yellow" | "red" |
|
|
990
|
+
): "yellow" | "red" | typeof FOOTER_COLORS.contextUsage {
|
|
968
991
|
return pressure === "blocked"
|
|
969
992
|
? "red"
|
|
970
993
|
: pressure === "triggered"
|
|
971
994
|
? "yellow"
|
|
972
|
-
:
|
|
995
|
+
: FOOTER_COLORS.contextUsage;
|
|
973
996
|
}
|
|
974
997
|
|
|
975
998
|
function formatWorkspacePath(workspaceRoot: string): string {
|