reeval 0.0.1
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/LICENSE +202 -0
- package/THIRD_PARTY_NOTICES.md +2160 -0
- package/assets/package.json +9 -0
- package/assets/pnpm-lock.yaml +1336 -0
- package/dist/agent-DVHkx8aT.js +532 -0
- package/dist/agent-DVHkx8aT.js.map +1 -0
- package/dist/analysis-CxSCt1YY.js +16 -0
- package/dist/analysis-CxSCt1YY.js.map +1 -0
- package/dist/assemble-B-nmz8oH.js +695 -0
- package/dist/assemble-B-nmz8oH.js.map +1 -0
- package/dist/assemble-CmRVDZ2Q.js +2 -0
- package/dist/attempt-BdRQ9jKX.js +176 -0
- package/dist/attempt-BdRQ9jKX.js.map +1 -0
- package/dist/bridge/index.mjs +1911 -0
- package/dist/bridge/package.json +13 -0
- package/dist/bridge/pnpm-lock.yaml +1041 -0
- package/dist/bridge/pnpm-workspace.yaml +2 -0
- package/dist/budget-DBUrH4jX.js +8 -0
- package/dist/budget-DBUrH4jX.js.map +1 -0
- package/dist/cli--CQ3Iy9q.js +1865 -0
- package/dist/cli--CQ3Iy9q.js.map +1 -0
- package/dist/cli-spec-DKAu09Gi.js +478 -0
- package/dist/cli-spec-DKAu09Gi.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -0
- package/dist/colors-QV9dFVhN.js +34 -0
- package/dist/colors-QV9dFVhN.js.map +1 -0
- package/dist/command-BSJzHMtP.js +280 -0
- package/dist/command-BSJzHMtP.js.map +1 -0
- package/dist/command-CEm8PZ1N.js +1043 -0
- package/dist/command-CEm8PZ1N.js.map +1 -0
- package/dist/command-D-jnQWVG.js +673 -0
- package/dist/command-D-jnQWVG.js.map +1 -0
- package/dist/command-DQAvbG7d.js +432 -0
- package/dist/command-DQAvbG7d.js.map +1 -0
- package/dist/commands-A4udfyKZ.js +2 -0
- package/dist/commands-CF8mOfiu.js +207 -0
- package/dist/commands-CF8mOfiu.js.map +1 -0
- package/dist/config-Cuj0kVYj.js +415 -0
- package/dist/config-Cuj0kVYj.js.map +1 -0
- package/dist/context-loi9OCZv.js +106 -0
- package/dist/context-loi9OCZv.js.map +1 -0
- package/dist/core-tLN-z1Be.js +96 -0
- package/dist/core-tLN-z1Be.js.map +1 -0
- package/dist/db-Cjj2ZsfQ.js +2 -0
- package/dist/db-DxDzMhtB.js +827 -0
- package/dist/db-DxDzMhtB.js.map +1 -0
- package/dist/debug-D24NOQH1.js +89 -0
- package/dist/debug-D24NOQH1.js.map +1 -0
- package/dist/debug-SEmW4w8f.js +2 -0
- package/dist/dist-BZXYHN2X.js +1673 -0
- package/dist/dist-BZXYHN2X.js.map +1 -0
- package/dist/docker-DQDZWXF9.js +20 -0
- package/dist/docker-DQDZWXF9.js.map +1 -0
- package/dist/docker-DnWAVdEm.js +2 -0
- package/dist/docker-oSbCExHL.js +153 -0
- package/dist/docker-oSbCExHL.js.map +1 -0
- package/dist/doctor-CxlH1pDM.js +525 -0
- package/dist/doctor-CxlH1pDM.js.map +1 -0
- package/dist/egress-73SQfKdx.js +619 -0
- package/dist/egress-73SQfKdx.js.map +1 -0
- package/dist/env-BQqj93gu.js +21 -0
- package/dist/env-BQqj93gu.js.map +1 -0
- package/dist/environment-Mz7wvrtD.js +552 -0
- package/dist/environment-Mz7wvrtD.js.map +1 -0
- package/dist/errors-C9w_ud7g.js +160 -0
- package/dist/errors-C9w_ud7g.js.map +1 -0
- package/dist/errors-CSxfJ4qu.js +11 -0
- package/dist/errors-CSxfJ4qu.js.map +1 -0
- package/dist/files--6CEUXm7.js +2 -0
- package/dist/files-BLlrhU4-.js +62 -0
- package/dist/files-BLlrhU4-.js.map +1 -0
- package/dist/files-Bd25OAQH.js +2 -0
- package/dist/files-BvHCFWgD.js +2 -0
- package/dist/files-D2-qn_Dl.js +275 -0
- package/dist/files-D2-qn_Dl.js.map +1 -0
- package/dist/files-bF2fPuT9.js +99 -0
- package/dist/files-bF2fPuT9.js.map +1 -0
- package/dist/git-D6hMeieS.js +44 -0
- package/dist/git-D6hMeieS.js.map +1 -0
- package/dist/harness-ls5aX1UO.js +131 -0
- package/dist/harness-ls5aX1UO.js.map +1 -0
- package/dist/harness.d.ts +74 -0
- package/dist/harness.js +2 -0
- package/dist/header-DzFDoMCI.js +78 -0
- package/dist/header-DzFDoMCI.js.map +1 -0
- package/dist/ids-Bp6ut7ZD.js +49 -0
- package/dist/ids-Bp6ut7ZD.js.map +1 -0
- package/dist/images-Cc1-coFc.js +286 -0
- package/dist/images-Cc1-coFc.js.map +1 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.js +1959 -0
- package/dist/index.js.map +1 -0
- package/dist/init-CFljS8BJ.js +344 -0
- package/dist/init-CFljS8BJ.js.map +1 -0
- package/dist/init-z2ZPn9Tj.js +2 -0
- package/dist/invocations-rXktgSAn.js +157 -0
- package/dist/invocations-rXktgSAn.js.map +1 -0
- package/dist/jiti-BOLXpKyG.js +46 -0
- package/dist/jiti-BOLXpKyG.js.map +1 -0
- package/dist/judge-D8Uf4dA9.js +146 -0
- package/dist/judge-D8Uf4dA9.js.map +1 -0
- package/dist/judge.d.ts +21 -0
- package/dist/judge.js +19 -0
- package/dist/judge.js.map +1 -0
- package/dist/live-Bs3LReMV.js +98 -0
- package/dist/live-Bs3LReMV.js.map +1 -0
- package/dist/matchers-DyLvm7EG.js +374 -0
- package/dist/matchers-DyLvm7EG.js.map +1 -0
- package/dist/model-BdO79gWz.js +44 -0
- package/dist/model-BdO79gWz.js.map +1 -0
- package/dist/model-CDL98xue.js +725 -0
- package/dist/model-CDL98xue.js.map +1 -0
- package/dist/model-v-0_Ik7S.js +2 -0
- package/dist/node-kG64XxdE.js +506 -0
- package/dist/node-kG64XxdE.js.map +1 -0
- package/dist/opencode-providers-DZuD_oYt.js +3149 -0
- package/dist/opencode-providers-DZuD_oYt.js.map +1 -0
- package/dist/options-CAQhu--C.js +452 -0
- package/dist/options-CAQhu--C.js.map +1 -0
- package/dist/patch-BkKje4cp.js +69 -0
- package/dist/patch-BkKje4cp.js.map +1 -0
- package/dist/paths-CBvm6pap.js +72 -0
- package/dist/paths-CBvm6pap.js.map +1 -0
- package/dist/plan-gwk6dJ8c.js +237 -0
- package/dist/plan-gwk6dJ8c.js.map +1 -0
- package/dist/preflight-BtubXKQ8.js +2 -0
- package/dist/preflight-BypZMNBG.js +185 -0
- package/dist/preflight-BypZMNBG.js.map +1 -0
- package/dist/prepare-Cwv0bHs_.js +3 -0
- package/dist/prepare-D6Uzcubb.js +213 -0
- package/dist/prepare-D6Uzcubb.js.map +1 -0
- package/dist/provenance-Dfb8YY5Y.js +129 -0
- package/dist/provenance-Dfb8YY5Y.js.map +1 -0
- package/dist/provider-BDbNOQhQ.js +2 -0
- package/dist/provider-CmAYTQQs.js +14 -0
- package/dist/provider-CmAYTQQs.js.map +1 -0
- package/dist/providers-2p3ylMHI.js +107 -0
- package/dist/providers-2p3ylMHI.js.map +1 -0
- package/dist/providers-BUOxitcT.js +2 -0
- package/dist/query-CFATHZmV.js +91 -0
- package/dist/query-CFATHZmV.js.map +1 -0
- package/dist/query-DR4m6CXf.js +2 -0
- package/dist/record-DQ8wzyco.js +99 -0
- package/dist/record-DQ8wzyco.js.map +1 -0
- package/dist/redact-C4fL_bZP.js +167 -0
- package/dist/redact-C4fL_bZP.js.map +1 -0
- package/dist/results-CeXb8Wde.js +37 -0
- package/dist/results-CeXb8Wde.js.map +1 -0
- package/dist/root-CFDjpWuc.js +110 -0
- package/dist/root-CFDjpWuc.js.map +1 -0
- package/dist/sandbox-By2gkdkC.js +133 -0
- package/dist/sandbox-By2gkdkC.js.map +1 -0
- package/dist/sandbox.d.ts +41 -0
- package/dist/sandbox.js +2 -0
- package/dist/server-Bi61uiY0.js +350 -0
- package/dist/server-Bi61uiY0.js.map +1 -0
- package/dist/server-CsSBL8NC.js +2 -0
- package/dist/source-BXzrmof5.js +2 -0
- package/dist/source-Bsfa3LZH.js +40 -0
- package/dist/source-Bsfa3LZH.js.map +1 -0
- package/dist/src-55j1zNHH.js +3 -0
- package/dist/src-AEwxd1UP.js +602 -0
- package/dist/src-AEwxd1UP.js.map +1 -0
- package/dist/src-BDwSuyIo.js +3 -0
- package/dist/src-BQyMiWri.js +490 -0
- package/dist/src-BQyMiWri.js.map +1 -0
- package/dist/src-C-LHyTSV.js +3 -0
- package/dist/src-Cmp-7YrD.js +1136 -0
- package/dist/src-Cmp-7YrD.js.map +1 -0
- package/dist/src-D0RdqpNb.js +252 -0
- package/dist/src-D0RdqpNb.js.map +1 -0
- package/dist/src-D8KYzxBX.js +793 -0
- package/dist/src-D8KYzxBX.js.map +1 -0
- package/dist/src-DEgff9Z7.js +4 -0
- package/dist/src-DXx_29pq.js +567 -0
- package/dist/src-DXx_29pq.js.map +1 -0
- package/dist/src-DwwiVLqv.js +2937 -0
- package/dist/src-DwwiVLqv.js.map +1 -0
- package/dist/src-N7E_mfcZ.js +2 -0
- package/dist/src-W9g-y5X5.js +3 -0
- package/dist/src-daS0wKH2.js +3 -0
- package/dist/state-Cyw3QTsN.js +2 -0
- package/dist/state-DZ7eqb1F.js +167 -0
- package/dist/state-DZ7eqb1F.js.map +1 -0
- package/dist/stats-BNAHlNMD.js +114 -0
- package/dist/stats-BNAHlNMD.js.map +1 -0
- package/dist/studio-app/assets/index-D6XyfFSH.js +58 -0
- package/dist/studio-app/assets/index-xwzWdcE_.css +2 -0
- package/dist/studio-app/favicon.svg +1 -0
- package/dist/studio-app/index.html +15 -0
- package/dist/summary-D7Ttky0z.js +166 -0
- package/dist/summary-D7Ttky0z.js.map +1 -0
- package/dist/text-gEcKjAyp.js +29 -0
- package/dist/text-gEcKjAyp.js.map +1 -0
- package/dist/types-C5vI3g1C.js +9 -0
- package/dist/types-C5vI3g1C.js.map +1 -0
- package/dist/types-DLec-6Cx.d.ts +1535 -0
- package/dist/usage-DsYUqIUM.js +24 -0
- package/dist/usage-DsYUqIUM.js.map +1 -0
- package/dist/view/index.d.ts +645 -0
- package/dist/view/index.js +8 -0
- package/dist/views-BrHOv6wg.js +220 -0
- package/dist/views-BrHOv6wg.js.map +1 -0
- package/dist/views-CwCWLWqo.js +3 -0
- package/dist/worker-entry-DnYkANPG.js +506 -0
- package/dist/worker-entry-DnYkANPG.js.map +1 -0
- package/dist/workspace-C2S0Z6gl.js +327 -0
- package/dist/workspace-C2S0Z6gl.js.map +1 -0
- package/dist/workspace-CyoXG6CY.js +2 -0
- package/docker/Dockerfile +19 -0
- package/package.json +79 -0
|
@@ -0,0 +1,793 @@
|
|
|
1
|
+
import { posix } from "node:path";
|
|
2
|
+
import { Readable } from "node:stream";
|
|
3
|
+
import { HarnessCapabilityUnsupportedError, commonTool, harnessSessionDataDirectoryPath, harnessStateDirectoryPath } from "@ai-sdk/harness";
|
|
4
|
+
import { createCredentialRequestTransformation, generateSandboxCredentialPlaceholder, isHarnessAuthenticationEnvironment, resolveSandboxHomeDir, shellQuote, warnCredentialBrokeringUnavailable, writeInstructions, writeSkills } from "@ai-sdk/harness/utils";
|
|
5
|
+
import { tool } from "@ai-sdk/provider-utils";
|
|
6
|
+
import { createInterface } from "node:readline";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
//#region ../harness-antigravity/src/antigravity-auth.ts
|
|
9
|
+
/** The only credential the adapter uses: a Gemini API key, for the CLI's `gemini` provider. */
|
|
10
|
+
const ANTIGRAVITY_CREDENTIAL_ENV = "GEMINI_API_KEY";
|
|
11
|
+
/** Overrides where the CLI sends Gemini API requests (and so where the key is brokered). */
|
|
12
|
+
const ANTIGRAVITY_BASE_URL_ENV = "GOOGLE_GEMINI_BASE_URL";
|
|
13
|
+
const GEMINI_API_URL = "https://generativelanguage.googleapis.com";
|
|
14
|
+
/** The header the CLI sends the key in. It never puts the key in the query string. */
|
|
15
|
+
const GEMINI_API_KEY_HEADER = "x-goog-api-key";
|
|
16
|
+
function resolveAntigravityCredentials(auth = "auto", hostEnv = process.env) {
|
|
17
|
+
if (auth !== "auto" && !isHarnessAuthenticationEnvironment(auth)) throw new Error(`Antigravity auth must be 'auto' or an environment object such as { ${ANTIGRAVITY_CREDENTIAL_ENV}: '…' } (got ${JSON.stringify(auth)})`);
|
|
18
|
+
const env = auth === "auto" ? hostEnv : auth;
|
|
19
|
+
const apiKey = env[ANTIGRAVITY_CREDENTIAL_ENV];
|
|
20
|
+
if (!apiKey) throw new Error(`${ANTIGRAVITY_CREDENTIAL_ENV} isn't set, so the Antigravity CLI can't authenticate. It needs a Gemini API key (Google AI Studio).`);
|
|
21
|
+
const baseUrl = env[ANTIGRAVITY_BASE_URL_ENV];
|
|
22
|
+
return {
|
|
23
|
+
apiKey,
|
|
24
|
+
...baseUrl ? { baseUrl } : {}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Swaps the sandbox's placeholder for the real key on requests to the Gemini API's host (under
|
|
29
|
+
* the base URL's path, when it has one). The rule is host-wide on purpose: a gateway that also
|
|
30
|
+
* enforces {@link antigravityEndpoints} can then refuse, loudly, a placeholder sent anywhere else.
|
|
31
|
+
*/
|
|
32
|
+
function createAntigravityRequestTransformations({ credentials, placeholder, headers }) {
|
|
33
|
+
return [createCredentialRequestTransformation({
|
|
34
|
+
matchUrl: credentials.baseUrl ?? "https://generativelanguage.googleapis.com",
|
|
35
|
+
matchHeaders: { [GEMINI_API_KEY_HEADER]: placeholder },
|
|
36
|
+
transformHeaders: {
|
|
37
|
+
...headers,
|
|
38
|
+
[GEMINI_API_KEY_HEADER]: credentials.apiKey
|
|
39
|
+
}
|
|
40
|
+
})];
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region ../harness-antigravity/src/antigravity-bootstrap.ts
|
|
44
|
+
/** The CLI build the bootstrap installs. Bump it with both checksums from the release. */
|
|
45
|
+
const ANTIGRAVITY_CLI_VERSION = "1.2.11";
|
|
46
|
+
const ANTIGRAVITY_CLI_SHA256 = {
|
|
47
|
+
x64: "c91c62c5e6fa954f5a7e1d7b9ad417d749db4aa60a4ba0b3d604dec1b645d190",
|
|
48
|
+
arm64: "01513bc61f9592353045ba801ebb407fbccb8984fcbfde591bc6b681b24e92bc"
|
|
49
|
+
};
|
|
50
|
+
/** Relative to the harness state directory, `$HOME/.ai-sdk-harness`. */
|
|
51
|
+
const ANTIGRAVITY_BOOTSTRAP_DIR = ".harness-bootstrap/antigravity";
|
|
52
|
+
/** The CLI's path relative to the bootstrap directory. */
|
|
53
|
+
const ANTIGRAVITY_CLI_PATH = "bin/agy";
|
|
54
|
+
const RELEASES = "https://github.com/google-antigravity/antigravity-cli/releases/download";
|
|
55
|
+
/**
|
|
56
|
+
* Downloads the pinned release for the sandbox's architecture, checks its sha256 and unpacks
|
|
57
|
+
* the single `antigravity` binary as `bin/agy`. The binary needs glibc (Debian, Ubuntu).
|
|
58
|
+
*/
|
|
59
|
+
function antigravityInstallScript(version = ANTIGRAVITY_CLI_VERSION) {
|
|
60
|
+
return `set -eu
|
|
61
|
+
case "$(uname -m)" in
|
|
62
|
+
x86_64|amd64) arch=x64; sha=${ANTIGRAVITY_CLI_SHA256.x64} ;;
|
|
63
|
+
aarch64|arm64) arch=arm64; sha=${ANTIGRAVITY_CLI_SHA256.arm64} ;;
|
|
64
|
+
*) echo "The Antigravity CLI has no Linux build for $(uname -m)" >&2; exit 1 ;;
|
|
65
|
+
esac
|
|
66
|
+
curl -fsSL --retry 3 -o agy.tar.gz "${RELEASES}/${version}/agy_cli_linux_$arch.tar.gz"
|
|
67
|
+
echo "$sha agy.tar.gz" | sha256sum -c - >/dev/null
|
|
68
|
+
rm -rf bin && mkdir bin
|
|
69
|
+
tar -xzf agy.tar.gz -C bin
|
|
70
|
+
mv bin/antigravity bin/agy
|
|
71
|
+
chmod 755 bin/agy
|
|
72
|
+
rm agy.tar.gz
|
|
73
|
+
`;
|
|
74
|
+
}
|
|
75
|
+
async function getAntigravityBootstrap() {
|
|
76
|
+
return {
|
|
77
|
+
harnessId: "antigravity",
|
|
78
|
+
bootstrapDir: ANTIGRAVITY_BOOTSTRAP_DIR,
|
|
79
|
+
files: [{
|
|
80
|
+
path: `${ANTIGRAVITY_BOOTSTRAP_DIR}/install.sh`,
|
|
81
|
+
content: antigravityInstallScript()
|
|
82
|
+
}],
|
|
83
|
+
commands: [{ command: "sh install.sh" }]
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region ../harness-antigravity/src/antigravity-command.ts
|
|
88
|
+
/**
|
|
89
|
+
* `allow-all` skips every approval. The CLI can't ask in print mode, so anything it would ask
|
|
90
|
+
* about is declined: `allow-edits` still edits (`accept-edits`) and `allow-reads` plans only.
|
|
91
|
+
*/
|
|
92
|
+
const PERMISSION_FLAGS = {
|
|
93
|
+
"allow-all": ["--dangerously-skip-permissions"],
|
|
94
|
+
"allow-edits": ["--mode", "accept-edits"],
|
|
95
|
+
"allow-reads": ["--mode", "plan"]
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* One headless turn: NDJSON events on stdout, the workspace added explicitly (without it, print
|
|
99
|
+
* mode can write into a scratch directory), slash commands off so a prompt starting with `/` is
|
|
100
|
+
* sent as text, and no print timeout (the caller owns cancellation). `-p` comes last.
|
|
101
|
+
*/
|
|
102
|
+
function buildAntigravityCommand(o) {
|
|
103
|
+
const args = [
|
|
104
|
+
"--output-format",
|
|
105
|
+
"stream-json",
|
|
106
|
+
"--add-dir",
|
|
107
|
+
o.workDir,
|
|
108
|
+
"--disable-slash-commands",
|
|
109
|
+
"--print-timeout",
|
|
110
|
+
"0",
|
|
111
|
+
...o.model ? ["--model", o.model] : [],
|
|
112
|
+
...o.effort ? ["--effort", o.effort] : [],
|
|
113
|
+
...PERMISSION_FLAGS[o.permissionMode ?? "allow-all"],
|
|
114
|
+
...o.conversationId ? ["--conversation", o.conversationId] : [],
|
|
115
|
+
...o.jsonSchemaFile ? ["--json-schema", o.jsonSchemaFile] : []
|
|
116
|
+
];
|
|
117
|
+
return `exec ${[o.cli, ...args].map(shellQuote).join(" ")} -p "$(cat ${shellQuote(o.promptFile)})"`;
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region ../harness-antigravity/src/antigravity-tools.ts
|
|
121
|
+
const native = (nativeName, title, toolUseKind) => ({
|
|
122
|
+
...tool({
|
|
123
|
+
title,
|
|
124
|
+
inputSchema: z.looseObject({})
|
|
125
|
+
}),
|
|
126
|
+
nativeName,
|
|
127
|
+
...toolUseKind ? { toolUseKind } : {}
|
|
128
|
+
});
|
|
129
|
+
const ANTIGRAVITY_BUILTIN_TOOLS = {
|
|
130
|
+
bash: {
|
|
131
|
+
...commonTool("bash", {
|
|
132
|
+
nativeName: "run_command",
|
|
133
|
+
toolUseKind: "bash",
|
|
134
|
+
inputSchema: z.looseObject({
|
|
135
|
+
command: z.string(),
|
|
136
|
+
Cwd: z.string().optional()
|
|
137
|
+
})
|
|
138
|
+
}),
|
|
139
|
+
title: "Run Command"
|
|
140
|
+
},
|
|
141
|
+
read: {
|
|
142
|
+
...commonTool("read", {
|
|
143
|
+
nativeName: "view_file",
|
|
144
|
+
toolUseKind: "readonly",
|
|
145
|
+
inputSchema: z.looseObject({ file_path: z.string() })
|
|
146
|
+
}),
|
|
147
|
+
title: "View File"
|
|
148
|
+
},
|
|
149
|
+
write: {
|
|
150
|
+
...commonTool("write", {
|
|
151
|
+
nativeName: "write_to_file",
|
|
152
|
+
toolUseKind: "edit",
|
|
153
|
+
inputSchema: z.looseObject({
|
|
154
|
+
file_path: z.string(),
|
|
155
|
+
content: z.string().optional()
|
|
156
|
+
})
|
|
157
|
+
}),
|
|
158
|
+
title: "Write File"
|
|
159
|
+
},
|
|
160
|
+
edit: {
|
|
161
|
+
...commonTool("edit", {
|
|
162
|
+
nativeName: "replace_file_content",
|
|
163
|
+
toolUseKind: "edit",
|
|
164
|
+
inputSchema: z.looseObject({
|
|
165
|
+
file_path: z.string(),
|
|
166
|
+
old_string: z.string().optional(),
|
|
167
|
+
new_string: z.string().optional()
|
|
168
|
+
})
|
|
169
|
+
}),
|
|
170
|
+
title: "Edit File"
|
|
171
|
+
},
|
|
172
|
+
grep: {
|
|
173
|
+
...commonTool("grep", {
|
|
174
|
+
nativeName: "grep_search",
|
|
175
|
+
toolUseKind: "readonly",
|
|
176
|
+
inputSchema: z.looseObject({
|
|
177
|
+
pattern: z.string(),
|
|
178
|
+
path: z.string().optional()
|
|
179
|
+
})
|
|
180
|
+
}),
|
|
181
|
+
title: "Grep Search"
|
|
182
|
+
},
|
|
183
|
+
glob: {
|
|
184
|
+
...commonTool("glob", {
|
|
185
|
+
nativeName: "find_by_name",
|
|
186
|
+
toolUseKind: "readonly",
|
|
187
|
+
inputSchema: z.looseObject({ pattern: z.string() })
|
|
188
|
+
}),
|
|
189
|
+
title: "Find By Name"
|
|
190
|
+
},
|
|
191
|
+
webSearch: {
|
|
192
|
+
...commonTool("webSearch", {
|
|
193
|
+
nativeName: "search_web",
|
|
194
|
+
toolUseKind: "readonly",
|
|
195
|
+
inputSchema: z.looseObject({ query: z.string() })
|
|
196
|
+
}),
|
|
197
|
+
title: "Search Web"
|
|
198
|
+
},
|
|
199
|
+
webFetch: {
|
|
200
|
+
...tool({
|
|
201
|
+
title: "Read URL",
|
|
202
|
+
inputSchema: z.looseObject({ url: z.string() })
|
|
203
|
+
}),
|
|
204
|
+
nativeName: "read_url_content",
|
|
205
|
+
toolUseKind: "readonly"
|
|
206
|
+
},
|
|
207
|
+
list_dir: native("list_dir", "List Directory", "readonly"),
|
|
208
|
+
command_status: native("command_status", "Command Status", "readonly"),
|
|
209
|
+
send_command_input: native("send_command_input", "Send Command Input", "bash"),
|
|
210
|
+
call_mcp_tool: native("call_mcp_tool", "Call MCP Tool"),
|
|
211
|
+
generate_image: native("generate_image", "Generate Image"),
|
|
212
|
+
invoke_subagent: native("invoke_subagent", "Invoke Subagent"),
|
|
213
|
+
browser_subagent: native("browser_subagent", "Browser Subagent"),
|
|
214
|
+
notebook_edit: native("notebook_edit", "Edit Notebook", "edit"),
|
|
215
|
+
ask_question: native("ask_question", "Ask Question")
|
|
216
|
+
};
|
|
217
|
+
const str = (value) => typeof value === "string" ? value : void 0;
|
|
218
|
+
/** Native edit tools that all surface as `edit`, since the key must be unique. */
|
|
219
|
+
const EDIT_TOOLS = /* @__PURE__ */ new Set([
|
|
220
|
+
"replace_file_content",
|
|
221
|
+
"multi_replace_file_content",
|
|
222
|
+
"sed_file"
|
|
223
|
+
]);
|
|
224
|
+
const BY_NATIVE_NAME = new Map(Object.entries(ANTIGRAVITY_BUILTIN_TOOLS).map(([key, t]) => [t.nativeName ?? key, key]));
|
|
225
|
+
/** Maps a native tool call to its catalog name, adding the common-schema fields it implies. */
|
|
226
|
+
function projectToolCall(nativeName, parameters = {}) {
|
|
227
|
+
const p = parameters;
|
|
228
|
+
const common = (toolName, extra) => ({
|
|
229
|
+
toolName,
|
|
230
|
+
nativeName,
|
|
231
|
+
input: {
|
|
232
|
+
...p,
|
|
233
|
+
...extra
|
|
234
|
+
},
|
|
235
|
+
dynamic: false
|
|
236
|
+
});
|
|
237
|
+
if (EDIT_TOOLS.has(nativeName)) return common("edit", { file_path: str(p.TargetFile) ?? str(p.AbsolutePath) ?? "" });
|
|
238
|
+
const server = str(p.ServerName);
|
|
239
|
+
const mcpTool = str(p.ToolName);
|
|
240
|
+
if (nativeName === "call_mcp_tool" && server && mcpTool) return {
|
|
241
|
+
toolName: `mcp__${server}__${mcpTool}`,
|
|
242
|
+
nativeName,
|
|
243
|
+
input: { ...p },
|
|
244
|
+
dynamic: true
|
|
245
|
+
};
|
|
246
|
+
switch (nativeName) {
|
|
247
|
+
case "run_command": return common("bash", { command: str(p.CommandLine) ?? str(p.command) ?? "" });
|
|
248
|
+
case "view_file": return common("read", { file_path: str(p.AbsolutePath) ?? str(p.TargetFile) ?? "" });
|
|
249
|
+
case "write_to_file": return common("write", { file_path: str(p.TargetFile) ?? "" });
|
|
250
|
+
case "grep_search": return common("grep", {
|
|
251
|
+
pattern: str(p.Query) ?? str(p.Pattern) ?? str(p.query) ?? "",
|
|
252
|
+
...str(p.SearchPath) ? { path: p.SearchPath } : {}
|
|
253
|
+
});
|
|
254
|
+
case "find_by_name": return common("glob", { pattern: str(p.Pattern) ?? str(p.pattern) ?? "" });
|
|
255
|
+
case "search_web": return common("webSearch", { query: str(p.query) ?? str(p.Query) ?? "" });
|
|
256
|
+
case "read_url_content": return common("webFetch", { url: str(p.Url) ?? str(p.url) ?? "" });
|
|
257
|
+
}
|
|
258
|
+
const key = BY_NATIVE_NAME.get(nativeName);
|
|
259
|
+
return key ? {
|
|
260
|
+
toolName: key,
|
|
261
|
+
nativeName,
|
|
262
|
+
input: { ...p },
|
|
263
|
+
dynamic: false
|
|
264
|
+
} : {
|
|
265
|
+
toolName: nativeName,
|
|
266
|
+
nativeName,
|
|
267
|
+
input: { ...p },
|
|
268
|
+
dynamic: true
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region ../harness-antigravity/src/antigravity-stream.ts
|
|
273
|
+
/** Maps the CLI's counts onto the AI SDK's usage shape, keeping the original under `raw`. */
|
|
274
|
+
function toUsage(usage) {
|
|
275
|
+
const noCache = usage?.input_tokens;
|
|
276
|
+
const cacheRead = usage?.cache_read_tokens;
|
|
277
|
+
const output = usage?.output_tokens;
|
|
278
|
+
const reasoning = usage?.thinking_tokens;
|
|
279
|
+
return {
|
|
280
|
+
inputTokens: {
|
|
281
|
+
total: noCache !== void 0 ? noCache + (cacheRead ?? 0) : void 0,
|
|
282
|
+
noCache,
|
|
283
|
+
cacheRead,
|
|
284
|
+
cacheWrite: void 0
|
|
285
|
+
},
|
|
286
|
+
outputTokens: {
|
|
287
|
+
total: output,
|
|
288
|
+
text: output !== void 0 && reasoning !== void 0 ? output - reasoning : void 0,
|
|
289
|
+
reasoning
|
|
290
|
+
},
|
|
291
|
+
...usage ? { raw: { ...usage } } : {}
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
const FINISH = {
|
|
295
|
+
SUCCESS: "stop",
|
|
296
|
+
ERROR: "error"
|
|
297
|
+
};
|
|
298
|
+
const TERMINAL_TOOL_STATES = /* @__PURE__ */ new Set([
|
|
299
|
+
"DONE",
|
|
300
|
+
"ERROR",
|
|
301
|
+
"CANCELED",
|
|
302
|
+
"CANCELLED"
|
|
303
|
+
]);
|
|
304
|
+
/**
|
|
305
|
+
* Turns one `agy` process's NDJSON into harness stream parts, in order. The CLI reports no
|
|
306
|
+
* tool-call ids, so a call is identified by its conversation and step index.
|
|
307
|
+
*/
|
|
308
|
+
var AntigravityStreamTranslator = class {
|
|
309
|
+
conversationId;
|
|
310
|
+
started = false;
|
|
311
|
+
finished = false;
|
|
312
|
+
sawText = false;
|
|
313
|
+
/**
|
|
314
|
+
* The reply step being streamed, held until agy moves on: an `error_message` step next means its
|
|
315
|
+
* model call failed (agy retries it), so its partial text isn't the reply.
|
|
316
|
+
*/
|
|
317
|
+
reply;
|
|
318
|
+
/**
|
|
319
|
+
* A model call agy reported failed, held until it's known whether agy retried it (another step
|
|
320
|
+
* follows) or gave up (the result, whose error is the turn's).
|
|
321
|
+
*/
|
|
322
|
+
failure;
|
|
323
|
+
retried = false;
|
|
324
|
+
openTools = /* @__PURE__ */ new Map();
|
|
325
|
+
pendingStep;
|
|
326
|
+
stepUsage = false;
|
|
327
|
+
turn;
|
|
328
|
+
constructor(options) {
|
|
329
|
+
this.turn = options.turn;
|
|
330
|
+
this.conversationId = options.conversationId;
|
|
331
|
+
}
|
|
332
|
+
/** Parts for one stdout line. Lines that aren't JSON events are passed through as raw. */
|
|
333
|
+
push(line) {
|
|
334
|
+
const trimmed = line.trim();
|
|
335
|
+
if (!trimmed) return [];
|
|
336
|
+
let event;
|
|
337
|
+
try {
|
|
338
|
+
event = JSON.parse(trimmed);
|
|
339
|
+
} catch {
|
|
340
|
+
return [{
|
|
341
|
+
type: "raw",
|
|
342
|
+
rawValue: { unparsed: trimmed }
|
|
343
|
+
}];
|
|
344
|
+
}
|
|
345
|
+
if (this.finished) return [{
|
|
346
|
+
type: "raw",
|
|
347
|
+
rawValue: event
|
|
348
|
+
}];
|
|
349
|
+
const parts = [];
|
|
350
|
+
if (event.event === "init") {
|
|
351
|
+
this.conversationId = event.conversation_id ?? this.conversationId;
|
|
352
|
+
this.start(parts, event.init?.model);
|
|
353
|
+
} else if (event.event === "step_update" && event.step_update) {
|
|
354
|
+
this.start(parts);
|
|
355
|
+
this.step(parts, event.step_update);
|
|
356
|
+
} else if (event.event === "result") {
|
|
357
|
+
this.start(parts);
|
|
358
|
+
this.result(parts, event.result ?? {});
|
|
359
|
+
}
|
|
360
|
+
parts.push({
|
|
361
|
+
type: "raw",
|
|
362
|
+
rawValue: event
|
|
363
|
+
});
|
|
364
|
+
return parts;
|
|
365
|
+
}
|
|
366
|
+
/** Closes the turn when the process ends without a `result` (killed, crashed, aborted). */
|
|
367
|
+
end(options) {
|
|
368
|
+
if (this.finished) return [];
|
|
369
|
+
const parts = [];
|
|
370
|
+
this.start(parts);
|
|
371
|
+
for (const call of this.openTools.values()) parts.push(this.toolResult(call, `${call.nativeName} ${options.aborted ? "aborted" : "interrupted"}`));
|
|
372
|
+
this.openTools.clear();
|
|
373
|
+
this.closeBlocks(parts);
|
|
374
|
+
if (!options.aborted) {
|
|
375
|
+
const detail = options.stderr?.trim();
|
|
376
|
+
parts.push({
|
|
377
|
+
type: "error",
|
|
378
|
+
error: /* @__PURE__ */ new Error(`The Antigravity CLI exited with code ${options.exitCode} before reporting a result${detail ? `: ${detail}` : ""}`)
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
this.finished = true;
|
|
382
|
+
parts.push({
|
|
383
|
+
type: "finish",
|
|
384
|
+
finishReason: options.aborted ? {
|
|
385
|
+
unified: "other",
|
|
386
|
+
raw: "aborted"
|
|
387
|
+
} : {
|
|
388
|
+
unified: "error",
|
|
389
|
+
raw: `exit ${options.exitCode}`
|
|
390
|
+
},
|
|
391
|
+
totalUsage: toUsage(void 0)
|
|
392
|
+
});
|
|
393
|
+
return parts;
|
|
394
|
+
}
|
|
395
|
+
start(parts, modelId) {
|
|
396
|
+
if (this.started) return;
|
|
397
|
+
this.started = true;
|
|
398
|
+
parts.push({
|
|
399
|
+
type: "stream-start",
|
|
400
|
+
...modelId ? { modelId } : {}
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
id(step) {
|
|
404
|
+
return `agy-${this.conversationId ?? `turn${this.turn}`}-${step}`;
|
|
405
|
+
}
|
|
406
|
+
toolResult(call, error, output = "") {
|
|
407
|
+
return {
|
|
408
|
+
type: "tool-result",
|
|
409
|
+
toolCallId: call.toolCallId,
|
|
410
|
+
toolName: call.toolName,
|
|
411
|
+
result: error ?? output,
|
|
412
|
+
...error !== void 0 ? { isError: true } : {},
|
|
413
|
+
...call.dynamic ? { dynamic: true } : {}
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
flushStep(parts, next) {
|
|
417
|
+
if (!this.pendingStep) return;
|
|
418
|
+
parts.push({
|
|
419
|
+
type: "finish-step",
|
|
420
|
+
finishReason: {
|
|
421
|
+
unified: next,
|
|
422
|
+
raw: "agent_response"
|
|
423
|
+
},
|
|
424
|
+
usage: toUsage(this.pendingStep)
|
|
425
|
+
});
|
|
426
|
+
this.pendingStep = void 0;
|
|
427
|
+
}
|
|
428
|
+
closeBlocks(parts) {
|
|
429
|
+
this.settleReply(parts);
|
|
430
|
+
this.settleFailure(parts, false);
|
|
431
|
+
this.flushStep(parts, "stop");
|
|
432
|
+
}
|
|
433
|
+
/** The held reply stood: its text goes out, and its usage ends its step. */
|
|
434
|
+
settleReply(parts) {
|
|
435
|
+
const r = this.reply;
|
|
436
|
+
if (!r) return;
|
|
437
|
+
this.reply = void 0;
|
|
438
|
+
if (r.deltas.length) {
|
|
439
|
+
this.flushStep(parts, "stop");
|
|
440
|
+
const id = `text-${r.index}`;
|
|
441
|
+
parts.push({
|
|
442
|
+
type: "text-start",
|
|
443
|
+
id
|
|
444
|
+
});
|
|
445
|
+
for (const delta of r.deltas) parts.push({
|
|
446
|
+
type: "text-delta",
|
|
447
|
+
id,
|
|
448
|
+
delta
|
|
449
|
+
});
|
|
450
|
+
parts.push({
|
|
451
|
+
type: "text-end",
|
|
452
|
+
id
|
|
453
|
+
});
|
|
454
|
+
this.sawText = true;
|
|
455
|
+
}
|
|
456
|
+
if (r.usage) {
|
|
457
|
+
this.flushStep(parts, "stop");
|
|
458
|
+
this.pendingStep = r.usage;
|
|
459
|
+
this.stepUsage = true;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
/** A model call agy reports failed (`error_message`): its partial text isn't the reply. */
|
|
463
|
+
failReply(parts) {
|
|
464
|
+
this.settleFailure(parts, true);
|
|
465
|
+
const usage = this.reply?.usage;
|
|
466
|
+
this.reply = void 0;
|
|
467
|
+
this.failure = usage ? { usage } : {};
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* The held failure's step, with the tokens it spent: failed (`error`) if agy retried the call,
|
|
471
|
+
* else ended plainly, since the result's error already fails the turn.
|
|
472
|
+
*/
|
|
473
|
+
settleFailure(parts, retried) {
|
|
474
|
+
const f = this.failure;
|
|
475
|
+
if (!f) return;
|
|
476
|
+
this.failure = void 0;
|
|
477
|
+
this.flushStep(parts, "stop");
|
|
478
|
+
if (retried) this.retried = true;
|
|
479
|
+
if (!retried && !f.usage) return;
|
|
480
|
+
if (f.usage) this.stepUsage = true;
|
|
481
|
+
parts.push({
|
|
482
|
+
type: "finish-step",
|
|
483
|
+
finishReason: {
|
|
484
|
+
unified: retried ? "error" : "other",
|
|
485
|
+
raw: "error_message"
|
|
486
|
+
},
|
|
487
|
+
usage: toUsage(f.usage)
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
step(parts, s) {
|
|
491
|
+
const index = s.step_index ?? -1;
|
|
492
|
+
this.conversationId ??= s.conversation_id;
|
|
493
|
+
if (s.step_type === "agent_response") {
|
|
494
|
+
this.settleFailure(parts, true);
|
|
495
|
+
if (this.reply && this.reply.index !== index) this.settleReply(parts);
|
|
496
|
+
this.reply ??= {
|
|
497
|
+
index,
|
|
498
|
+
deltas: []
|
|
499
|
+
};
|
|
500
|
+
if (s.text_delta) this.reply.deltas.push(s.text_delta);
|
|
501
|
+
if (s.state !== "ACTIVE" && s.usage) this.reply.usage = s.usage;
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
if (s.step_type === "error_message") {
|
|
505
|
+
this.failReply(parts);
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
this.settleReply(parts);
|
|
509
|
+
if (s.step_type !== "user_input") this.settleFailure(parts, true);
|
|
510
|
+
if (s.step_type === "tool") {
|
|
511
|
+
this.flushStep(parts, "tool-calls");
|
|
512
|
+
const info = s.tool_info ?? {};
|
|
513
|
+
const nativeName = info.name ?? s.tool_name ?? "unknown";
|
|
514
|
+
let call = this.openTools.get(index);
|
|
515
|
+
if (!call) {
|
|
516
|
+
const projected = projectToolCall(nativeName, info.parameters);
|
|
517
|
+
call = {
|
|
518
|
+
...projected,
|
|
519
|
+
toolCallId: this.id(index)
|
|
520
|
+
};
|
|
521
|
+
this.openTools.set(index, call);
|
|
522
|
+
parts.push({
|
|
523
|
+
type: "tool-call",
|
|
524
|
+
toolCallId: call.toolCallId,
|
|
525
|
+
toolName: call.toolName,
|
|
526
|
+
input: JSON.stringify(projected.input),
|
|
527
|
+
providerExecuted: true,
|
|
528
|
+
...call.dynamic ? { dynamic: true } : {},
|
|
529
|
+
...call.toolName !== nativeName ? { nativeName } : {}
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
if (s.state && TERMINAL_TOOL_STATES.has(s.state)) {
|
|
533
|
+
this.openTools.delete(index);
|
|
534
|
+
const failed = s.state !== "DONE" || info.error !== void 0;
|
|
535
|
+
parts.push(this.toolResult(call, failed ? info.error?.message ?? `${nativeName} ${s.state.toLowerCase()}` : void 0, info.output ?? ""));
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
result(parts, r) {
|
|
540
|
+
this.conversationId = r.conversation_id || this.conversationId;
|
|
541
|
+
this.settleReply(parts);
|
|
542
|
+
if (!this.sawText && !this.retried && !this.failure && r.response) {
|
|
543
|
+
parts.push({
|
|
544
|
+
type: "text-start",
|
|
545
|
+
id: "text-result"
|
|
546
|
+
});
|
|
547
|
+
parts.push({
|
|
548
|
+
type: "text-delta",
|
|
549
|
+
id: "text-result",
|
|
550
|
+
delta: r.response
|
|
551
|
+
});
|
|
552
|
+
parts.push({
|
|
553
|
+
type: "text-end",
|
|
554
|
+
id: "text-result"
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
this.closeBlocks(parts);
|
|
558
|
+
if (!this.stepUsage && r.usage) parts.push({
|
|
559
|
+
type: "finish-step",
|
|
560
|
+
finishReason: {
|
|
561
|
+
unified: "stop",
|
|
562
|
+
raw: "result"
|
|
563
|
+
},
|
|
564
|
+
usage: toUsage(r.usage)
|
|
565
|
+
});
|
|
566
|
+
const status = r.status ?? "UNKNOWN";
|
|
567
|
+
if (status !== "SUCCESS") parts.push({
|
|
568
|
+
type: "error",
|
|
569
|
+
error: new Error(r.error || `The Antigravity CLI ended the turn with status ${status}`)
|
|
570
|
+
});
|
|
571
|
+
this.finished = true;
|
|
572
|
+
parts.push({
|
|
573
|
+
type: "finish",
|
|
574
|
+
finishReason: {
|
|
575
|
+
unified: FINISH[status] ?? "other",
|
|
576
|
+
raw: status
|
|
577
|
+
},
|
|
578
|
+
totalUsage: toUsage(r.usage),
|
|
579
|
+
...r.structured_output !== void 0 ? { harnessMetadata: { antigravity: { structuredOutput: r.structured_output } } } : {}
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
//#endregion
|
|
584
|
+
//#region ../harness-antigravity/src/antigravity-harness.ts
|
|
585
|
+
const ANTIGRAVITY_HARNESS_ID = "antigravity";
|
|
586
|
+
/** Where the CLI reads home skills (1.2.11; its docs' `~/.gemini/antigravity-cli/skills` isn't read). */
|
|
587
|
+
const ANTIGRAVITY_HOME_SKILLS_DIR = ".gemini/config/skills";
|
|
588
|
+
/** Always-on global rules; `instructions` are appended here. */
|
|
589
|
+
const ANTIGRAVITY_INSTRUCTIONS_FILE = ".gemini/GEMINI.md";
|
|
590
|
+
const ANTIGRAVITY_MCP_CONFIG_FILE = ".gemini/config/mcp_config.json";
|
|
591
|
+
const ANTIGRAVITY_SETTINGS_FILE = ".gemini/antigravity-cli/settings.json";
|
|
592
|
+
const lifecycleData = z.object({ conversationId: z.string().nullable() });
|
|
593
|
+
function promptText(prompt) {
|
|
594
|
+
if (typeof prompt === "string") return prompt;
|
|
595
|
+
const { content } = prompt;
|
|
596
|
+
if (typeof content === "string") return content;
|
|
597
|
+
return content.map((part) => {
|
|
598
|
+
if (part.type !== "text") throw new HarnessCapabilityUnsupportedError({
|
|
599
|
+
message: `The Antigravity CLI takes text prompts only (got a ${part.type} part)`,
|
|
600
|
+
harnessId: ANTIGRAVITY_HARNESS_ID
|
|
601
|
+
});
|
|
602
|
+
return part.text;
|
|
603
|
+
}).join("\n");
|
|
604
|
+
}
|
|
605
|
+
const unsupported = (what) => new HarnessCapabilityUnsupportedError({
|
|
606
|
+
message: `The Antigravity CLI's print mode has no ${what}`,
|
|
607
|
+
harnessId: ANTIGRAVITY_HARNESS_ID
|
|
608
|
+
});
|
|
609
|
+
const lines = (stream) => createInterface({
|
|
610
|
+
input: Readable.fromWeb(stream),
|
|
611
|
+
crlfDelay: Infinity
|
|
612
|
+
});
|
|
613
|
+
async function tail(stream, max = 4e3) {
|
|
614
|
+
let text = "";
|
|
615
|
+
for await (const line of lines(stream)) text = `${text}${line}\n`.slice(-max);
|
|
616
|
+
return text;
|
|
617
|
+
}
|
|
618
|
+
const canBroker = (sandbox) => "addRequestTransformations" in sandbox && typeof sandbox.addRequestTransformations === "function";
|
|
619
|
+
/**
|
|
620
|
+
* The Antigravity CLI (`agy`) as an AI SDK harness. It has no ACP mode, so each turn is one
|
|
621
|
+
* `agy -p … --output-format stream-json` process, resumed with `--conversation`, and its NDJSON
|
|
622
|
+
* is translated into harness stream parts. Only a Gemini API key authenticates it.
|
|
623
|
+
*/
|
|
624
|
+
function createAntigravity(settings = {}) {
|
|
625
|
+
return {
|
|
626
|
+
specificationVersion: "harness-v1",
|
|
627
|
+
harnessId: ANTIGRAVITY_HARNESS_ID,
|
|
628
|
+
builtinTools: ANTIGRAVITY_BUILTIN_TOOLS,
|
|
629
|
+
lifecycleStateSchema: lifecycleData,
|
|
630
|
+
getBootstrap: getAntigravityBootstrap,
|
|
631
|
+
doStart: (options) => startSession(settings, options)
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
async function startSession(settings, options) {
|
|
635
|
+
const { sandboxSession: sandbox, sessionWorkDir, sessionId, abortSignal } = options;
|
|
636
|
+
const credentials = resolveAntigravityCredentials(settings.auth);
|
|
637
|
+
let sandboxKey = credentials.apiKey;
|
|
638
|
+
if (canBroker(sandbox)) {
|
|
639
|
+
sandboxKey = generateSandboxCredentialPlaceholder();
|
|
640
|
+
await sandbox.addRequestTransformations(createAntigravityRequestTransformations({
|
|
641
|
+
credentials,
|
|
642
|
+
placeholder: sandboxKey,
|
|
643
|
+
...options.headers ? { headers: options.headers } : {}
|
|
644
|
+
}));
|
|
645
|
+
} else if (settings.requireCredentialBrokering) throw new Error(`The sandbox can't broker ${ANTIGRAVITY_CREDENTIAL_ENV} (it has no request transformations), and requireCredentialBrokering is set, so the key stays out of it.`);
|
|
646
|
+
else warnCredentialBrokeringUnavailable({
|
|
647
|
+
environment: { [ANTIGRAVITY_CREDENTIAL_ENV]: credentials.apiKey },
|
|
648
|
+
forwardedEnvironment: { [ANTIGRAVITY_CREDENTIAL_ENV]: sandboxKey },
|
|
649
|
+
credentialEnvironmentVariables: [ANTIGRAVITY_CREDENTIAL_ENV]
|
|
650
|
+
});
|
|
651
|
+
const home = await resolveSandboxHomeDir({
|
|
652
|
+
sandbox,
|
|
653
|
+
abortSignal
|
|
654
|
+
});
|
|
655
|
+
const stateDir = harnessStateDirectoryPath({ sandboxHomeDir: home });
|
|
656
|
+
const cli = posix.join(stateDir, ANTIGRAVITY_BOOTSTRAP_DIR, ANTIGRAVITY_CLI_PATH);
|
|
657
|
+
const sessionDir = harnessSessionDataDirectoryPath({
|
|
658
|
+
stateDirectory: stateDir,
|
|
659
|
+
sessionId
|
|
660
|
+
});
|
|
661
|
+
const write = (file, content) => sandbox.writeTextFile({
|
|
662
|
+
path: posix.join(home, file),
|
|
663
|
+
content,
|
|
664
|
+
abortSignal
|
|
665
|
+
});
|
|
666
|
+
await write(ANTIGRAVITY_SETTINGS_FILE, `${JSON.stringify({
|
|
667
|
+
enableTelemetry: false,
|
|
668
|
+
...settings.settings,
|
|
669
|
+
modelProvider: "gemini"
|
|
670
|
+
}, null, 2)}\n`);
|
|
671
|
+
if (settings.mcpServers && Object.keys(settings.mcpServers).length > 0) await write(ANTIGRAVITY_MCP_CONFIG_FILE, `${JSON.stringify({ mcpServers: settings.mcpServers }, null, 2)}\n`);
|
|
672
|
+
const env = {
|
|
673
|
+
...settings.env,
|
|
674
|
+
[ANTIGRAVITY_CREDENTIAL_ENV]: sandboxKey,
|
|
675
|
+
AGY_CLI_DISABLE_AUTO_UPDATE: "true",
|
|
676
|
+
...credentials.baseUrl ? { [ANTIGRAVITY_BASE_URL_ENV]: credentials.baseUrl } : {}
|
|
677
|
+
};
|
|
678
|
+
const resumed = lifecycleData.safeParse(options.resumeFrom?.data);
|
|
679
|
+
let conversationId = resumed.success ? resumed.data.conversationId : null;
|
|
680
|
+
let turns = 0;
|
|
681
|
+
let running;
|
|
682
|
+
let ended = false;
|
|
683
|
+
const state = () => ({
|
|
684
|
+
type: "resume-session",
|
|
685
|
+
harnessId: ANTIGRAVITY_HARNESS_ID,
|
|
686
|
+
specificationVersion: "harness-v1",
|
|
687
|
+
data: { conversationId }
|
|
688
|
+
});
|
|
689
|
+
const stop = async () => {
|
|
690
|
+
ended = true;
|
|
691
|
+
await running?.kill();
|
|
692
|
+
running = void 0;
|
|
693
|
+
};
|
|
694
|
+
return {
|
|
695
|
+
sessionId,
|
|
696
|
+
isResume: options.resumeFrom !== void 0,
|
|
697
|
+
async doPromptTurn(turn) {
|
|
698
|
+
if (ended) throw new Error("This Antigravity session has ended");
|
|
699
|
+
if (turn.tools.length > 0) throw unsupported("host-executed tools");
|
|
700
|
+
const n = ++turns;
|
|
701
|
+
await writeSkills({
|
|
702
|
+
sandbox,
|
|
703
|
+
homePath: home,
|
|
704
|
+
skillsDir: ANTIGRAVITY_HOME_SKILLS_DIR,
|
|
705
|
+
skills: turn.skills,
|
|
706
|
+
...turn.abortSignal ? { abortSignal: turn.abortSignal } : {}
|
|
707
|
+
});
|
|
708
|
+
await writeInstructions({
|
|
709
|
+
sandbox,
|
|
710
|
+
homePath: home,
|
|
711
|
+
instructionsFile: ANTIGRAVITY_INSTRUCTIONS_FILE,
|
|
712
|
+
...turn.instructions !== void 0 ? { instructions: turn.instructions } : {},
|
|
713
|
+
...turn.abortSignal ? { abortSignal: turn.abortSignal } : {}
|
|
714
|
+
});
|
|
715
|
+
const promptFile = posix.join(sessionDir, `prompt-${n}.txt`);
|
|
716
|
+
await sandbox.writeTextFile({
|
|
717
|
+
path: promptFile,
|
|
718
|
+
content: promptText(turn.prompt),
|
|
719
|
+
abortSignal: turn.abortSignal
|
|
720
|
+
});
|
|
721
|
+
let jsonSchemaFile;
|
|
722
|
+
if (turn.responseFormat?.type === "json" && turn.responseFormat.schema) {
|
|
723
|
+
jsonSchemaFile = posix.join(sessionDir, `schema-${n}.json`);
|
|
724
|
+
await sandbox.writeTextFile({
|
|
725
|
+
path: jsonSchemaFile,
|
|
726
|
+
content: JSON.stringify(turn.responseFormat.schema),
|
|
727
|
+
abortSignal: turn.abortSignal
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
const command = buildAntigravityCommand({
|
|
731
|
+
cli,
|
|
732
|
+
workDir: sessionWorkDir,
|
|
733
|
+
promptFile,
|
|
734
|
+
model: turn.model,
|
|
735
|
+
effort: settings.effort,
|
|
736
|
+
permissionMode: options.permissionMode,
|
|
737
|
+
conversationId: conversationId ?? void 0,
|
|
738
|
+
jsonSchemaFile
|
|
739
|
+
});
|
|
740
|
+
const translator = new AntigravityStreamTranslator({
|
|
741
|
+
turn: n,
|
|
742
|
+
conversationId: conversationId ?? void 0
|
|
743
|
+
});
|
|
744
|
+
const emit = (parts) => {
|
|
745
|
+
for (const part of parts) turn.emit(part);
|
|
746
|
+
};
|
|
747
|
+
const proc = await sandbox.spawn({
|
|
748
|
+
command,
|
|
749
|
+
workingDirectory: sessionWorkDir,
|
|
750
|
+
env,
|
|
751
|
+
...turn.abortSignal ? { abortSignal: turn.abortSignal } : {}
|
|
752
|
+
});
|
|
753
|
+
running = proc;
|
|
754
|
+
const onAbort = () => void proc.kill();
|
|
755
|
+
turn.abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
756
|
+
return {
|
|
757
|
+
submitToolResult: () => Promise.reject(unsupported("host-executed tools")),
|
|
758
|
+
done: (async () => {
|
|
759
|
+
const stderr = tail(proc.stderr).catch(() => "");
|
|
760
|
+
try {
|
|
761
|
+
for await (const line of lines(proc.stdout)) emit(translator.push(line));
|
|
762
|
+
const { exitCode } = await proc.wait();
|
|
763
|
+
emit(translator.end({
|
|
764
|
+
exitCode,
|
|
765
|
+
stderr: await stderr,
|
|
766
|
+
aborted: turn.abortSignal?.aborted === true
|
|
767
|
+
}));
|
|
768
|
+
} finally {
|
|
769
|
+
turn.abortSignal?.removeEventListener("abort", onAbort);
|
|
770
|
+
if (running === proc) running = void 0;
|
|
771
|
+
conversationId = translator.conversationId ?? conversationId;
|
|
772
|
+
}
|
|
773
|
+
})()
|
|
774
|
+
};
|
|
775
|
+
},
|
|
776
|
+
doCompact: () => Promise.reject(unsupported("manual compaction")),
|
|
777
|
+
doContinueTurn: () => Promise.reject(unsupported("turn continuation")),
|
|
778
|
+
doSuspendTurn: () => Promise.reject(unsupported("turn suspension")),
|
|
779
|
+
async doDetach() {
|
|
780
|
+
await stop();
|
|
781
|
+
return state();
|
|
782
|
+
},
|
|
783
|
+
async doStop() {
|
|
784
|
+
await stop();
|
|
785
|
+
return state();
|
|
786
|
+
},
|
|
787
|
+
doDestroy: stop
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
//#endregion
|
|
791
|
+
export { resolveAntigravityCredentials as C, createAntigravityRequestTransformations as S, getAntigravityBootstrap as _, ANTIGRAVITY_SETTINGS_FILE as a, GEMINI_API_KEY_HEADER as b, toUsage as c, buildAntigravityCommand as d, ANTIGRAVITY_BOOTSTRAP_DIR as f, antigravityInstallScript as g, ANTIGRAVITY_CLI_VERSION as h, ANTIGRAVITY_MCP_CONFIG_FILE as i, ANTIGRAVITY_BUILTIN_TOOLS as l, ANTIGRAVITY_CLI_SHA256 as m, ANTIGRAVITY_HOME_SKILLS_DIR as n, createAntigravity as o, ANTIGRAVITY_CLI_PATH as p, ANTIGRAVITY_INSTRUCTIONS_FILE as r, AntigravityStreamTranslator as s, ANTIGRAVITY_HARNESS_ID as t, projectToolCall as u, ANTIGRAVITY_BASE_URL_ENV as v, GEMINI_API_URL as x, ANTIGRAVITY_CREDENTIAL_ENV as y };
|
|
792
|
+
|
|
793
|
+
//# sourceMappingURL=src-D8KYzxBX.js.map
|