@markusylisiurunen/tau 0.3.46 → 0.3.48
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 +57 -6
- package/dist/code_mode/command.d.ts +2 -0
- package/dist/code_mode/command.js +33 -0
- package/dist/code_mode/command.js.map +1 -0
- package/dist/code_mode/files.d.ts +47 -0
- package/dist/code_mode/files.js +296 -0
- package/dist/code_mode/files.js.map +1 -0
- package/dist/code_mode/index.d.ts +6 -0
- package/dist/code_mode/index.js +5 -0
- package/dist/code_mode/index.js.map +1 -0
- package/dist/code_mode/runtime.d.ts +86 -0
- package/dist/code_mode/runtime.js +342 -0
- package/dist/code_mode/runtime.js.map +1 -0
- package/dist/core/agent/agent_runtime.js +0 -10
- package/dist/core/agent/agent_runtime.js.map +1 -1
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/runtime/chat_runtime.js +5 -8
- package/dist/core/runtime/chat_runtime.js.map +1 -1
- package/dist/core/session/direct_bash.js +6 -1
- package/dist/core/session/direct_bash.js.map +1 -1
- package/dist/core/static/code_mode/history/documentation.md +1 -12
- package/dist/core/static/code_mode/history/sandbox_runner.mjs +1 -111
- package/dist/core/static/code_mode/nook/documentation.md +2 -15
- package/dist/core/static/code_mode/nook/sandbox_runner.mjs +1 -147
- package/dist/core/static/code_mode/sandbox_runner.mjs +191 -0
- package/dist/core/static/code_mode/web/documentation.md +1 -13
- package/dist/core/static/code_mode/web/sandbox_runner.mjs +1 -115
- package/dist/core/telegram/config.js +34 -11
- package/dist/core/telegram/config.js.map +1 -1
- package/dist/core/telegram/session_manager.js +48 -14
- package/dist/core/telegram/session_manager.js.map +1 -1
- package/dist/core/telegram/workspace.js +24 -0
- package/dist/core/telegram/workspace.js.map +1 -1
- package/dist/core/tools/bash.js +1 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/code_mode.js +52 -47
- package/dist/core/tools/code_mode.js.map +1 -1
- package/dist/core/tools/code_mode_worker.js +43 -12
- package/dist/core/tools/code_mode_worker.js.map +1 -1
- package/dist/core/tools/history.js +17 -26
- package/dist/core/tools/history.js.map +1 -1
- package/dist/core/tools/nook.js +36 -23
- package/dist/core/tools/nook.js.map +1 -1
- package/dist/core/tools/presentation.js +36 -20
- package/dist/core/tools/presentation.js.map +1 -1
- package/dist/core/tools/send_input_to_agent.js +1 -1
- package/dist/core/tools/send_input_to_agent.js.map +1 -1
- package/dist/core/tools/spawn_agent.js +1 -1
- package/dist/core/tools/spawn_agent.js.map +1 -1
- package/dist/core/tools/subagent_ui.js +1 -1
- package/dist/core/tools/subagent_ui.js.map +1 -1
- package/dist/core/tools/web.js +19 -23
- package/dist/core/tools/web.js.map +1 -1
- package/dist/core/tools/write.js +6 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/utils/spawn_capture.js +34 -21
- package/dist/core/utils/spawn_capture.js.map +1 -1
- package/dist/core/version.js +1 -1
- package/dist/host/client_tool_broker.js +9 -1
- package/dist/host/client_tool_broker.js.map +1 -1
- package/dist/host/local_session_host.js +3 -17
- package/dist/host/local_session_host.js.map +1 -1
- package/dist/nook/README.md +1 -1
- package/dist/protocol/session_protocol.d.ts +2 -1
- package/dist/protocol/session_protocol.js +2 -1
- package/dist/protocol/session_protocol.js.map +1 -1
- package/dist/sdk/client_tool_command.d.ts +80 -0
- package/dist/sdk/client_tool_command.js +417 -0
- package/dist/sdk/client_tool_command.js.map +1 -0
- package/dist/sdk/code_mode.d.ts +6 -0
- package/dist/sdk/code_mode.js +60 -0
- package/dist/sdk/code_mode.js.map +1 -0
- package/dist/sdk/index.d.ts +5 -1
- package/dist/sdk/index.js +3 -0
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/session.js +52 -39
- package/dist/sdk/session.js.map +1 -1
- package/dist/sdk/types.d.ts +15 -9
- package/dist/store/file_session_store.js +0 -8
- package/dist/store/file_session_store.js.map +1 -1
- package/dist/store/memory_session_store.js +0 -4
- package/dist/store/memory_session_store.js.map +1 -1
- package/dist/store/session_store.js.map +1 -1
- package/dist/tui/chat_controller/diff_review_service.js +2 -2
- package/dist/tui/chat_controller/diff_review_service.js.map +1 -1
- package/dist/tui/command_client_tools.js +163 -23
- package/dist/tui/command_client_tools.js.map +1 -1
- package/dist/tui/session_chat_app.js +1 -1
- package/dist/tui/session_chat_app.js.map +1 -1
- package/dist/tui/session_chat_controller.js +9 -5
- package/dist/tui/session_chat_controller.js.map +1 -1
- package/dist/tui/session_tool_execution_backend.js +2 -2
- package/dist/tui/session_tool_execution_backend.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -174,7 +174,7 @@ The runner keeps tool and lifecycle progress quiet: Telegram receives command ac
|
|
|
174
174
|
|
|
175
175
|
Telegram DM input supports plain text, voice/audio transcription with the transcript echoed back for verification, and attachment queueing (`image/*`, PDF, `.txt`, `.md`, `.json`, `.csv`, `.yaml`, `.yml`). allowed groups are opt-in via `allowedChatIds`; non-triggering group text/captions, attachments, audio transcripts, and processing errors are buffered as sender-attributed context and the most recent 50 messages since the previous bot-triggering turn are included when a bot mention triggers a turn. group commands accept explicit bot mentions on or around the command, such as `/status@botusername`, `/status @botusername`, or `@botusername /status`.
|
|
176
176
|
|
|
177
|
-
Telegram config defines `bots`, `projects`, `workspaceRoot`, optional `systemMessage`, and optional `maxSessions`. Projects may describe one repository or compose several repository projects under a generated multi-repo root. Repositories use persistent bare caches at `<workspaceRoot>-repo-cache/<projectId>.git`; active and failed session records and per-chat project preferences are persisted, workspaces survive runner restarts, and unreferenced workspace entries are removed on startup. Tau reconnects preserved active sessions to their corresponding snapshots and reconciles unresolved Telegram requests through the durable turn ledger. Accepted running turns remain interruptible after a lost response, while failed, blocked, or confirmed-unaccepted request notifications remain persisted until Telegram delivery succeeds. Terminal failed records retain the initiating submission diagnostic until the session is closed. When creating or reconstructing a workspace, Telegram starts an optional executable `.tau/scripts/provision`
|
|
177
|
+
Telegram config defines `bots`, `projects`, `workspaceRoot`, optional `systemMessage`, and optional `maxSessions`. Projects may describe one repository, reuse one existing persistent directory across sessions, or compose several repository projects under a generated multi-repo root. Persistent directories must already exist and are never created, provisioned, or removed by Tau. Repositories use persistent bare caches at `<workspaceRoot>-repo-cache/<projectId>.git`; active and failed session records and per-chat project preferences are persisted, workspaces survive runner restarts, and unreferenced managed workspace entries are removed on startup. Tau reconnects preserved active sessions to their corresponding snapshots and reconciles unresolved Telegram requests through the durable turn ledger. Accepted running turns remain interruptible after a lost response, while failed, blocked, or confirmed-unaccepted request notifications remain persisted until Telegram delivery succeeds. Terminal failed records retain the initiating submission diagnostic until the session is closed. When creating or reconstructing a repository workspace, Telegram starts an optional executable `.tau/scripts/provision` hook through the Tau session without blocking chat access; failures are reported while the session remains available. Preserved workspaces skip provisioning on restart. for config details, see [docs/telegram.md](docs/telegram.md).
|
|
178
178
|
|
|
179
179
|
## built-in tool commands
|
|
180
180
|
|
|
@@ -669,24 +669,75 @@ A project or nested directory can select a different exact set without defining
|
|
|
669
669
|
|
|
670
670
|
The most specific `.tau/config.json` selection wins. Unknown names are skipped, and `enabledClientTools: []` disables every configured command client tool for that workspace.
|
|
671
671
|
|
|
672
|
-
For every call, Tau validates the arguments against the configured schema, starts the command directly without a shell, and
|
|
672
|
+
For every call, Tau validates the arguments against the configured schema, starts the command directly without a shell, and speaks a version 3 newline-delimited JSON protocol over stdin and stdout. The initial stdin frame contains the invocation:
|
|
673
673
|
|
|
674
674
|
```json
|
|
675
675
|
{
|
|
676
|
-
"version":
|
|
676
|
+
"version": 3,
|
|
677
|
+
"type": "invoke",
|
|
677
678
|
"sessionId": "session-id",
|
|
679
|
+
"agentId": "agent-id",
|
|
678
680
|
"callId": "call-id",
|
|
679
681
|
"arguments": { "message": "Build finished" }
|
|
680
682
|
}
|
|
681
683
|
```
|
|
682
684
|
|
|
683
|
-
|
|
685
|
+
Commands may send `exec` frames to run commands in the session execution environment. Tau returns the ordinary `session.exec` result in a matching `exec.result` stdin frame. The command finishes with one stdout result frame:
|
|
684
686
|
|
|
685
687
|
```json
|
|
686
|
-
{ "content": "Notification shown." }
|
|
688
|
+
{ "version": 3, "type": "result", "content": "Notification shown." }
|
|
687
689
|
```
|
|
688
690
|
|
|
689
|
-
|
|
691
|
+
Use `runTauClientToolCommand()` from `@markusylisiurunen/tau/sdk` or `@markusylisiurunen/tau/code-mode` to handle this framing and receive the same `{ sessionId, agentId, callId, signal, executionEnvironment }` context as an in-process SDK client tool. The command itself still runs on the TUI machine; only `context.executionEnvironment.exec()` runs through `session.exec` in the session execution environment.
|
|
692
|
+
|
|
693
|
+
The result `content` becomes model-visible. A nonzero exit fails the tool using stderr. Tau runs the command from the TUI's current working directory with the TUI process environment unchanged. Command stdout is decoded as a bounded NDJSON protocol stream with at most 512 frames and 192 MiB total per invocation; each frame is capped at 24 MiB, `exec` stdin retains the session protocol's 16 MiB decoded limit, and final result content plus stderr are each capped at 1 MiB. Tau allows at most eight execution requests to remain active while their responses are delivered with stdin backpressure, and terminates the command's process group on cancellation, terminal transport failure, timeout, or excess output. Closing protocol stdin aborts the command helper and its pending execution requests. Process-group termination escalates to `SIGKILL` after two seconds even if the command leader exits first. `executionTimeoutMs` defaults to 60 seconds.
|
|
694
|
+
|
|
695
|
+
```ts
|
|
696
|
+
#!/usr/bin/env node
|
|
697
|
+
import { runTauClientToolCommand } from "@markusylisiurunen/tau/sdk";
|
|
698
|
+
|
|
699
|
+
await runTauClientToolCommand(async (args, context) => {
|
|
700
|
+
const status = await context.executionEnvironment.exec("git status --short");
|
|
701
|
+
return { content: status.output || "working tree clean" };
|
|
702
|
+
});
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
Tau's `@markusylisiurunen/tau/code-mode` export implements this command framing plus the same isolated one-shot JavaScript runtime used by Tau's built-in code-mode tools. A code-mode command remains an ordinary configured client tool with the exact `{ code: string }` schema and a complete author-controlled description:
|
|
706
|
+
|
|
707
|
+
```json
|
|
708
|
+
{
|
|
709
|
+
"name": "linear",
|
|
710
|
+
"defaultEnabled": true,
|
|
711
|
+
"description": "Search Linear issues. When this tool is useful, your first call must be a documentation-only program that does nothing except print docs with console.log(docs). Read the returned documentation before writing a later tool call that uses linear. Do not guess API signatures.",
|
|
712
|
+
"parameters": {
|
|
713
|
+
"type": "object",
|
|
714
|
+
"properties": { "code": { "type": "string" } },
|
|
715
|
+
"required": ["code"],
|
|
716
|
+
"additionalProperties": false
|
|
717
|
+
},
|
|
718
|
+
"command": ".config/tau/tools/linear"
|
|
719
|
+
}
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
The executable owns authenticated clients and explicitly exposes trusted handlers. Handler arguments and results cross a JSON boundary; generated code receives the declared namespace, agent-scoped `files`, `docs`, `console`, `Date`, and `Math`:
|
|
723
|
+
|
|
724
|
+
```ts
|
|
725
|
+
#!/usr/bin/env node
|
|
726
|
+
import { runTauCodeModeCommand } from "@markusylisiurunen/tau/code-mode";
|
|
727
|
+
|
|
728
|
+
await runTauCodeModeCommand({
|
|
729
|
+
name: "linear",
|
|
730
|
+
documentation:
|
|
731
|
+
"# Linear API\n\nUse `linear.issues.get(id)` to read an issue.",
|
|
732
|
+
api: {
|
|
733
|
+
issues: {
|
|
734
|
+
get: async ([id], { signal }) => linearClient.issue(id, { signal }),
|
|
735
|
+
},
|
|
736
|
+
},
|
|
737
|
+
});
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
Trusted code-mode API handlers receive the command's execution-environment facade in their context and may intentionally expose narrower workspace operations through the declared API. Generated code does not receive an undeclared shell namespace. Its `files.read()`, `files.write()`, `files.list()`, and `files.remove()` methods operate on UTF-8 files in an agent-scoped execution-environment temporary directory. The files are shared across code-mode tools and later calls for that agent, and returned absolute paths are usable by Bash. Names are basenames rather than paths; `files.write()` rejects changes above 128 regular files or 64 MiB total, while Bash-created over-limit contents remain visible and removable. The execution environment's temporary filesystem controls the lifetime, and no scratch metadata enters the session snapshot. Tau prepends canonical runtime guidance to the executable's API documentation. The installed runtime therefore documents its actual capabilities, 60-second default timeout, 8,192-token output projection, 128-call total limit, and eight-call concurrency limit without duplicating those details in `config.json`. The optional `buildTauCodeModeToolDescription()` helper produces the recommended progressive-disclosure description, but descriptions are otherwise passed through unchanged.
|
|
690
741
|
|
|
691
742
|
Configured names must be unique and cannot replace built-in TUI or host tools. Only one observing client may advertise a given name for a session. `--no-client-tools` disables command client tools together with `diff_review` and `prefill_input`.
|
|
692
743
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { runTauClientToolCommand } from "../sdk/client_tool_command.js";
|
|
2
|
+
import { createTauCodeModeExecutionEnvironmentFiles, executeTauCodeMode, validateTauCodeModeDefinition, } from "./runtime.js";
|
|
3
|
+
export async function runTauCodeModeCommand(definition) {
|
|
4
|
+
validateTauCodeModeDefinition(definition);
|
|
5
|
+
await runTauClientToolCommand(async (args, context) => {
|
|
6
|
+
const code = parseCodeArguments(args);
|
|
7
|
+
return await executeTauCodeMode({
|
|
8
|
+
...definition,
|
|
9
|
+
code,
|
|
10
|
+
signal: context.signal,
|
|
11
|
+
invocation: {
|
|
12
|
+
sessionId: context.sessionId,
|
|
13
|
+
agentId: context.agentId,
|
|
14
|
+
callId: context.callId,
|
|
15
|
+
},
|
|
16
|
+
executionEnvironment: context.executionEnvironment,
|
|
17
|
+
files: createTauCodeModeExecutionEnvironmentFiles(context.agentId, context.executionEnvironment),
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function parseCodeArguments(value) {
|
|
22
|
+
if (typeof value !== "object" || value === null) {
|
|
23
|
+
throw new Error("code-mode command arguments must be an object");
|
|
24
|
+
}
|
|
25
|
+
const args = value;
|
|
26
|
+
if (typeof args.code !== "string" ||
|
|
27
|
+
!args.code.trim() ||
|
|
28
|
+
Object.keys(args).some((key) => key !== "code")) {
|
|
29
|
+
throw new Error("code-mode command arguments must contain exactly one non-empty 'code' string");
|
|
30
|
+
}
|
|
31
|
+
return args.code;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/code_mode/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EACL,0CAA0C,EAC1C,kBAAkB,EAElB,6BAA6B,GAC9B,MAAM,cAAc,CAAC;AAEtB,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,UAAiC;IAC3E,6BAA6B,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,uBAAuB,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QACpD,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACtC,OAAO,MAAM,kBAAkB,CAAC;YAC9B,GAAG,UAAU;YACb,IAAI;YACJ,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE;gBACV,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB;YACD,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;YAClD,KAAK,EAAE,0CAA0C,CAC/C,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,oBAAoB,CAC7B;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,IAAI,GAAG,KAAgC,CAAC;IAC9C,IACE,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;QAC7B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QACjB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,MAAM,CAAC,EAC/C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;IAClG,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export declare const TAU_CODE_MODE_MAX_FILES = 128;
|
|
2
|
+
export declare const TAU_CODE_MODE_MAX_TOTAL_FILE_BYTES: number;
|
|
3
|
+
export type TauCodeModeFileAdapterResult = {
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
exitCode: number | null;
|
|
7
|
+
};
|
|
8
|
+
export type TauCodeModeFileAdapter = {
|
|
9
|
+
runNodeScript(script: string, options: {
|
|
10
|
+
input: string;
|
|
11
|
+
signal: AbortSignal;
|
|
12
|
+
maxCaptureBytes: number;
|
|
13
|
+
}): Promise<TauCodeModeFileAdapterResult>;
|
|
14
|
+
};
|
|
15
|
+
export type TauCodeModeFilesOptions = {
|
|
16
|
+
agentId: string;
|
|
17
|
+
adapter: TauCodeModeFileAdapter;
|
|
18
|
+
};
|
|
19
|
+
export type TauCodeModeFileMetadata = {
|
|
20
|
+
name: string;
|
|
21
|
+
path: string;
|
|
22
|
+
bytes: number;
|
|
23
|
+
};
|
|
24
|
+
export type TauCodeModeFileList = {
|
|
25
|
+
files: TauCodeModeFileMetadata[];
|
|
26
|
+
totalFiles: number;
|
|
27
|
+
totalBytes: number;
|
|
28
|
+
};
|
|
29
|
+
export declare function createTauCodeModeFilesApi(options: TauCodeModeFilesOptions): {
|
|
30
|
+
read: (args: unknown[], context: {
|
|
31
|
+
signal: AbortSignal;
|
|
32
|
+
}) => Promise<string>;
|
|
33
|
+
write: (args: unknown[], context: {
|
|
34
|
+
signal: AbortSignal;
|
|
35
|
+
}) => Promise<{
|
|
36
|
+
path: string;
|
|
37
|
+
bytes: number;
|
|
38
|
+
}>;
|
|
39
|
+
list: (args: unknown[], context: {
|
|
40
|
+
signal: AbortSignal;
|
|
41
|
+
}) => Promise<TauCodeModeFileList>;
|
|
42
|
+
remove: (args: unknown[], context: {
|
|
43
|
+
signal: AbortSignal;
|
|
44
|
+
}) => Promise<{
|
|
45
|
+
path: string;
|
|
46
|
+
}>;
|
|
47
|
+
};
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { CODE_MODE_MAX_BRIDGE_PAYLOAD_BYTES } from "../core/tools/code_mode_worker.js";
|
|
2
|
+
export const TAU_CODE_MODE_MAX_FILES = 128;
|
|
3
|
+
export const TAU_CODE_MODE_MAX_TOTAL_FILE_BYTES = 64 * 1024 * 1024;
|
|
4
|
+
const FILE_COMMAND_MAX_CAPTURE_BYTES = 8 * 1024 * 1024;
|
|
5
|
+
export function createTauCodeModeFilesApi(options) {
|
|
6
|
+
if (!options.agentId)
|
|
7
|
+
throw new Error("code-mode files agentId must not be empty");
|
|
8
|
+
let operationQueue = Promise.resolve();
|
|
9
|
+
const execute = (request, signal) => {
|
|
10
|
+
const operation = operationQueue.then(() => executeScratchFileRequest(options.adapter, request, signal));
|
|
11
|
+
operationQueue = operation.then(() => undefined, () => undefined);
|
|
12
|
+
return operation;
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
read: async (args, context) => {
|
|
16
|
+
const [name] = parseArguments(args, ["string"], "files.read");
|
|
17
|
+
return await execute({ operation: "read", agentId: options.agentId, name }, context.signal);
|
|
18
|
+
},
|
|
19
|
+
write: async (args, context) => {
|
|
20
|
+
const [name, content] = parseArguments(args, ["string", "string"], "files.write");
|
|
21
|
+
return await execute({
|
|
22
|
+
operation: "write",
|
|
23
|
+
agentId: options.agentId,
|
|
24
|
+
name,
|
|
25
|
+
content,
|
|
26
|
+
}, context.signal);
|
|
27
|
+
},
|
|
28
|
+
list: async (args, context) => {
|
|
29
|
+
parseArguments(args, [], "files.list");
|
|
30
|
+
return await execute({ operation: "list", agentId: options.agentId }, context.signal);
|
|
31
|
+
},
|
|
32
|
+
remove: async (args, context) => {
|
|
33
|
+
const [name] = parseArguments(args, ["string"], "files.remove");
|
|
34
|
+
return await execute({
|
|
35
|
+
operation: "remove",
|
|
36
|
+
agentId: options.agentId,
|
|
37
|
+
name,
|
|
38
|
+
}, context.signal);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function parseArguments(args, types, method) {
|
|
43
|
+
if (args.length !== types.length || args.some((value) => typeof value !== "string")) {
|
|
44
|
+
const signature = types.map((type, index) => `${index === 0 ? "name" : "content"}: ${type}`);
|
|
45
|
+
throw new TypeError(`${method} expects (${signature.join(", ")})`);
|
|
46
|
+
}
|
|
47
|
+
return args;
|
|
48
|
+
}
|
|
49
|
+
async function executeScratchFileRequest(adapter, request, signal) {
|
|
50
|
+
const result = await adapter.runNodeScript(SCRATCH_FILE_SCRIPT, {
|
|
51
|
+
input: JSON.stringify(request),
|
|
52
|
+
signal,
|
|
53
|
+
maxCaptureBytes: FILE_COMMAND_MAX_CAPTURE_BYTES,
|
|
54
|
+
});
|
|
55
|
+
if (result.exitCode !== 0) {
|
|
56
|
+
throw new Error(result.stderr.trim() || "code-mode scratch file operation failed");
|
|
57
|
+
}
|
|
58
|
+
let response;
|
|
59
|
+
try {
|
|
60
|
+
response = JSON.parse(result.stdout);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
throw new Error("code-mode scratch file operation returned invalid JSON");
|
|
64
|
+
}
|
|
65
|
+
if (!isScratchFileResponse(response)) {
|
|
66
|
+
throw new Error("code-mode scratch file operation returned an invalid response");
|
|
67
|
+
}
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
const error = new Error(response.error.message);
|
|
70
|
+
error.name = response.error.name;
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
return response.value;
|
|
74
|
+
}
|
|
75
|
+
function isScratchFileResponse(value) {
|
|
76
|
+
if (typeof value !== "object" || value === null || !("ok" in value))
|
|
77
|
+
return false;
|
|
78
|
+
const response = value;
|
|
79
|
+
if (response.ok === true)
|
|
80
|
+
return "value" in response;
|
|
81
|
+
if (response.ok !== false || typeof response.error !== "object" || response.error === null) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const error = response.error;
|
|
85
|
+
return typeof error.name === "string" && typeof error.message === "string";
|
|
86
|
+
}
|
|
87
|
+
const SCRATCH_FILE_SCRIPT = String.raw `
|
|
88
|
+
const {
|
|
89
|
+
closeSync,
|
|
90
|
+
constants,
|
|
91
|
+
fstatSync,
|
|
92
|
+
fsyncSync,
|
|
93
|
+
lstatSync,
|
|
94
|
+
mkdirSync,
|
|
95
|
+
openSync,
|
|
96
|
+
readFileSync,
|
|
97
|
+
readdirSync,
|
|
98
|
+
renameSync,
|
|
99
|
+
unlinkSync,
|
|
100
|
+
writeFileSync,
|
|
101
|
+
} = require("node:fs");
|
|
102
|
+
const { createHash, randomUUID } = require("node:crypto");
|
|
103
|
+
const { tmpdir } = require("node:os");
|
|
104
|
+
const { join } = require("node:path");
|
|
105
|
+
const { TextDecoder } = require("node:util");
|
|
106
|
+
|
|
107
|
+
const MAX_NAME_BYTES = 255;
|
|
108
|
+
const MAX_OPERATION_BYTES = ${CODE_MODE_MAX_BRIDGE_PAYLOAD_BYTES};
|
|
109
|
+
const MAX_FILES = ${TAU_CODE_MODE_MAX_FILES};
|
|
110
|
+
const MAX_TOTAL_BYTES = ${TAU_CODE_MODE_MAX_TOTAL_FILE_BYTES};
|
|
111
|
+
|
|
112
|
+
function fail(message) {
|
|
113
|
+
throw new Error(message);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function validateName(name) {
|
|
117
|
+
const bytes = Buffer.byteLength(name, "utf8");
|
|
118
|
+
if (
|
|
119
|
+
bytes === 0 ||
|
|
120
|
+
bytes > MAX_NAME_BYTES ||
|
|
121
|
+
name === "." ||
|
|
122
|
+
name === ".." ||
|
|
123
|
+
name.includes("/") ||
|
|
124
|
+
name.includes("\\") ||
|
|
125
|
+
name.includes("\0")
|
|
126
|
+
) {
|
|
127
|
+
fail("scratch file name must be a UTF-8 basename between 1 and 255 bytes");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function ensureOwnedDirectory(path, label) {
|
|
132
|
+
try {
|
|
133
|
+
mkdirSync(path, { mode: 0o700 });
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (error?.code !== "EEXIST") throw error;
|
|
136
|
+
}
|
|
137
|
+
const stats = lstatSync(path);
|
|
138
|
+
if (stats.isSymbolicLink() || !stats.isDirectory()) {
|
|
139
|
+
fail(label + " path is not a directory");
|
|
140
|
+
}
|
|
141
|
+
if (typeof process.getuid !== "function" || stats.uid !== process.getuid()) {
|
|
142
|
+
fail(label + " directory is not owned by the current user");
|
|
143
|
+
}
|
|
144
|
+
if ((stats.mode & 0o077) !== 0) {
|
|
145
|
+
fail(label + " directory permissions must not allow group or other access");
|
|
146
|
+
}
|
|
147
|
+
return path;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function getRoot(agentId) {
|
|
151
|
+
if (typeof agentId !== "string" || agentId.length === 0) fail("agentId must not be empty");
|
|
152
|
+
const scope = createHash("sha256").update(agentId).digest("hex").slice(0, 32);
|
|
153
|
+
return ensureOwnedDirectory(join(tmpdir(), "tau-code-mode-files-" + scope), "code-mode scratch");
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function getStagingRoot(root) {
|
|
157
|
+
return ensureOwnedDirectory(root + "-staging", "code-mode scratch staging");
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function getFilePath(root, name) {
|
|
161
|
+
validateName(name);
|
|
162
|
+
return join(root, name);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function getExistingFile(path) {
|
|
166
|
+
let stats;
|
|
167
|
+
try {
|
|
168
|
+
stats = lstatSync(path);
|
|
169
|
+
} catch (error) {
|
|
170
|
+
if (error?.code === "ENOENT") return undefined;
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
if (stats.isSymbolicLink() || !stats.isFile()) fail("scratch path is not a regular file");
|
|
174
|
+
return stats;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function listFiles(root) {
|
|
178
|
+
const files = [];
|
|
179
|
+
for (const name of readdirSync(root)) {
|
|
180
|
+
const path = join(root, name);
|
|
181
|
+
const stats = lstatSync(path);
|
|
182
|
+
if (stats.isSymbolicLink() || !stats.isFile()) continue;
|
|
183
|
+
files.push({ name, path, bytes: stats.size });
|
|
184
|
+
}
|
|
185
|
+
files.sort((left, right) => left.name.localeCompare(right.name));
|
|
186
|
+
return files;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function read(root, name) {
|
|
190
|
+
const path = getFilePath(root, name);
|
|
191
|
+
const descriptor = openSync(
|
|
192
|
+
path,
|
|
193
|
+
constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK,
|
|
194
|
+
);
|
|
195
|
+
try {
|
|
196
|
+
const stats = fstatSync(descriptor);
|
|
197
|
+
if (!stats.isFile()) fail("scratch path is not a regular file");
|
|
198
|
+
if (stats.size > MAX_OPERATION_BYTES) {
|
|
199
|
+
fail("scratch file exceeds the 1 MiB read limit");
|
|
200
|
+
}
|
|
201
|
+
const content = readFileSync(descriptor);
|
|
202
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(content);
|
|
203
|
+
} finally {
|
|
204
|
+
closeSync(descriptor);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function write(root, name, content) {
|
|
209
|
+
if (typeof content !== "string") fail("scratch file content must be a string");
|
|
210
|
+
const bytes = Buffer.byteLength(content, "utf8");
|
|
211
|
+
if (bytes > MAX_OPERATION_BYTES) fail("scratch file exceeds the 1 MiB write limit");
|
|
212
|
+
|
|
213
|
+
const path = getFilePath(root, name);
|
|
214
|
+
const existing = getExistingFile(path);
|
|
215
|
+
const files = listFiles(root);
|
|
216
|
+
const totalBytes = files.reduce((total, file) => total + file.bytes, 0);
|
|
217
|
+
const resultingFiles = files.length + (existing ? 0 : 1);
|
|
218
|
+
const resultingBytes = totalBytes - (existing?.size ?? 0) + bytes;
|
|
219
|
+
if (resultingFiles > MAX_FILES) fail("scratch directory exceeds the 128-file limit");
|
|
220
|
+
if (resultingBytes > MAX_TOTAL_BYTES) fail("scratch directory exceeds the 64 MiB total limit");
|
|
221
|
+
|
|
222
|
+
const temporaryPath = join(getStagingRoot(root), ".tau-write-" + randomUUID());
|
|
223
|
+
let descriptor;
|
|
224
|
+
try {
|
|
225
|
+
descriptor = openSync(
|
|
226
|
+
temporaryPath,
|
|
227
|
+
constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW,
|
|
228
|
+
0o600,
|
|
229
|
+
);
|
|
230
|
+
writeFileSync(descriptor, content, "utf8");
|
|
231
|
+
fsyncSync(descriptor);
|
|
232
|
+
closeSync(descriptor);
|
|
233
|
+
descriptor = undefined;
|
|
234
|
+
renameSync(temporaryPath, path);
|
|
235
|
+
} finally {
|
|
236
|
+
if (descriptor !== undefined) closeSync(descriptor);
|
|
237
|
+
try {
|
|
238
|
+
unlinkSync(temporaryPath);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
if (error?.code !== "ENOENT") throw error;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return { path, bytes };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function list(root) {
|
|
247
|
+
const allFiles = listFiles(root);
|
|
248
|
+
return {
|
|
249
|
+
files: allFiles,
|
|
250
|
+
totalFiles: allFiles.length,
|
|
251
|
+
totalBytes: allFiles.reduce((total, file) => total + file.bytes, 0),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function remove(root, name) {
|
|
256
|
+
const path = getFilePath(root, name);
|
|
257
|
+
if (!getExistingFile(path)) fail("scratch file does not exist");
|
|
258
|
+
unlinkSync(path);
|
|
259
|
+
return { path };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function execute(request) {
|
|
263
|
+
if (typeof request !== "object" || request === null || typeof request.operation !== "string") {
|
|
264
|
+
fail("invalid scratch file request");
|
|
265
|
+
}
|
|
266
|
+
const root = getRoot(request.agentId);
|
|
267
|
+
switch (request.operation) {
|
|
268
|
+
case "read":
|
|
269
|
+
return read(root, request.name);
|
|
270
|
+
case "write":
|
|
271
|
+
return write(root, request.name, request.content);
|
|
272
|
+
case "list":
|
|
273
|
+
return list(root);
|
|
274
|
+
case "remove":
|
|
275
|
+
return remove(root, request.name);
|
|
276
|
+
default:
|
|
277
|
+
fail("unsupported scratch file operation");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
try {
|
|
282
|
+
const request = JSON.parse(readFileSync(0, "utf8"));
|
|
283
|
+
process.stdout.write(JSON.stringify({ ok: true, value: execute(request) }));
|
|
284
|
+
} catch (error) {
|
|
285
|
+
process.stdout.write(
|
|
286
|
+
JSON.stringify({
|
|
287
|
+
ok: false,
|
|
288
|
+
error: {
|
|
289
|
+
name: error instanceof Error ? error.name : "Error",
|
|
290
|
+
message: error instanceof Error ? error.message : String(error),
|
|
291
|
+
},
|
|
292
|
+
}),
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
`;
|
|
296
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/code_mode/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { runTauClientToolCommand, TAU_CLIENT_TOOL_COMMAND_PROTOCOL_VERSION, type TauClientToolCommandHandler, } from "../sdk/client_tool_command.js";
|
|
2
|
+
export { runTauCodeModeCommand } from "./command.js";
|
|
3
|
+
export type { TauCodeModeFileAdapter, TauCodeModeFileAdapterResult, TauCodeModeFileList, TauCodeModeFileMetadata, TauCodeModeFilesOptions, } from "./files.js";
|
|
4
|
+
export { TAU_CODE_MODE_MAX_FILES, TAU_CODE_MODE_MAX_TOTAL_FILE_BYTES, } from "./files.js";
|
|
5
|
+
export type { BuildTauCodeModeToolDescriptionOptions, ExecuteTauCodeModeOptions, TauCodeModeApi, TauCodeModeDefinition, TauCodeModeExecutionStatus, TauCodeModeHandler, TauCodeModeHandlerContext, TauCodeModeInvocation, TauCodeModeJsonValue, TauCodeModePersistOutput, TauCodeModeResult, } from "./runtime.js";
|
|
6
|
+
export { buildTauCodeModeToolDescription, executeTauCodeMode, TAU_CODE_MODE_DEFAULT_TIMEOUT_MS, TAU_CODE_MODE_MAX_OUTPUT_TOKENS, } from "./runtime.js";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { runTauClientToolCommand, TAU_CLIENT_TOOL_COMMAND_PROTOCOL_VERSION, } from "../sdk/client_tool_command.js";
|
|
2
|
+
export { runTauCodeModeCommand } from "./command.js";
|
|
3
|
+
export { TAU_CODE_MODE_MAX_FILES, TAU_CODE_MODE_MAX_TOTAL_FILE_BYTES, } from "./files.js";
|
|
4
|
+
export { buildTauCodeModeToolDescription, executeTauCodeMode, TAU_CODE_MODE_DEFAULT_TIMEOUT_MS, TAU_CODE_MODE_MAX_OUTPUT_TOKENS, } from "./runtime.js";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/code_mode/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EACvB,wCAAwC,GAEzC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAQrD,OAAO,EACL,uBAAuB,EACvB,kCAAkC,GACnC,MAAM,YAAY,CAAC;AAcpB,OAAO,EACL,+BAA+B,EAC/B,kBAAkB,EAClB,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { TauSdkClientToolExecutionEnvironment } from "../sdk/types.js";
|
|
2
|
+
import { type TauCodeModeFilesOptions } from "./files.js";
|
|
3
|
+
export declare const TAU_CODE_MODE_DEFAULT_TIMEOUT_MS = 60000;
|
|
4
|
+
export declare const TAU_CODE_MODE_MAX_OUTPUT_TOKENS = 8192;
|
|
5
|
+
export type TauCodeModeJsonValue = null | boolean | number | string | TauCodeModeJsonValue[] | {
|
|
6
|
+
[key: string]: TauCodeModeJsonValue;
|
|
7
|
+
};
|
|
8
|
+
export type TauCodeModeInvocation = {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
agentId: string;
|
|
11
|
+
callId: string;
|
|
12
|
+
};
|
|
13
|
+
export type TauCodeModeHandlerContext = {
|
|
14
|
+
signal: AbortSignal;
|
|
15
|
+
invocation: TauCodeModeInvocation | null;
|
|
16
|
+
executionEnvironment: TauSdkClientToolExecutionEnvironment | null;
|
|
17
|
+
};
|
|
18
|
+
export type TauCodeModeHandler = (args: unknown[], context: TauCodeModeHandlerContext) => unknown | Promise<unknown>;
|
|
19
|
+
export type TauCodeModeApi = {
|
|
20
|
+
[key: string]: TauCodeModeApi | TauCodeModeHandler;
|
|
21
|
+
};
|
|
22
|
+
export type TauCodeModeExecutionStatus = "succeeded" | "failed" | "timed-out" | "cancelled";
|
|
23
|
+
type TauCodeModeProjection = {
|
|
24
|
+
content: string;
|
|
25
|
+
truncated: boolean;
|
|
26
|
+
truncatedBy: "lines" | "bytes" | null;
|
|
27
|
+
totalLines: number;
|
|
28
|
+
totalBytes: number;
|
|
29
|
+
outputLines: number;
|
|
30
|
+
outputBytes: number;
|
|
31
|
+
maxLines: number;
|
|
32
|
+
maxTokens: number;
|
|
33
|
+
};
|
|
34
|
+
type TauCodeModeExecutionCapture = {
|
|
35
|
+
output: string;
|
|
36
|
+
stdout: string;
|
|
37
|
+
stderr: string;
|
|
38
|
+
exitCode: number | null;
|
|
39
|
+
truncated: boolean;
|
|
40
|
+
timedOut: boolean;
|
|
41
|
+
aborted: boolean;
|
|
42
|
+
closeSignal: string | null;
|
|
43
|
+
};
|
|
44
|
+
export type TauCodeModePersistOutput = (output: {
|
|
45
|
+
content: string;
|
|
46
|
+
captureTruncated: boolean;
|
|
47
|
+
contextTruncated: boolean;
|
|
48
|
+
status: TauCodeModeExecutionStatus;
|
|
49
|
+
}, context: TauCodeModeHandlerContext) => Promise<{
|
|
50
|
+
path: string;
|
|
51
|
+
} | undefined>;
|
|
52
|
+
export type TauCodeModeDefinition = {
|
|
53
|
+
name: string;
|
|
54
|
+
documentation: string;
|
|
55
|
+
api: TauCodeModeApi;
|
|
56
|
+
timeoutMs?: number;
|
|
57
|
+
persistOutput?: TauCodeModePersistOutput;
|
|
58
|
+
};
|
|
59
|
+
export type ExecuteTauCodeModeOptions = TauCodeModeDefinition & {
|
|
60
|
+
code: string;
|
|
61
|
+
signal?: AbortSignal;
|
|
62
|
+
invocation?: TauCodeModeInvocation | null;
|
|
63
|
+
executionEnvironment?: TauSdkClientToolExecutionEnvironment | null;
|
|
64
|
+
files?: TauCodeModeFilesOptions;
|
|
65
|
+
};
|
|
66
|
+
export type TauCodeModeResult = {
|
|
67
|
+
content: string;
|
|
68
|
+
};
|
|
69
|
+
export type BuildTauCodeModeToolDescriptionOptions = {
|
|
70
|
+
name: string;
|
|
71
|
+
description: string;
|
|
72
|
+
};
|
|
73
|
+
export declare function createTauCodeModeExecutionEnvironmentFiles(agentId: string, executionEnvironment: TauSdkClientToolExecutionEnvironment): TauCodeModeFilesOptions;
|
|
74
|
+
export type TauCodeModeRuntimeResult = {
|
|
75
|
+
result: TauCodeModeResult;
|
|
76
|
+
status: TauCodeModeExecutionStatus;
|
|
77
|
+
execution: TauCodeModeExecutionCapture;
|
|
78
|
+
durationMs: number;
|
|
79
|
+
projection: TauCodeModeProjection;
|
|
80
|
+
persistedPath?: string;
|
|
81
|
+
};
|
|
82
|
+
export declare function buildTauCodeModeToolDescription({ name, description, }: BuildTauCodeModeToolDescriptionOptions): string;
|
|
83
|
+
export declare function validateTauCodeModeDefinition(definition: TauCodeModeDefinition): void;
|
|
84
|
+
export declare function executeTauCodeMode(options: ExecuteTauCodeModeOptions): Promise<TauCodeModeResult>;
|
|
85
|
+
export declare function runTauCodeMode(options: ExecuteTauCodeModeOptions): Promise<TauCodeModeRuntimeResult>;
|
|
86
|
+
export {};
|