tinker-agent 1.0.65
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/README.md +173 -0
- package/package.json +78 -0
- package/patches/markdansi@0.3.2.patch +37 -0
- package/src/agent/context-builder.ts +43 -0
- package/src/agent/context-meter.ts +310 -0
- package/src/agent/loop.ts +525 -0
- package/src/agent/runtime-session.ts +1212 -0
- package/src/agent/session-ledger.ts +828 -0
- package/src/agent/turn-cancellation.ts +44 -0
- package/src/agent/types.ts +77 -0
- package/src/cli/config.ts +283 -0
- package/src/cli/index.ts +29 -0
- package/src/cli/model-profiles.ts +289 -0
- package/src/cli/run-runner.ts +107 -0
- package/src/cli/tui-runner.tsx +290 -0
- package/src/context/compiled-context-hash.ts +138 -0
- package/src/context/compiled-context-validator.ts +209 -0
- package/src/context/context-manager.ts +362 -0
- package/src/context/context-policy.ts +8 -0
- package/src/context/context-protocol-validator.ts +463 -0
- package/src/context/context-revision-compiler.ts +281 -0
- package/src/context/context-revision.ts +111 -0
- package/src/context/context-source.ts +30 -0
- package/src/context/context-swap-renderer.ts +272 -0
- package/src/context/protocol-frame.ts +240 -0
- package/src/context/swap-planner.ts +725 -0
- package/src/events/append-private-file.ts +16 -0
- package/src/events/bash-result-detail.ts +70 -0
- package/src/events/composite-event-sink.ts +82 -0
- package/src/events/event-sink.ts +16 -0
- package/src/events/jsonl-event-log.ts +13 -0
- package/src/events/observation-text-log.ts +195 -0
- package/src/events/stdout-event-printer.ts +396 -0
- package/src/events/types.ts +263 -0
- package/src/ids/runtime-id.ts +68 -0
- package/src/ids/uuid-v7.ts +5 -0
- package/src/instructions/project-instructions.ts +242 -0
- package/src/mcp/mcp-config.ts +144 -0
- package/src/mcp/mcp-manager.ts +216 -0
- package/src/mcp/mcp-tool-executor.ts +178 -0
- package/src/model/committed-prefix-auditor.ts +68 -0
- package/src/model/fake-model-client.ts +280 -0
- package/src/model/model-client.ts +64 -0
- package/src/model/model-context-profile.ts +134 -0
- package/src/model/model-request-preflight.ts +120 -0
- package/src/model/openai-chat-mapping.ts +444 -0
- package/src/model/openai-chat-model-client.ts +190 -0
- package/src/model/prompt-prefix-hash.ts +47 -0
- package/src/model/token-estimator.ts +148 -0
- package/src/observation/observation-builder.ts +481 -0
- package/src/session/resume-projection.ts +616 -0
- package/src/session/session-catalog.ts +270 -0
- package/src/session/session-errors.ts +121 -0
- package/src/session/session-history-reader.ts +535 -0
- package/src/session/session-lock.ts +291 -0
- package/src/session/session-schema.ts +741 -0
- package/src/session/session-store.ts +3067 -0
- package/src/session/sqlite-session-ledger.ts +153 -0
- package/src/tools/bash-task.ts +617 -0
- package/src/tools/bash.ts +450 -0
- package/src/tools/cwd-state.ts +22 -0
- package/src/tools/edit.ts +428 -0
- package/src/tools/file-diff.ts +116 -0
- package/src/tools/glob.ts +202 -0
- package/src/tools/grep.ts +550 -0
- package/src/tools/hash.ts +9 -0
- package/src/tools/path-safety.ts +33 -0
- package/src/tools/read.ts +319 -0
- package/src/tools/recall.ts +400 -0
- package/src/tools/registry.ts +213 -0
- package/src/tools/ripgrep.ts +220 -0
- package/src/tools/task-list.ts +59 -0
- package/src/tools/task-output-snapshot.ts +47 -0
- package/src/tools/task-output-tool.ts +62 -0
- package/src/tools/task-output.ts +159 -0
- package/src/tools/task-stop.ts +59 -0
- package/src/tools/task-tool-args.ts +29 -0
- package/src/tools/types.ts +330 -0
- package/src/tools/web-fetch/backend.ts +27 -0
- package/src/tools/web-fetch/browser-backend.ts +126 -0
- package/src/tools/web-fetch/exa-backend.ts +172 -0
- package/src/tools/web-fetch/index.ts +298 -0
- package/src/tools/web-fetch/local-backend.ts +267 -0
- package/src/tools/web-fetch/refiner.ts +78 -0
- package/src/tools/web-fetch/route.ts +95 -0
- package/src/tools/web-search.ts +300 -0
- package/src/tools/write.ts +244 -0
- package/src/tui/app.tsx +497 -0
- package/src/tui/components/assistant-markdown.tsx +47 -0
- package/src/tui/components/background-tasks.tsx +92 -0
- package/src/tui/components/bash-result-view.tsx +47 -0
- package/src/tui/components/context-status.tsx +127 -0
- package/src/tui/components/diff-view.tsx +151 -0
- package/src/tui/components/file-viewer.tsx +212 -0
- package/src/tui/components/footer.tsx +60 -0
- package/src/tui/components/header.tsx +21 -0
- package/src/tui/components/model-picker.tsx +142 -0
- package/src/tui/components/prompt-input.tsx +432 -0
- package/src/tui/components/resume-session-picker.tsx +273 -0
- package/src/tui/components/timeline.tsx +121 -0
- package/src/tui/context-format.ts +24 -0
- package/src/tui/event-store.ts +865 -0
- package/src/tui/git-branch.ts +23 -0
- package/src/tui/line-editor.ts +157 -0
- package/src/tui/prompt-history.ts +94 -0
- package/src/tui/slash-commands.ts +126 -0
- package/src/tui/tui-projection-policy.ts +35 -0
- package/src/tui/tui-projection-store.ts +123 -0
- package/src/tui/tui-session-controller.ts +170 -0
- package/src/tui/view-file.ts +122 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import type { MessageId, ProtocolFrameId, SessionId } from "../ids/runtime-id";
|
|
2
|
+
import { sha256, stableJsonStringify } from "../model/model-request-preflight";
|
|
3
|
+
import type { ToolRawResult } from "../tools/types";
|
|
4
|
+
import type {
|
|
5
|
+
AgentMessage,
|
|
6
|
+
AssistantMessage,
|
|
7
|
+
IterationIdentity,
|
|
8
|
+
ToolCall,
|
|
9
|
+
TurnIdentity,
|
|
10
|
+
} from "../agent/types";
|
|
11
|
+
|
|
12
|
+
export const TOOL_OBSERVATION_FORMAT = "tool-observation-v2" as const;
|
|
13
|
+
|
|
14
|
+
export type CanonicalMessageBase = {
|
|
15
|
+
readonly messageId: MessageId;
|
|
16
|
+
readonly sessionId: SessionId;
|
|
17
|
+
readonly frameId: ProtocolFrameId;
|
|
18
|
+
readonly ordinal: number;
|
|
19
|
+
readonly contentSha256: string;
|
|
20
|
+
readonly createdAt: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type CanonicalMessageRecord =
|
|
24
|
+
| (CanonicalMessageBase & {
|
|
25
|
+
readonly role: "system";
|
|
26
|
+
readonly content: string;
|
|
27
|
+
readonly origin: "runtime";
|
|
28
|
+
})
|
|
29
|
+
| (CanonicalMessageBase & {
|
|
30
|
+
readonly role: "user";
|
|
31
|
+
readonly turnId: TurnIdentity["turnId"];
|
|
32
|
+
readonly content: string;
|
|
33
|
+
readonly origin: "user";
|
|
34
|
+
})
|
|
35
|
+
| (CanonicalMessageBase & {
|
|
36
|
+
readonly role: "assistant";
|
|
37
|
+
readonly turnId: TurnIdentity["turnId"];
|
|
38
|
+
readonly iterationId: IterationIdentity["iterationId"];
|
|
39
|
+
readonly content: string | null;
|
|
40
|
+
readonly reasoningContent?: string | null;
|
|
41
|
+
readonly toolCalls?: readonly ToolCall[];
|
|
42
|
+
readonly provider: string;
|
|
43
|
+
readonly model: string;
|
|
44
|
+
readonly origin: "model";
|
|
45
|
+
})
|
|
46
|
+
| (CanonicalMessageBase & {
|
|
47
|
+
readonly role: "tool";
|
|
48
|
+
readonly turnId: TurnIdentity["turnId"];
|
|
49
|
+
readonly iterationId: IterationIdentity["iterationId"];
|
|
50
|
+
readonly toolCallId: ToolCall["toolCallId"];
|
|
51
|
+
readonly providerToolCallId: string;
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly content: string;
|
|
54
|
+
readonly origin: "tool" | "runtime";
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export type ProtocolFrame = {
|
|
58
|
+
readonly frameId: ProtocolFrameId;
|
|
59
|
+
readonly sessionId: SessionId;
|
|
60
|
+
readonly turnId?: TurnIdentity["turnId"];
|
|
61
|
+
readonly iterationId?: IterationIdentity["iterationId"];
|
|
62
|
+
readonly kind: "system" | "user" | "assistant_text" | "tool_exchange";
|
|
63
|
+
readonly state: "open" | "closed";
|
|
64
|
+
readonly firstOrdinal: number;
|
|
65
|
+
readonly lastOrdinal?: number;
|
|
66
|
+
readonly createdAt: string;
|
|
67
|
+
readonly closedAt?: string;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type SyntheticToolCompletionReason =
|
|
71
|
+
| "cancelled_active"
|
|
72
|
+
| "skipped_after_cancel"
|
|
73
|
+
| "failed_active"
|
|
74
|
+
| "skipped_after_failure"
|
|
75
|
+
| "interrupted_active"
|
|
76
|
+
| "skipped_after_interruption";
|
|
77
|
+
|
|
78
|
+
export type ToolCompletion =
|
|
79
|
+
| {
|
|
80
|
+
readonly kind: "returned";
|
|
81
|
+
readonly raw: ToolRawResult;
|
|
82
|
+
readonly rawSha256: string;
|
|
83
|
+
readonly observationFormat: typeof TOOL_OBSERVATION_FORMAT;
|
|
84
|
+
}
|
|
85
|
+
| {
|
|
86
|
+
readonly kind: "synthetic";
|
|
87
|
+
readonly reason: SyntheticToolCompletionReason;
|
|
88
|
+
readonly detail?: string;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export type ToolResultRecord = {
|
|
92
|
+
readonly sessionId: SessionId;
|
|
93
|
+
readonly frameId: ProtocolFrameId;
|
|
94
|
+
readonly toolCallId: ToolCall["toolCallId"];
|
|
95
|
+
readonly toolMessageId: MessageId;
|
|
96
|
+
readonly completion: ToolCompletion;
|
|
97
|
+
readonly observationSha256: string;
|
|
98
|
+
readonly createdAt: string;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export type ProtocolContextView = {
|
|
102
|
+
readonly sessionId: SessionId;
|
|
103
|
+
readonly faulted: boolean;
|
|
104
|
+
readonly frames: readonly ProtocolFrame[];
|
|
105
|
+
readonly messages: readonly CanonicalMessageRecord[];
|
|
106
|
+
readonly toolResults: readonly ToolResultRecord[];
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export type ReturnedToolCompletionInput = {
|
|
110
|
+
readonly call: ToolCall;
|
|
111
|
+
readonly kind: "returned";
|
|
112
|
+
readonly raw: ToolRawResult;
|
|
113
|
+
readonly observation: string;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export type SyntheticToolCompletionInput = {
|
|
117
|
+
readonly call: ToolCall;
|
|
118
|
+
readonly kind: "synthetic";
|
|
119
|
+
readonly reason: SyntheticToolCompletionReason;
|
|
120
|
+
readonly detail?: string;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export type ToolCompletionInput =
|
|
124
|
+
| ReturnedToolCompletionInput
|
|
125
|
+
| SyntheticToolCompletionInput;
|
|
126
|
+
|
|
127
|
+
export function contentHash(content: string | null): string {
|
|
128
|
+
return sha256(stableJsonStringify({ content }));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function rawResultHash(raw: ToolRawResult): string {
|
|
132
|
+
return sha256(stableJsonStringify(raw));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function canonicalClone<T>(value: T): T {
|
|
136
|
+
return JSON.parse(stableJsonStringify(value)) as T;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function immutableCanonicalClone<T>(value: T): T {
|
|
140
|
+
return deepFreeze(canonicalClone(value));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function immutableRecord<T extends object>(value: T): Readonly<T> {
|
|
144
|
+
return deepFreeze(value);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function materializeAgentMessages(
|
|
148
|
+
records: readonly CanonicalMessageRecord[],
|
|
149
|
+
): AgentMessage[] {
|
|
150
|
+
return records.map((record): AgentMessage => {
|
|
151
|
+
switch (record.role) {
|
|
152
|
+
case "system":
|
|
153
|
+
case "user":
|
|
154
|
+
return { role: record.role, content: record.content };
|
|
155
|
+
case "assistant": {
|
|
156
|
+
const message: AssistantMessage = {
|
|
157
|
+
role: "assistant",
|
|
158
|
+
content: record.content,
|
|
159
|
+
...(record.reasoningContent === undefined
|
|
160
|
+
? {}
|
|
161
|
+
: { reasoningContent: record.reasoningContent }),
|
|
162
|
+
...(record.toolCalls === undefined
|
|
163
|
+
? {}
|
|
164
|
+
: { toolCalls: canonicalClone(record.toolCalls) }),
|
|
165
|
+
};
|
|
166
|
+
return message;
|
|
167
|
+
}
|
|
168
|
+
case "tool":
|
|
169
|
+
return {
|
|
170
|
+
role: "tool",
|
|
171
|
+
toolCallId: record.toolCallId,
|
|
172
|
+
providerToolCallId: record.providerToolCallId,
|
|
173
|
+
name: record.name,
|
|
174
|
+
content: record.content,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function renderSyntheticToolObservation(
|
|
181
|
+
reason: SyntheticToolCompletionReason,
|
|
182
|
+
detail?: string,
|
|
183
|
+
): string {
|
|
184
|
+
switch (reason) {
|
|
185
|
+
case "cancelled_active":
|
|
186
|
+
return "Tool execution was cancelled by the user. Side effects may have partially completed; inspect current state before retrying.";
|
|
187
|
+
case "skipped_after_cancel":
|
|
188
|
+
return "Tool call was skipped because the user cancelled the turn.";
|
|
189
|
+
case "failed_active":
|
|
190
|
+
return `Tool execution failed: ${requireSyntheticDetail(detail)}. Side effects may have partially completed; inspect current state before retrying.`;
|
|
191
|
+
case "skipped_after_failure":
|
|
192
|
+
return "Tool call was skipped because an earlier tool call failed.";
|
|
193
|
+
case "interrupted_active":
|
|
194
|
+
return "Tinker was interrupted while this tool call may have been running. Its side-effect state is unknown; inspect current state before retrying.";
|
|
195
|
+
case "skipped_after_interruption":
|
|
196
|
+
return "Tool call was skipped because Tinker was interrupted before it could run.";
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export function normalizeSyntheticDetail(error: unknown): string {
|
|
201
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
202
|
+
const normalized = detail.trim();
|
|
203
|
+
if (normalized === "") {
|
|
204
|
+
return "Unknown error";
|
|
205
|
+
}
|
|
206
|
+
return normalized.slice(0, 2_000);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function interruptedCompletionInputs(
|
|
210
|
+
calls: readonly ToolCall[],
|
|
211
|
+
): readonly SyntheticToolCompletionInput[] {
|
|
212
|
+
return calls.map((call, index) => ({
|
|
213
|
+
call,
|
|
214
|
+
kind: "synthetic",
|
|
215
|
+
reason: index === 0 ? "interrupted_active" : "skipped_after_interruption",
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function observationForCompletion(input: ToolCompletionInput): string {
|
|
220
|
+
return input.kind === "returned"
|
|
221
|
+
? input.observation
|
|
222
|
+
: renderSyntheticToolObservation(input.reason, input.detail);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function requireSyntheticDetail(detail: string | undefined): string {
|
|
226
|
+
if (detail === undefined || detail.trim() === "") {
|
|
227
|
+
throw new Error("failed_active synthetic completion requires error detail.");
|
|
228
|
+
}
|
|
229
|
+
return detail;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function deepFreeze<T>(value: T): T {
|
|
233
|
+
if (typeof value !== "object" || value === null || Object.isFrozen(value)) {
|
|
234
|
+
return value;
|
|
235
|
+
}
|
|
236
|
+
for (const child of Object.values(value)) {
|
|
237
|
+
deepFreeze(child);
|
|
238
|
+
}
|
|
239
|
+
return Object.freeze(value);
|
|
240
|
+
}
|