tinker-agent 1.0.65 → 1.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 +36 -0
- package/LICENSE +201 -0
- package/NOTICE +6 -0
- package/README.md +90 -9
- package/bin/tinker.js +39 -0
- package/node_modules/ansi-regex/index.d.ts +33 -0
- package/node_modules/ansi-regex/index.js +14 -0
- package/node_modules/ansi-regex/license +9 -0
- package/node_modules/ansi-regex/package.json +61 -0
- package/node_modules/ansi-regex/readme.md +66 -0
- package/node_modules/ansi-styles/index.d.ts +236 -0
- package/node_modules/ansi-styles/index.js +223 -0
- package/node_modules/ansi-styles/license +9 -0
- package/node_modules/ansi-styles/package.json +54 -0
- package/node_modules/ansi-styles/readme.md +173 -0
- package/node_modules/chalk/license +9 -0
- package/node_modules/chalk/package.json +83 -0
- package/node_modules/chalk/readme.md +297 -0
- package/node_modules/chalk/source/index.d.ts +325 -0
- package/node_modules/chalk/source/index.js +225 -0
- package/node_modules/chalk/source/utilities.js +33 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
- package/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
- package/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
- package/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
- package/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
- package/node_modules/character-entities/index.d.ts +6 -0
- package/node_modules/character-entities/index.js +2132 -0
- package/node_modules/character-entities/license +22 -0
- package/node_modules/character-entities/package.json +78 -0
- package/node_modules/character-entities/readme.md +152 -0
- package/node_modules/decode-named-character-reference/index.d.ts +13 -0
- package/node_modules/decode-named-character-reference/index.d.ts.map +1 -0
- package/node_modules/decode-named-character-reference/index.dom.d.ts +6 -0
- package/node_modules/decode-named-character-reference/index.dom.d.ts.map +1 -0
- package/node_modules/decode-named-character-reference/index.dom.js +32 -0
- package/node_modules/decode-named-character-reference/index.js +19 -0
- package/node_modules/decode-named-character-reference/license +22 -0
- package/node_modules/decode-named-character-reference/package.json +90 -0
- package/node_modules/decode-named-character-reference/readme.md +136 -0
- package/node_modules/get-east-asian-width/index.d.ts +60 -0
- package/node_modules/get-east-asian-width/index.js +30 -0
- package/node_modules/get-east-asian-width/license +9 -0
- package/node_modules/get-east-asian-width/lookup-data.js +21 -0
- package/node_modules/get-east-asian-width/lookup.js +138 -0
- package/node_modules/get-east-asian-width/package.json +71 -0
- package/node_modules/get-east-asian-width/readme.md +65 -0
- package/node_modules/get-east-asian-width/utilities.js +24 -0
- package/node_modules/has-flag/index.d.ts +39 -0
- package/node_modules/has-flag/index.js +8 -0
- package/node_modules/has-flag/license +9 -0
- package/node_modules/has-flag/package.json +49 -0
- package/node_modules/has-flag/readme.md +74 -0
- package/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
- package/node_modules/is-fullwidth-code-point/index.js +12 -0
- package/node_modules/is-fullwidth-code-point/license +9 -0
- package/node_modules/is-fullwidth-code-point/package.json +53 -0
- package/node_modules/is-fullwidth-code-point/readme.md +31 -0
- package/node_modules/markdansi/LICENSE +21 -0
- package/node_modules/markdansi/README.md +167 -0
- package/node_modules/markdansi/dist/ast.d.ts +99 -0
- package/node_modules/markdansi/dist/ast.js +1 -0
- package/node_modules/markdansi/dist/cli.d.ts +17 -0
- package/node_modules/markdansi/dist/cli.js +208 -0
- package/node_modules/markdansi/dist/hyperlink.d.ts +9 -0
- package/node_modules/markdansi/dist/hyperlink.js +26 -0
- package/node_modules/markdansi/dist/index.d.ts +10 -0
- package/node_modules/markdansi/dist/index.js +16 -0
- package/node_modules/markdansi/dist/parser.d.ts +2 -0
- package/node_modules/markdansi/dist/parser.js +205 -0
- package/node_modules/markdansi/dist/render.d.ts +9 -0
- package/node_modules/markdansi/dist/render.js +680 -0
- package/node_modules/markdansi/dist/stream.d.ts +39 -0
- package/node_modules/markdansi/dist/stream.js +192 -0
- package/node_modules/markdansi/dist/theme.d.ts +18 -0
- package/node_modules/markdansi/dist/theme.js +105 -0
- package/node_modules/markdansi/dist/types.d.ts +58 -0
- package/node_modules/markdansi/dist/types.js +1 -0
- package/node_modules/markdansi/dist/wrap.d.ts +10 -0
- package/node_modules/markdansi/dist/wrap.js +73 -0
- package/node_modules/markdansi/docs/spec.md +110 -0
- package/node_modules/markdansi/package.json +78 -0
- package/node_modules/markdansi/tsconfig.json +18 -0
- package/node_modules/marked/LICENSE +44 -0
- package/node_modules/marked/README.md +115 -0
- package/node_modules/marked/bin/main.js +284 -0
- package/node_modules/marked/bin/marked.js +16 -0
- package/node_modules/marked/lib/marked.d.ts +760 -0
- package/node_modules/marked/lib/marked.esm.js +77 -0
- package/node_modules/marked/lib/marked.esm.js.map +7 -0
- package/node_modules/marked/lib/marked.umd.js +79 -0
- package/node_modules/marked/lib/marked.umd.js.map +7 -0
- package/node_modules/marked/man/marked.1 +113 -0
- package/node_modules/marked/man/marked.1.md +93 -0
- package/node_modules/marked/package.json +103 -0
- package/node_modules/slice-ansi/index.d.ts +19 -0
- package/node_modules/slice-ansi/index.js +317 -0
- package/node_modules/slice-ansi/license +10 -0
- package/node_modules/slice-ansi/package.json +59 -0
- package/node_modules/slice-ansi/readme.md +55 -0
- package/node_modules/slice-ansi/tokenize-ansi.js +752 -0
- package/node_modules/string-width/index.d.ts +39 -0
- package/node_modules/string-width/index.js +203 -0
- package/node_modules/string-width/license +9 -0
- package/node_modules/string-width/package.json +65 -0
- package/node_modules/string-width/readme.md +66 -0
- package/node_modules/strip-ansi/index.d.ts +15 -0
- package/node_modules/strip-ansi/index.js +19 -0
- package/node_modules/strip-ansi/license +9 -0
- package/node_modules/strip-ansi/package.json +59 -0
- package/node_modules/strip-ansi/readme.md +37 -0
- package/node_modules/supports-color/browser.d.ts +1 -0
- package/node_modules/supports-color/browser.js +35 -0
- package/node_modules/supports-color/index.d.ts +55 -0
- package/node_modules/supports-color/index.js +202 -0
- package/node_modules/supports-color/license +9 -0
- package/node_modules/supports-color/package.json +64 -0
- package/node_modules/supports-color/readme.md +75 -0
- package/node_modules/supports-hyperlinks/browser.js +10 -0
- package/node_modules/supports-hyperlinks/index.d.ts +25 -0
- package/node_modules/supports-hyperlinks/index.js +163 -0
- package/node_modules/supports-hyperlinks/license +10 -0
- package/node_modules/supports-hyperlinks/package.json +47 -0
- package/node_modules/supports-hyperlinks/readme.md +45 -0
- package/package.json +41 -10
- package/patches/markdansi@0.3.2.patch +22 -2
- package/src/agent/context-builder.ts +24 -10
- package/src/agent/context-meter.ts +89 -5
- package/src/agent/loop.ts +107 -10
- package/src/agent/runtime-session.ts +1437 -82
- package/src/agent/session-ledger.ts +169 -29
- package/src/agent/types.ts +12 -1
- package/src/agent/user-prompt-projection.ts +62 -0
- package/src/cli/config.ts +57 -14
- package/src/cli/model-profiles.ts +124 -0
- package/src/cli/run-runner.ts +4 -1
- package/src/cli/tui-runner.tsx +68 -30
- package/src/context/compiled-context-hash.ts +1 -1
- package/src/context/compiled-context-validator.ts +92 -15
- package/src/context/context-automation-policy.ts +121 -0
- package/src/context/context-manager.ts +390 -11
- package/src/context/context-policy.ts +8 -0
- package/src/context/context-protocol-validator.ts +11 -1
- package/src/context/context-revision-compiler.ts +190 -27
- package/src/context/context-revision.ts +105 -19
- package/src/context/context-surface.ts +329 -0
- package/src/context/prefix-retirement-planner.ts +570 -0
- package/src/context/protocol-frame.ts +30 -3
- package/src/context/recall-retirement-contract.ts +27 -0
- package/src/context/swap-planner.ts +34 -10
- package/src/events/observation-text-log.ts +3 -3
- package/src/events/stdout-event-printer.ts +39 -3
- package/src/events/types.ts +172 -35
- package/src/ids/runtime-id.ts +6 -0
- package/src/ids/uuid-v7.ts +7 -0
- package/src/image/image-asset-store.ts +319 -0
- package/src/image/image-input-policy.ts +14 -0
- package/src/image/image-probe.ts +233 -0
- package/src/image/image-types.ts +262 -0
- package/src/instructions/project-instructions.ts +4 -1
- package/src/mcp/mcp-manager.ts +83 -19
- package/src/model/fake-model-client.ts +9 -1
- package/src/model/input-token-estimator.ts +25 -0
- package/src/model/model-client.ts +60 -0
- package/src/model/model-request-preflight.ts +1 -0
- package/src/model/moonshot-input-token-estimator.ts +107 -0
- package/src/model/openai-chat-mapping.ts +77 -1
- package/src/model/openai-chat-model-client.ts +389 -59
- package/src/model/openai-chat-stream.ts +272 -0
- package/src/model/prompt-prefix-hash.ts +2 -4
- package/src/model/token-estimator.ts +4 -0
- package/src/observation/observation-builder.ts +29 -0
- package/src/session/resume-projection.ts +94 -34
- package/src/session/session-catalog.ts +4 -4
- package/src/session/session-errors.ts +1 -1
- package/src/session/session-history-reader.ts +151 -4
- package/src/session/session-last-response-reader.ts +189 -0
- package/src/session/session-schema.ts +349 -35
- package/src/session/session-store.ts +3266 -255
- package/src/session/sqlite-session-ledger.ts +9 -4
- package/src/skills/skill-catalog.ts +182 -0
- package/src/skills/skill-context.ts +364 -0
- package/src/skills/skill-loader.ts +779 -0
- package/src/skills/skill-tool.ts +297 -0
- package/src/tools/edit.ts +51 -64
- package/src/tools/ensure-parent-directory.ts +6 -0
- package/src/tools/read.ts +2 -2
- package/src/tools/recall.ts +43 -40
- package/src/tools/registry.ts +24 -3
- package/src/tools/ripgrep.ts +3 -2
- package/src/tools/types.ts +43 -4
- package/src/tools/write.ts +20 -31
- package/src/tui/app.tsx +333 -96
- package/src/tui/clipboard.ts +5 -0
- package/src/tui/components/mcp-panel.tsx +28 -0
- package/src/tui/components/prompt-input.tsx +790 -257
- package/src/tui/components/skills-panel.tsx +31 -0
- package/src/tui/components/timeline.tsx +30 -1
- package/src/tui/event-store.ts +85 -2
- package/src/tui/file-mention.ts +234 -0
- package/src/tui/line-editor.ts +1 -0
- package/src/tui/project-slash-commands.ts +229 -0
- package/src/tui/prompt-draft.ts +510 -0
- package/src/tui/prompt-history.ts +294 -22
- package/src/tui/slash-commands.ts +46 -2
- package/src/tui/tui-session-controller.ts +110 -48
- package/src/tui/workspace-file-search.ts +94 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { InputTokenEstimate, InputTokenEstimator } from "./input-token-estimator";
|
|
2
|
+
import type { MaterializedModelRequest } from "./model-client";
|
|
3
|
+
import { IMAGE_INPUT_POLICY } from "../image/image-input-policy";
|
|
4
|
+
|
|
5
|
+
export class MoonshotInputTokenEstimator implements InputTokenEstimator {
|
|
6
|
+
readonly kind = "moonshot-estimate-token-count-v1";
|
|
7
|
+
readonly compatibility: InputTokenEstimator["compatibility"];
|
|
8
|
+
private readonly endpoint: string;
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
private readonly options: {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
baseURL: string;
|
|
14
|
+
model: string;
|
|
15
|
+
timeoutMs: number;
|
|
16
|
+
fetch?: typeof fetch;
|
|
17
|
+
},
|
|
18
|
+
) {
|
|
19
|
+
const base = new URL(
|
|
20
|
+
options.baseURL.endsWith("/") ? options.baseURL : `${options.baseURL}/`,
|
|
21
|
+
);
|
|
22
|
+
base.username = "";
|
|
23
|
+
base.password = "";
|
|
24
|
+
base.search = "";
|
|
25
|
+
base.hash = "";
|
|
26
|
+
const endpoint = new URL("tokenizers/estimate-token-count", base);
|
|
27
|
+
this.endpoint = endpoint.toString();
|
|
28
|
+
this.compatibility = Object.freeze({
|
|
29
|
+
kind: "moonshot-estimate-token-count-v1",
|
|
30
|
+
coverageVersion: "full-request-v1",
|
|
31
|
+
model: options.model,
|
|
32
|
+
endpoint: this.endpoint,
|
|
33
|
+
timeoutMs: options.timeoutMs,
|
|
34
|
+
maxRetries: 0,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async estimate(
|
|
39
|
+
request: MaterializedModelRequest,
|
|
40
|
+
options: { signal: AbortSignal },
|
|
41
|
+
): Promise<InputTokenEstimate> {
|
|
42
|
+
const chatPayload = requireRecord(request.payload, "materialized chat payload");
|
|
43
|
+
if (!Array.isArray(chatPayload.messages)) {
|
|
44
|
+
throw new Error("Materialized request has no token estimator messages.");
|
|
45
|
+
}
|
|
46
|
+
const payload = {
|
|
47
|
+
model: this.options.model,
|
|
48
|
+
messages: chatPayload.messages,
|
|
49
|
+
...(Array.isArray(chatPayload.tools) ? { tools: chatPayload.tools } : {}),
|
|
50
|
+
};
|
|
51
|
+
const body = JSON.stringify(payload);
|
|
52
|
+
const bodyBytes = Buffer.byteLength(body, "utf8");
|
|
53
|
+
if (bodyBytes > IMAGE_INPUT_POLICY.maxRequestBodyBytes) {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Token estimate request is ${bodyBytes} bytes; maximum is ${IMAGE_INPUT_POLICY.maxRequestBodyBytes}.`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const controller = new AbortController();
|
|
60
|
+
const timeout = setTimeout(
|
|
61
|
+
() => controller.abort(new Error("Token estimate timed out.")),
|
|
62
|
+
this.options.timeoutMs,
|
|
63
|
+
);
|
|
64
|
+
const onAbort = () => controller.abort(options.signal.reason);
|
|
65
|
+
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
66
|
+
try {
|
|
67
|
+
options.signal.throwIfAborted();
|
|
68
|
+
const response = await (this.options.fetch ?? fetch)(this.endpoint, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: {
|
|
71
|
+
authorization: `Bearer ${this.options.apiKey}`,
|
|
72
|
+
"content-type": "application/json",
|
|
73
|
+
},
|
|
74
|
+
body,
|
|
75
|
+
signal: controller.signal,
|
|
76
|
+
});
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new Error(`Token estimate endpoint returned HTTP ${response.status}.`);
|
|
79
|
+
}
|
|
80
|
+
const decoded: unknown = await response.json();
|
|
81
|
+
const root = requireRecord(decoded, "token estimate response");
|
|
82
|
+
if (root.error !== undefined && root.error !== null) {
|
|
83
|
+
throw new Error("Token estimate endpoint returned an error response.");
|
|
84
|
+
}
|
|
85
|
+
const data = requireRecord(root.data, "token estimate response data");
|
|
86
|
+
const inputTokens = data.total_tokens;
|
|
87
|
+
if (!Number.isSafeInteger(inputTokens) || (inputTokens as number) < 0) {
|
|
88
|
+
throw new Error("Token estimate response total_tokens is invalid.");
|
|
89
|
+
}
|
|
90
|
+
return Object.freeze({
|
|
91
|
+
inputTokens: inputTokens as number,
|
|
92
|
+
source: "provider_estimated",
|
|
93
|
+
coverage: "full_request",
|
|
94
|
+
});
|
|
95
|
+
} finally {
|
|
96
|
+
clearTimeout(timeout);
|
|
97
|
+
options.signal.removeEventListener("abort", onAbort);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function requireRecord(value: unknown, name: string): Record<string, unknown> {
|
|
103
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
104
|
+
throw new Error(`${name} must be an object.`);
|
|
105
|
+
}
|
|
106
|
+
return value as Record<string, unknown>;
|
|
107
|
+
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AgentMessage,
|
|
3
|
+
IterationIdentity,
|
|
4
|
+
ToolCall,
|
|
5
|
+
UserMessage,
|
|
6
|
+
} from "../agent/types";
|
|
2
7
|
import type { RuntimeSessionContext } from "../agent/runtime-session";
|
|
3
8
|
import type { ModelRequestOutput, ModelUsage } from "./model-client";
|
|
4
9
|
import type { ToolDefinition } from "../tools/types";
|
|
@@ -6,8 +11,20 @@ import type {
|
|
|
6
11
|
ChatCompletionAssistantMessageParam,
|
|
7
12
|
ChatCompletionMessageFunctionToolCall,
|
|
8
13
|
ChatCompletionMessageParam,
|
|
14
|
+
ChatCompletionContentPart,
|
|
9
15
|
ChatCompletionTool,
|
|
10
16
|
} from "openai/resources/chat/completions";
|
|
17
|
+
import {
|
|
18
|
+
parseImageAssetId,
|
|
19
|
+
validateUserMessage,
|
|
20
|
+
type ImageAssetId,
|
|
21
|
+
} from "../image/image-types";
|
|
22
|
+
|
|
23
|
+
const IMAGE_ASSET_URL_MARKER = Symbol("tinker.image-asset-url-marker");
|
|
24
|
+
|
|
25
|
+
export type ImageAssetUrlMarker = {
|
|
26
|
+
readonly [IMAGE_ASSET_URL_MARKER]: ImageAssetId;
|
|
27
|
+
};
|
|
11
28
|
|
|
12
29
|
type DeepSeekAssistantMessageParam = ChatCompletionAssistantMessageParam & {
|
|
13
30
|
reasoning_content?: string | null;
|
|
@@ -15,6 +32,7 @@ type DeepSeekAssistantMessageParam = ChatCompletionAssistantMessageParam & {
|
|
|
15
32
|
|
|
16
33
|
export type OpenAIChatMessageMappingOptions = {
|
|
17
34
|
includeReasoningContent?: boolean;
|
|
35
|
+
materializedImages?: ReadonlyMap<ImageAssetId, string>;
|
|
18
36
|
};
|
|
19
37
|
|
|
20
38
|
export function toOpenAIChatMessages(
|
|
@@ -47,10 +65,68 @@ export function toOpenAIChatMessages(
|
|
|
47
65
|
};
|
|
48
66
|
}
|
|
49
67
|
|
|
68
|
+
if (message.role === "user") {
|
|
69
|
+
return {
|
|
70
|
+
role: "user",
|
|
71
|
+
content: toOpenAIUserContent(message, options.materializedImages),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
50
75
|
return message;
|
|
51
76
|
});
|
|
52
77
|
}
|
|
53
78
|
|
|
79
|
+
export function toOpenAIUserContent(
|
|
80
|
+
message: UserMessage,
|
|
81
|
+
materializedImages?: ReadonlyMap<ImageAssetId, string>,
|
|
82
|
+
): string | ChatCompletionContentPart[] {
|
|
83
|
+
validateUserMessage(message);
|
|
84
|
+
const attachments = message.attachments;
|
|
85
|
+
if (attachments === undefined) {
|
|
86
|
+
return message.content;
|
|
87
|
+
}
|
|
88
|
+
return [
|
|
89
|
+
...attachments.flatMap((attachment): ChatCompletionContentPart[] => [
|
|
90
|
+
{ type: "text", text: `<image name=${attachment.label}>` },
|
|
91
|
+
{
|
|
92
|
+
type: "image_url",
|
|
93
|
+
image_url: {
|
|
94
|
+
url:
|
|
95
|
+
materializedImages === undefined
|
|
96
|
+
? (imageAssetUrlMarker(attachment.assetId) as unknown as string)
|
|
97
|
+
: requireMaterializedImage(materializedImages, attachment.assetId),
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{ type: "text", text: "</image>" },
|
|
101
|
+
]),
|
|
102
|
+
{ type: "text", text: message.content },
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function imageAssetUrlMarker(assetId: ImageAssetId): ImageAssetUrlMarker {
|
|
107
|
+
parseImageAssetId(assetId);
|
|
108
|
+
return Object.freeze({ [IMAGE_ASSET_URL_MARKER]: assetId });
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function parseImageAssetUrlMarker(value: unknown): ImageAssetId | undefined {
|
|
112
|
+
if (typeof value !== "object" || value === null) {
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
const assetId = (value as Partial<ImageAssetUrlMarker>)[IMAGE_ASSET_URL_MARKER];
|
|
116
|
+
return typeof assetId === "string" ? parseImageAssetId(assetId) : undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function requireMaterializedImage(
|
|
120
|
+
materializedImages: ReadonlyMap<ImageAssetId, string>,
|
|
121
|
+
assetId: ImageAssetId,
|
|
122
|
+
): string {
|
|
123
|
+
const dataUrl = materializedImages.get(assetId);
|
|
124
|
+
if (dataUrl === undefined) {
|
|
125
|
+
throw new Error(`Image asset ${assetId.slice(0, 12)}… was not materialized.`);
|
|
126
|
+
}
|
|
127
|
+
return dataUrl;
|
|
128
|
+
}
|
|
129
|
+
|
|
54
130
|
export function toOpenAIChatTools(
|
|
55
131
|
tools: readonly ToolDefinition[],
|
|
56
132
|
): ChatCompletionTool[] {
|