@smithers-orchestrator/agents 0.20.4 → 0.22.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/package.json +5 -5
- package/src/AntigravityAgent.js +267 -0
- package/src/AntigravityAgentOptions.ts +38 -0
- package/src/BaseCliAgent/BaseCliAgent.js +13 -0
- package/src/BaseCliAgent/runRpcCommandEffect.js +7 -3
- package/src/BaseCliAgent/truncateToBytes.js +18 -1
- package/src/CodexAgent.js +15 -8
- package/src/GeminiAgent.js +4 -0
- package/src/GeminiAgentOptions.ts +5 -0
- package/src/HermesAgent.js +41 -0
- package/src/HermesAgentOptions.ts +41 -0
- package/src/__type-tests__/AgentLike.assignability.test-d.ts +2 -0
- package/src/capability-registry/AgentCapabilityRegistry.ts +1 -1
- package/src/cli-capabilities/CliAgentCapabilityAdapterId.ts +1 -0
- package/src/cli-capabilities/getCliAgentCapabilityReport.js +6 -0
- package/src/diagnostics/getDiagnosticStrategy.js +34 -1
- package/src/diagnostics/runDiagnostics.js +9 -1
- package/src/index.d.ts +67 -2
- package/src/index.js +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithers-orchestrator/agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "AI SDK and CLI agent adapters for Smithers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"ai": "^6.0.168",
|
|
51
51
|
"effect": "^3.21.1",
|
|
52
52
|
"zod": "^4.3.6",
|
|
53
|
-
"@smithers-orchestrator/
|
|
54
|
-
"@smithers-orchestrator/
|
|
55
|
-
"@smithers-orchestrator/observability": "0.
|
|
53
|
+
"@smithers-orchestrator/driver": "0.22.0",
|
|
54
|
+
"@smithers-orchestrator/errors": "0.22.0",
|
|
55
|
+
"@smithers-orchestrator/observability": "0.22.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/bun": "latest",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"typescript": "~5.9.3"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
|
-
"test": "bun test tests",
|
|
63
|
+
"test": "bun test --timeout=60000 --max-concurrency=1 tests",
|
|
64
64
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
65
65
|
"build": "tsup --dts-only"
|
|
66
66
|
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { BaseCliAgent, pushFlag, pushList, isRecord, asString, truncate, toolKindFromName, createSyntheticIdGenerator, } from "./BaseCliAgent/index.js";
|
|
2
|
+
import { normalizeCapabilityStringList, } from "./capability-registry/index.js";
|
|
3
|
+
/** @typedef {import("./capability-registry/AgentCapabilityRegistry.ts").AgentCapabilityRegistry} AgentCapabilityRegistry */
|
|
4
|
+
/** @typedef {import("./BaseCliAgent/CliOutputInterpreter.ts").CliOutputInterpreter} CliOutputInterpreter */
|
|
5
|
+
/** @typedef {import("./AntigravityAgentOptions.ts").AntigravityAgentOptions} AntigravityAgentOptions */
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {AntigravityAgentOptions} opts
|
|
9
|
+
*/
|
|
10
|
+
function resolveAntigravityBuiltIns(opts) {
|
|
11
|
+
return opts.allowedTools?.length
|
|
12
|
+
? normalizeCapabilityStringList(opts.allowedTools)
|
|
13
|
+
: ["default"];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @param {AntigravityAgentOptions} [opts]
|
|
18
|
+
* @returns {AgentCapabilityRegistry}
|
|
19
|
+
*/
|
|
20
|
+
export function createAntigravityCapabilityRegistry(opts = {}) {
|
|
21
|
+
return {
|
|
22
|
+
version: 1,
|
|
23
|
+
engine: "antigravity",
|
|
24
|
+
runtimeTools: {},
|
|
25
|
+
mcp: {
|
|
26
|
+
bootstrap: "project-config",
|
|
27
|
+
supportsProjectScope: true,
|
|
28
|
+
supportsUserScope: true,
|
|
29
|
+
},
|
|
30
|
+
skills: {
|
|
31
|
+
supportsSkills: true,
|
|
32
|
+
installMode: "plugin",
|
|
33
|
+
smithersSkillIds: [],
|
|
34
|
+
},
|
|
35
|
+
humanInteraction: {
|
|
36
|
+
supportsUiRequests: false,
|
|
37
|
+
methods: [],
|
|
38
|
+
},
|
|
39
|
+
builtIns: resolveAntigravityBuiltIns(opts),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class AntigravityAgent extends BaseCliAgent {
|
|
44
|
+
opts;
|
|
45
|
+
capabilities;
|
|
46
|
+
cliEngine = "antigravity";
|
|
47
|
+
/**
|
|
48
|
+
* @param {AntigravityAgentOptions} [opts]
|
|
49
|
+
*/
|
|
50
|
+
constructor(opts = {}) {
|
|
51
|
+
super(opts);
|
|
52
|
+
this.opts = opts;
|
|
53
|
+
this.capabilities = createAntigravityCapabilityRegistry(opts);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @returns {CliOutputInterpreter}
|
|
57
|
+
*/
|
|
58
|
+
createOutputInterpreter() {
|
|
59
|
+
let sessionId;
|
|
60
|
+
let finalAnswer = "";
|
|
61
|
+
let didEmitCompleted = false;
|
|
62
|
+
const nextSyntheticId = createSyntheticIdGenerator();
|
|
63
|
+
/**
|
|
64
|
+
* @param {string} line
|
|
65
|
+
* @returns {AgentCliEvent[]}
|
|
66
|
+
*/
|
|
67
|
+
const parseLine = (line) => {
|
|
68
|
+
const trimmed = line.trim();
|
|
69
|
+
if (!trimmed)
|
|
70
|
+
return [];
|
|
71
|
+
let payload;
|
|
72
|
+
try {
|
|
73
|
+
payload = JSON.parse(trimmed);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
if (!isRecord(payload))
|
|
79
|
+
return [];
|
|
80
|
+
const type = asString(payload.type);
|
|
81
|
+
if (!type)
|
|
82
|
+
return [];
|
|
83
|
+
if (type === "init") {
|
|
84
|
+
const resume = asString(payload.session_id);
|
|
85
|
+
if (resume) {
|
|
86
|
+
sessionId = resume;
|
|
87
|
+
}
|
|
88
|
+
return [{
|
|
89
|
+
type: "started",
|
|
90
|
+
engine: this.cliEngine,
|
|
91
|
+
title: "Antigravity CLI",
|
|
92
|
+
resume: sessionId,
|
|
93
|
+
detail: {
|
|
94
|
+
model: asString(payload.model),
|
|
95
|
+
},
|
|
96
|
+
}];
|
|
97
|
+
}
|
|
98
|
+
if (type === "MESSAGE") {
|
|
99
|
+
const role = asString(payload.role);
|
|
100
|
+
const content = asString(payload.content);
|
|
101
|
+
if (role === "assistant" && content) {
|
|
102
|
+
if (payload.delta === true) {
|
|
103
|
+
finalAnswer += content;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
finalAnswer = content;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
if (type === "TOOL_USE") {
|
|
112
|
+
const toolName = asString(payload.tool_name) ?? "tool";
|
|
113
|
+
const toolId = asString(payload.tool_id) ?? nextSyntheticId("antigravity-tool");
|
|
114
|
+
return [{
|
|
115
|
+
type: "action",
|
|
116
|
+
engine: this.cliEngine,
|
|
117
|
+
phase: "started",
|
|
118
|
+
entryType: "thought",
|
|
119
|
+
action: {
|
|
120
|
+
id: toolId,
|
|
121
|
+
kind: toolKindFromName(toolName),
|
|
122
|
+
title: toolName,
|
|
123
|
+
detail: {
|
|
124
|
+
parameters: payload.parameters,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
message: `Running ${toolName}`,
|
|
128
|
+
level: "info",
|
|
129
|
+
}];
|
|
130
|
+
}
|
|
131
|
+
if (type === "TOOL_RESULT") {
|
|
132
|
+
const toolId = asString(payload.tool_id) ?? nextSyntheticId("antigravity-tool");
|
|
133
|
+
const ok = asString(payload.status) !== "error";
|
|
134
|
+
const error = isRecord(payload.error) ? asString(payload.error.message) : undefined;
|
|
135
|
+
const output = asString(payload.output);
|
|
136
|
+
return [{
|
|
137
|
+
type: "action",
|
|
138
|
+
engine: this.cliEngine,
|
|
139
|
+
phase: "completed",
|
|
140
|
+
entryType: "thought",
|
|
141
|
+
action: {
|
|
142
|
+
id: toolId,
|
|
143
|
+
kind: "tool",
|
|
144
|
+
title: "tool result",
|
|
145
|
+
detail: {
|
|
146
|
+
status: asString(payload.status),
|
|
147
|
+
output: output ? truncate(output, 400) : undefined,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
message: error ?? output,
|
|
151
|
+
ok,
|
|
152
|
+
level: ok ? "info" : "warning",
|
|
153
|
+
}];
|
|
154
|
+
}
|
|
155
|
+
if (type === "ERROR") {
|
|
156
|
+
return [{
|
|
157
|
+
type: "action",
|
|
158
|
+
engine: this.cliEngine,
|
|
159
|
+
phase: "completed",
|
|
160
|
+
entryType: "thought",
|
|
161
|
+
action: {
|
|
162
|
+
id: nextSyntheticId("antigravity-warning"),
|
|
163
|
+
kind: "warning",
|
|
164
|
+
title: "warning",
|
|
165
|
+
detail: {
|
|
166
|
+
severity: asString(payload.severity),
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
message: asString(payload.message),
|
|
170
|
+
ok: asString(payload.severity) !== "error",
|
|
171
|
+
level: asString(payload.severity) === "error" ? "error" : "warning",
|
|
172
|
+
}];
|
|
173
|
+
}
|
|
174
|
+
if (type === "RESULT") {
|
|
175
|
+
if (didEmitCompleted)
|
|
176
|
+
return [];
|
|
177
|
+
didEmitCompleted = true;
|
|
178
|
+
return [{
|
|
179
|
+
type: "completed",
|
|
180
|
+
engine: this.cliEngine,
|
|
181
|
+
ok: asString(payload.status) !== "error",
|
|
182
|
+
answer: finalAnswer || asString(payload.response),
|
|
183
|
+
resume: sessionId,
|
|
184
|
+
usage: isRecord(payload.stats) ? payload.stats : undefined,
|
|
185
|
+
}];
|
|
186
|
+
}
|
|
187
|
+
return [];
|
|
188
|
+
};
|
|
189
|
+
return {
|
|
190
|
+
onStdoutLine: parseLine,
|
|
191
|
+
onExit: (result) => {
|
|
192
|
+
if (didEmitCompleted)
|
|
193
|
+
return [];
|
|
194
|
+
if (result.exitCode === 0)
|
|
195
|
+
return [];
|
|
196
|
+
didEmitCompleted = true;
|
|
197
|
+
return [{
|
|
198
|
+
type: "completed",
|
|
199
|
+
engine: this.cliEngine,
|
|
200
|
+
ok: false,
|
|
201
|
+
answer: finalAnswer || undefined,
|
|
202
|
+
error: result.stderr.trim() || `Antigravity exited with code ${result.exitCode}`,
|
|
203
|
+
resume: sessionId,
|
|
204
|
+
}];
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* @param {{ prompt: string; systemPrompt?: string; cwd: string; options: any; }} params
|
|
210
|
+
*/
|
|
211
|
+
async buildCommand(params) {
|
|
212
|
+
const args = [];
|
|
213
|
+
const yoloEnabled = this.opts.dangerouslySkipPermissions ?? this.opts.yolo ?? this.yolo;
|
|
214
|
+
const outputFormat = this.opts.outputFormat ??
|
|
215
|
+
(params.options?.onEvent ? "stream-json" : "json");
|
|
216
|
+
const resumeSession = typeof params.options?.resumeSession === "string"
|
|
217
|
+
? params.options.resumeSession
|
|
218
|
+
: this.opts.resume;
|
|
219
|
+
if (this.opts.debug)
|
|
220
|
+
args.push("--debug");
|
|
221
|
+
pushFlag(args, "--model", this.opts.model ?? this.model);
|
|
222
|
+
if (this.opts.sandbox)
|
|
223
|
+
args.push("--sandbox");
|
|
224
|
+
if (yoloEnabled)
|
|
225
|
+
args.push("--dangerously-skip-permissions");
|
|
226
|
+
pushList(args, "--allowed-mcp-server-names", this.opts.allowedMcpServerNames);
|
|
227
|
+
if (this.opts.allowedTools !== undefined) {
|
|
228
|
+
if (this.opts.allowedTools.length === 0) {
|
|
229
|
+
pushFlag(args, "--allowed-tools", "");
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
pushList(args, "--allowed-tools", this.opts.allowedTools);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
pushList(args, "--extensions", this.opts.extensions);
|
|
236
|
+
if (this.opts.listExtensions)
|
|
237
|
+
args.push("--list-extensions");
|
|
238
|
+
pushFlag(args, "--resume", resumeSession);
|
|
239
|
+
if (this.opts.listSessions)
|
|
240
|
+
args.push("--list-sessions");
|
|
241
|
+
pushFlag(args, "--delete-session", this.opts.deleteSession);
|
|
242
|
+
pushList(args, "--include-directories", this.opts.includeDirectories);
|
|
243
|
+
if (this.opts.screenReader)
|
|
244
|
+
args.push("--screen-reader");
|
|
245
|
+
pushFlag(args, "--gemini_dir", this.opts.geminiDir ?? this.opts.configDir);
|
|
246
|
+
pushFlag(args, "--output-format", outputFormat);
|
|
247
|
+
if (this.extraArgs?.length)
|
|
248
|
+
args.push(...this.extraArgs);
|
|
249
|
+
const systemPrefix = params.systemPrompt
|
|
250
|
+
? `${params.systemPrompt}\n\n`
|
|
251
|
+
: "";
|
|
252
|
+
const jsonReminder = params.prompt?.includes("REQUIRED OUTPUT")
|
|
253
|
+
? "\n\nREMINDER: Your response MUST be ONLY the required raw JSON object. Do not include prose, markdown, or code fences. The first character must be `{` and the last character must be `}`.\n"
|
|
254
|
+
: "";
|
|
255
|
+
const fullPrompt = `${systemPrefix}${params.prompt ?? ""}${jsonReminder}`;
|
|
256
|
+
args.push("--prompt", fullPrompt);
|
|
257
|
+
const accountEnv = {};
|
|
258
|
+
if (this.opts.apiKey)
|
|
259
|
+
accountEnv.GEMINI_API_KEY = this.opts.apiKey;
|
|
260
|
+
return {
|
|
261
|
+
command: this.opts.binary ?? "agy",
|
|
262
|
+
args,
|
|
263
|
+
outputFormat,
|
|
264
|
+
env: Object.keys(accountEnv).length > 0 ? accountEnv : undefined,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { BaseCliAgentOptions } from "./BaseCliAgent/BaseCliAgentOptions";
|
|
2
|
+
|
|
3
|
+
export type AntigravityAgentOptions = BaseCliAgentOptions & {
|
|
4
|
+
debug?: boolean;
|
|
5
|
+
model?: string;
|
|
6
|
+
sandbox?: boolean;
|
|
7
|
+
yolo?: boolean;
|
|
8
|
+
dangerouslySkipPermissions?: boolean;
|
|
9
|
+
allowedMcpServerNames?: string[];
|
|
10
|
+
allowedTools?: string[];
|
|
11
|
+
extensions?: string[];
|
|
12
|
+
listExtensions?: boolean;
|
|
13
|
+
resume?: string;
|
|
14
|
+
listSessions?: boolean;
|
|
15
|
+
deleteSession?: string;
|
|
16
|
+
includeDirectories?: string[];
|
|
17
|
+
screenReader?: boolean;
|
|
18
|
+
outputFormat?: "text" | "json" | "stream-json";
|
|
19
|
+
/**
|
|
20
|
+
* Antigravity CLI binary to execute. The official CLI currently installs
|
|
21
|
+
* `agy`; this exists for test harnesses and future binary renames.
|
|
22
|
+
*/
|
|
23
|
+
binary?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Path to an isolated Google CLI config root. Passed as `--gemini_dir` so
|
|
26
|
+
* Antigravity reads/writes `<configDir>/antigravity-cli/...` instead of the
|
|
27
|
+
* user's default `~/.gemini/antigravity-cli/...`.
|
|
28
|
+
*/
|
|
29
|
+
configDir?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Explicit alias for `configDir` when matching the Antigravity CLI flag name.
|
|
32
|
+
*/
|
|
33
|
+
geminiDir?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Google API key for API-billed invocations when supported by the CLI.
|
|
36
|
+
*/
|
|
37
|
+
apiKey?: string;
|
|
38
|
+
};
|
|
@@ -458,6 +458,7 @@ export function extractUsageFromOutput(raw) {
|
|
|
458
458
|
const lines = stripOscSequences(raw).split(/\r?\n/).filter(Boolean);
|
|
459
459
|
const usage = {};
|
|
460
460
|
let found = false;
|
|
461
|
+
let countedIncremental = false;
|
|
461
462
|
for (const line of lines) {
|
|
462
463
|
let parsed;
|
|
463
464
|
try {
|
|
@@ -480,6 +481,7 @@ export function extractUsageFromOutput(raw) {
|
|
|
480
481
|
(usage.cacheWriteTokens ?? 0) + u.cache_creation_input_tokens;
|
|
481
482
|
}
|
|
482
483
|
found = true;
|
|
484
|
+
countedIncremental = true;
|
|
483
485
|
continue;
|
|
484
486
|
}
|
|
485
487
|
if (parsed.type === "message_delta" && parsed.usage) {
|
|
@@ -488,8 +490,19 @@ export function extractUsageFromOutput(raw) {
|
|
|
488
490
|
(usage.outputTokens ?? 0) + parsed.usage.output_tokens;
|
|
489
491
|
}
|
|
490
492
|
found = true;
|
|
493
|
+
countedIncremental = true;
|
|
491
494
|
continue;
|
|
492
495
|
}
|
|
496
|
+
if (parsed.type === "result") {
|
|
497
|
+
// Claude Code stream-json emits a terminal "result" event whose
|
|
498
|
+
// top-level usage summarizes tokens already accumulated from the
|
|
499
|
+
// per-message message_start/message_delta events. If we counted
|
|
500
|
+
// those incrementally, skip this event to avoid double-counting.
|
|
501
|
+
// Otherwise fall through so the usage is still captured.
|
|
502
|
+
if (countedIncremental) {
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
493
506
|
if (parsed.type === "turn.completed" && parsed.usage) {
|
|
494
507
|
const u = parsed.usage;
|
|
495
508
|
if (u.input_tokens) {
|
|
@@ -13,7 +13,7 @@ import { truncateToBytes } from "./truncateToBytes.js";
|
|
|
13
13
|
|
|
14
14
|
/** @typedef {import("./PiExtensionUiRequest.ts").PiExtensionUiRequest} PiExtensionUiRequest */
|
|
15
15
|
/**
|
|
16
|
-
* @typedef {{ cwd: string; env: Record<string, string>; prompt: string; timeoutMs?: number; idleTimeoutMs?: number; signal?: AbortSignal; maxOutputBytes?: number; onStdout?: (chunk: string) => void; onStderr?: (chunk: string) => void; onJsonEvent?: (event: Record<string, unknown>) => Promise<void> | void; onExtensionUiRequest?: (request: PiExtensionUiRequest) => Promise<PiExtensionUiResponse | null> | PiExtensionUiResponse | null; }} RunRpcCommandOptions
|
|
16
|
+
* @typedef {{ cwd: string; env: Record<string, string>; prompt: string; timeoutMs?: number; idleTimeoutMs?: number; signal?: AbortSignal; maxOutputBytes?: number; onStdout?: (chunk: string) => void; onStderr?: (chunk: string) => void; onJsonEvent?: (event: Record<string, unknown>) => Promise<void> | void; onExtensionUiRequest?: (request: PiExtensionUiRequest) => Promise<PiExtensionUiResponse | null> | PiExtensionUiResponse | null; spawnFn?: typeof spawn; }} RunRpcCommandOptions
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -61,7 +61,7 @@ function createInactivityTimer(timeoutMs, onTimeout) {
|
|
|
61
61
|
* @returns {Effect.Effect<{ text: string; output: unknown; stderr: string; exitCode: number | null; usage?: any; }, SmithersError>}
|
|
62
62
|
*/
|
|
63
63
|
export function runRpcCommandEffect(command, args, options) {
|
|
64
|
-
const { cwd, env, prompt, timeoutMs, idleTimeoutMs, signal, maxOutputBytes, onStdout, onStderr, onJsonEvent, onExtensionUiRequest, } = options;
|
|
64
|
+
const { cwd, env, prompt, timeoutMs, idleTimeoutMs, signal, maxOutputBytes, onStdout, onStderr, onJsonEvent, onExtensionUiRequest, spawnFn = spawn, } = options;
|
|
65
65
|
const span = `agent:${command}:rpc`;
|
|
66
66
|
const logAnnotations = {
|
|
67
67
|
agentCommand: command,
|
|
@@ -82,7 +82,7 @@ export function runRpcCommandEffect(command, args, options) {
|
|
|
82
82
|
let extractedUsage = undefined;
|
|
83
83
|
let stderrTruncated = false;
|
|
84
84
|
logDebug("starting agent RPC command", logAnnotations, span);
|
|
85
|
-
const child =
|
|
85
|
+
const child = spawnFn(command, args, {
|
|
86
86
|
cwd,
|
|
87
87
|
env,
|
|
88
88
|
detached: true,
|
|
@@ -108,6 +108,8 @@ export function runRpcCommandEffect(command, args, options) {
|
|
|
108
108
|
if (settled)
|
|
109
109
|
return;
|
|
110
110
|
settled = true;
|
|
111
|
+
inactivity.clear();
|
|
112
|
+
totalTimeout.clear();
|
|
111
113
|
if (signal) {
|
|
112
114
|
signal.removeEventListener("abort", onAbort);
|
|
113
115
|
}
|
|
@@ -131,6 +133,8 @@ export function runRpcCommandEffect(command, args, options) {
|
|
|
131
133
|
if (settled)
|
|
132
134
|
return;
|
|
133
135
|
settled = true;
|
|
136
|
+
inactivity.clear();
|
|
137
|
+
totalTimeout.clear();
|
|
134
138
|
if (signal) {
|
|
135
139
|
signal.removeEventListener("abort", onAbort);
|
|
136
140
|
}
|
|
@@ -9,5 +9,22 @@ export function truncateToBytes(text, maxBytes) {
|
|
|
9
9
|
const buf = Buffer.from(text, "utf8");
|
|
10
10
|
if (buf.length <= maxBytes)
|
|
11
11
|
return text;
|
|
12
|
-
|
|
12
|
+
let end = maxBytes;
|
|
13
|
+
// Back off any UTF-8 continuation bytes (0b10xxxxxx) so the slice ends on a
|
|
14
|
+
// codepoint boundary, then drop the lead byte if its sequence is incomplete.
|
|
15
|
+
while (end > 0 && (buf[end] & 0xc0) === 0x80)
|
|
16
|
+
end--;
|
|
17
|
+
if (end > 0) {
|
|
18
|
+
const lead = buf[end - 1];
|
|
19
|
+
let seqLen = 1;
|
|
20
|
+
if ((lead & 0xe0) === 0xc0)
|
|
21
|
+
seqLen = 2;
|
|
22
|
+
else if ((lead & 0xf0) === 0xe0)
|
|
23
|
+
seqLen = 3;
|
|
24
|
+
else if ((lead & 0xf8) === 0xf0)
|
|
25
|
+
seqLen = 4;
|
|
26
|
+
if ((end - 1) + seqLen > maxBytes)
|
|
27
|
+
end--;
|
|
28
|
+
}
|
|
29
|
+
return buf.subarray(0, end).toString("utf8");
|
|
13
30
|
}
|
package/src/CodexAgent.js
CHANGED
|
@@ -510,7 +510,7 @@ export class CodexAgent extends BaseCliAgent {
|
|
|
510
510
|
const resumeSession = typeof params.options?.resumeSession === "string"
|
|
511
511
|
? params.options.resumeSession
|
|
512
512
|
: undefined;
|
|
513
|
-
const args = resumeSession ? ["exec", "resume"
|
|
513
|
+
const args = resumeSession ? ["exec", "resume"] : ["exec"];
|
|
514
514
|
const yoloEnabled = this.opts.yolo ?? this.yolo;
|
|
515
515
|
const configOverrides = normalizeCodexConfig(this.opts.config);
|
|
516
516
|
for (const entry of configOverrides) {
|
|
@@ -520,21 +520,26 @@ export class CodexAgent extends BaseCliAgent {
|
|
|
520
520
|
pushList(args, "--disable", this.opts.disable);
|
|
521
521
|
pushList(args, "--image", this.opts.image);
|
|
522
522
|
pushFlag(args, "--model", this.opts.model ?? this.model);
|
|
523
|
-
if (this.opts.oss)
|
|
523
|
+
if (!resumeSession && this.opts.oss)
|
|
524
524
|
args.push("--oss");
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
525
|
+
if (!resumeSession)
|
|
526
|
+
pushFlag(args, "--local-provider", this.opts.localProvider);
|
|
527
|
+
if (!resumeSession)
|
|
528
|
+
pushFlag(args, "--sandbox", this.opts.sandbox);
|
|
529
|
+
if (!resumeSession)
|
|
530
|
+
pushFlag(args, "--profile", this.opts.profile);
|
|
531
|
+
if (!resumeSession && this.opts.fullAuto) {
|
|
529
532
|
args.push("--full-auto");
|
|
530
533
|
}
|
|
531
534
|
else if (yoloEnabled || this.opts.dangerouslyBypassApprovalsAndSandbox) {
|
|
532
535
|
args.push("--dangerously-bypass-approvals-and-sandbox");
|
|
533
536
|
}
|
|
534
|
-
|
|
537
|
+
if (!resumeSession)
|
|
538
|
+
pushFlag(args, "--cd", this.opts.cd);
|
|
535
539
|
if (this.opts.skipGitRepoCheck)
|
|
536
540
|
args.push("--skip-git-repo-check");
|
|
537
|
-
|
|
541
|
+
if (!resumeSession)
|
|
542
|
+
pushList(args, "--add-dir", this.opts.addDir);
|
|
538
543
|
if (!resumeSession) {
|
|
539
544
|
pushFlag(args, "--output-schema", this.opts.outputSchema);
|
|
540
545
|
}
|
|
@@ -562,6 +567,8 @@ export class CodexAgent extends BaseCliAgent {
|
|
|
562
567
|
pushFlag(args, "--output-last-message", outputFile);
|
|
563
568
|
if (this.extraArgs?.length)
|
|
564
569
|
args.push(...this.extraArgs);
|
|
570
|
+
if (resumeSession)
|
|
571
|
+
args.push(resumeSession);
|
|
565
572
|
const systemPrefix = params.systemPrompt
|
|
566
573
|
? `${params.systemPrompt}\n\n`
|
|
567
574
|
: "";
|
package/src/GeminiAgent.js
CHANGED
|
@@ -38,6 +38,10 @@ export function createGeminiCapabilityRegistry(opts = {}) {
|
|
|
38
38
|
builtIns: resolveGeminiBuiltIns(opts),
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Use AntigravityAgent for new Google CLI integrations. GeminiAgent
|
|
43
|
+
* remains for legacy and enterprise Gemini CLI setups.
|
|
44
|
+
*/
|
|
41
45
|
export class GeminiAgent extends BaseCliAgent {
|
|
42
46
|
opts;
|
|
43
47
|
capabilities;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { BaseCliAgentOptions } from "./BaseCliAgent/BaseCliAgentOptions";
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Use AntigravityAgentOptions with the Antigravity CLI (`agy`) for
|
|
5
|
+
* new Google CLI integrations. GeminiAgentOptions remains for legacy and
|
|
6
|
+
* enterprise Gemini CLI setups.
|
|
7
|
+
*/
|
|
3
8
|
export type GeminiAgentOptions = BaseCliAgentOptions & {
|
|
4
9
|
debug?: boolean;
|
|
5
10
|
model?: string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SmithersError } from "@smithers-orchestrator/errors/SmithersError";
|
|
2
|
+
import { OpenAIAgent } from "./OpenAIAgent.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @template [CALL_OPTIONS=never], [TOOLS=import("ai").ToolSet]
|
|
6
|
+
* @typedef {import("./HermesAgentOptions.ts").HermesAgentOptions<CALL_OPTIONS, TOOLS>} HermesAgentOptions
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Hermes (Nous Research) agent, reached over its OpenAI-compatible HTTP API.
|
|
11
|
+
*
|
|
12
|
+
* A thin wrapper over {@link OpenAIAgent}: it points the OpenAI-compatible
|
|
13
|
+
* provider at the Hermes server (`baseURL` / `HERMES_BASE_URL`) and disables AI
|
|
14
|
+
* SDK native structured output by default, since a local Hermes server may not
|
|
15
|
+
* honor JSON-schema response formats. Everything else — tool loops, streaming,
|
|
16
|
+
* prompt-based structured output — comes from the shared OpenAI path.
|
|
17
|
+
*
|
|
18
|
+
* @template [CALL_OPTIONS=never], [TOOLS=import("ai").ToolSet]
|
|
19
|
+
*/
|
|
20
|
+
export class HermesAgent extends OpenAIAgent {
|
|
21
|
+
/**
|
|
22
|
+
* @param {HermesAgentOptions<CALL_OPTIONS, TOOLS>} [opts]
|
|
23
|
+
*/
|
|
24
|
+
constructor(opts = {}) {
|
|
25
|
+
const {
|
|
26
|
+
model = "hermes",
|
|
27
|
+
baseURL = process.env.HERMES_BASE_URL,
|
|
28
|
+
apiKey = process.env.HERMES_API_KEY ?? "hermes",
|
|
29
|
+
nativeStructuredOutput = false,
|
|
30
|
+
...rest
|
|
31
|
+
} = opts;
|
|
32
|
+
if (baseURL === undefined) {
|
|
33
|
+
throw new SmithersError(
|
|
34
|
+
"AGENT_CONFIG_INVALID",
|
|
35
|
+
"HermesAgent requires a baseURL (or the HERMES_BASE_URL env var) pointing at the Hermes OpenAI-compatible API, e.g. http://127.0.0.1:5123/v1.",
|
|
36
|
+
{},
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
super({ ...rest, model, baseURL, apiKey, nativeStructuredOutput });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { openai } from "@ai-sdk/openai";
|
|
2
|
+
import type { ToolSet } from "ai";
|
|
3
|
+
import type { SdkAgentOptions } from "./SdkAgentOptions";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Options for {@link HermesAgent}.
|
|
7
|
+
*
|
|
8
|
+
* Hermes (Nous Research) exposes an OpenAI-compatible HTTP API
|
|
9
|
+
* (`/v1/chat/completions`), so a Hermes agent is reached the same way as any
|
|
10
|
+
* OpenAI-compatible endpoint: point `baseURL` at the Hermes server. These mirror
|
|
11
|
+
* the string-model form of `OpenAIAgentOptions`.
|
|
12
|
+
*/
|
|
13
|
+
export type HermesAgentOptions<
|
|
14
|
+
CALL_OPTIONS = never,
|
|
15
|
+
TOOLS extends ToolSet = {},
|
|
16
|
+
> = Omit<
|
|
17
|
+
SdkAgentOptions<CALL_OPTIONS, TOOLS, ReturnType<typeof openai>>,
|
|
18
|
+
"model"
|
|
19
|
+
> & {
|
|
20
|
+
/**
|
|
21
|
+
* Model name exposed by your Hermes server. Defaults to `"hermes"`; override
|
|
22
|
+
* with whatever model id the server advertises.
|
|
23
|
+
*/
|
|
24
|
+
model?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Base URL of the Hermes OpenAI-compatible API, e.g. `http://127.0.0.1:5123/v1`.
|
|
27
|
+
* Falls back to the `HERMES_BASE_URL` environment variable.
|
|
28
|
+
*/
|
|
29
|
+
baseURL?: string;
|
|
30
|
+
/**
|
|
31
|
+
* API key sent to the Hermes server. Falls back to `HERMES_API_KEY`, then
|
|
32
|
+
* `"hermes"` (local servers commonly ignore the value).
|
|
33
|
+
*/
|
|
34
|
+
apiKey?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Enable AI SDK native structured output. Off by default because a local
|
|
37
|
+
* Hermes server may not honor JSON-schema response formats — leaving it off
|
|
38
|
+
* makes Smithers fall back to prompt-based JSON extraction.
|
|
39
|
+
*/
|
|
40
|
+
nativeStructuredOutput?: boolean;
|
|
41
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AgentLike,
|
|
3
3
|
AmpAgent,
|
|
4
|
+
AntigravityAgent,
|
|
4
5
|
AnthropicAgent,
|
|
5
6
|
ClaudeCodeAgent,
|
|
6
7
|
CodexAgent,
|
|
@@ -20,6 +21,7 @@ type _CustomNativeStructuredAgent = AssertAssignable<{
|
|
|
20
21
|
|
|
21
22
|
type _ConcreteAgentsAreAgentLike = [
|
|
22
23
|
AssertAssignable<AmpAgent>,
|
|
24
|
+
AssertAssignable<AntigravityAgent>,
|
|
23
25
|
AssertAssignable<AnthropicAgent>,
|
|
24
26
|
AssertAssignable<ClaudeCodeAgent>,
|
|
25
27
|
AssertAssignable<CodexAgent>,
|
|
@@ -2,7 +2,7 @@ import type { AgentToolDescriptor } from "./AgentToolDescriptor";
|
|
|
2
2
|
|
|
3
3
|
export type AgentCapabilityRegistry = {
|
|
4
4
|
version: 1;
|
|
5
|
-
engine: "claude-code" | "codex" | "gemini" | "kimi" | "pi" | "amp" | "forge" | "opencode";
|
|
5
|
+
engine: "claude-code" | "codex" | "antigravity" | "gemini" | "kimi" | "pi" | "amp" | "forge" | "opencode";
|
|
6
6
|
runtimeTools: Record<string, AgentToolDescriptor>;
|
|
7
7
|
mcp: {
|
|
8
8
|
bootstrap: "inline-config" | "project-config" | "allow-list" | "unsupported";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { hashCapabilityRegistry, normalizeCapabilityRegistry, } from "../capability-registry/index.js";
|
|
2
|
+
import { createAntigravityCapabilityRegistry } from "../AntigravityAgent.js";
|
|
2
3
|
import { createClaudeCodeCapabilityRegistry } from "../ClaudeCodeAgent.js";
|
|
3
4
|
import { createCodexCapabilityRegistry } from "../CodexAgent.js";
|
|
4
5
|
import { createGeminiCapabilityRegistry } from "../GeminiAgent.js";
|
|
@@ -18,6 +19,11 @@ const CLI_AGENT_CAPABILITY_ADAPTERS = [
|
|
|
18
19
|
binary: "codex",
|
|
19
20
|
buildRegistry: () => createCodexCapabilityRegistry(),
|
|
20
21
|
},
|
|
22
|
+
{
|
|
23
|
+
id: "antigravity",
|
|
24
|
+
binary: "agy",
|
|
25
|
+
buildRegistry: () => createAntigravityCapabilityRegistry(),
|
|
26
|
+
},
|
|
21
27
|
{
|
|
22
28
|
id: "gemini",
|
|
23
29
|
binary: "gemini",
|
|
@@ -321,7 +321,7 @@ const codexStrategy = {
|
|
|
321
321
|
],
|
|
322
322
|
};
|
|
323
323
|
// ---------------------------------------------------------------------------
|
|
324
|
-
//
|
|
324
|
+
// Google CLI strategies
|
|
325
325
|
// ---------------------------------------------------------------------------
|
|
326
326
|
// Validate Google auth via GET /v1beta/models (free, no tokens)
|
|
327
327
|
const googleAuthCheck = {
|
|
@@ -438,6 +438,37 @@ const geminiStrategy = {
|
|
|
438
438
|
googleRateLimitCheck,
|
|
439
439
|
],
|
|
440
440
|
};
|
|
441
|
+
const antigravityAuthSkip = {
|
|
442
|
+
id: "api_key_valid",
|
|
443
|
+
run: async () => {
|
|
444
|
+
return {
|
|
445
|
+
id: "api_key_valid",
|
|
446
|
+
status: "skip",
|
|
447
|
+
message: "Antigravity CLI uses Google Sign-In/keyring auth; run `agy` to authenticate.",
|
|
448
|
+
durationMs: 0,
|
|
449
|
+
};
|
|
450
|
+
},
|
|
451
|
+
};
|
|
452
|
+
const antigravityRateLimitSkip = {
|
|
453
|
+
id: "rate_limit_status",
|
|
454
|
+
run: async () => {
|
|
455
|
+
return {
|
|
456
|
+
id: "rate_limit_status",
|
|
457
|
+
status: "skip",
|
|
458
|
+
message: "Antigravity CLI rate limits are checked by the CLI at runtime.",
|
|
459
|
+
durationMs: 0,
|
|
460
|
+
};
|
|
461
|
+
},
|
|
462
|
+
};
|
|
463
|
+
const antigravityStrategy = {
|
|
464
|
+
agentId: "antigravity",
|
|
465
|
+
command: "agy",
|
|
466
|
+
checks: [
|
|
467
|
+
checkCliInstalled("agy", "Antigravity CLI"),
|
|
468
|
+
antigravityAuthSkip,
|
|
469
|
+
antigravityRateLimitSkip,
|
|
470
|
+
],
|
|
471
|
+
};
|
|
441
472
|
// ---------------------------------------------------------------------------
|
|
442
473
|
// Pi strategy
|
|
443
474
|
// ---------------------------------------------------------------------------
|
|
@@ -490,6 +521,8 @@ const ampStrategy = {
|
|
|
490
521
|
const strategies = {
|
|
491
522
|
claude: claudeStrategy,
|
|
492
523
|
codex: codexStrategy,
|
|
524
|
+
antigravity: antigravityStrategy,
|
|
525
|
+
agy: antigravityStrategy,
|
|
493
526
|
gemini: geminiStrategy,
|
|
494
527
|
pi: piStrategy,
|
|
495
528
|
amp: ampStrategy,
|
|
@@ -19,10 +19,15 @@ const PER_CHECK_TIMEOUT_MS = 5_000;
|
|
|
19
19
|
*/
|
|
20
20
|
async function runCheck(check, ctx) {
|
|
21
21
|
const start = performance.now();
|
|
22
|
+
/** @type {ReturnType<typeof setTimeout> | undefined} */
|
|
23
|
+
let timeoutHandle;
|
|
22
24
|
try {
|
|
23
25
|
return await Promise.race([
|
|
24
26
|
check.run(ctx),
|
|
25
|
-
new Promise((_, reject) =>
|
|
27
|
+
new Promise((_, reject) => {
|
|
28
|
+
timeoutHandle = setTimeout(() => reject(new SmithersError("AGENT_DIAGNOSTIC_TIMEOUT", "diagnostic check timed out", { timeoutMs: PER_CHECK_TIMEOUT_MS })), PER_CHECK_TIMEOUT_MS);
|
|
29
|
+
timeoutHandle.unref?.();
|
|
30
|
+
}),
|
|
26
31
|
]);
|
|
27
32
|
}
|
|
28
33
|
catch (err) {
|
|
@@ -33,6 +38,9 @@ async function runCheck(check, ctx) {
|
|
|
33
38
|
durationMs: performance.now() - start,
|
|
34
39
|
};
|
|
35
40
|
}
|
|
41
|
+
finally {
|
|
42
|
+
clearTimeout(timeoutHandle);
|
|
43
|
+
}
|
|
36
44
|
}
|
|
37
45
|
/**
|
|
38
46
|
* @param {AgentDiagnosticStrategy} strategy
|
package/src/index.d.ts
CHANGED
|
@@ -138,7 +138,7 @@ type AgentToolDescriptor$1 = {
|
|
|
138
138
|
|
|
139
139
|
type AgentCapabilityRegistry$3 = {
|
|
140
140
|
version: 1;
|
|
141
|
-
engine: "claude-code" | "codex" | "gemini" | "kimi" | "pi" | "amp" | "forge" | "opencode";
|
|
141
|
+
engine: "claude-code" | "codex" | "antigravity" | "gemini" | "kimi" | "pi" | "amp" | "forge" | "opencode";
|
|
142
142
|
runtimeTools: Record<string, AgentToolDescriptor$1>;
|
|
143
143
|
mcp: {
|
|
144
144
|
bootstrap: "inline-config" | "project-config" | "allow-list" | "unsupported";
|
|
@@ -364,6 +364,19 @@ declare class OpenAIAgent extends ToolLoopAgent<never, any, never> {
|
|
|
364
364
|
type GenerateTextResult$1 = ai.GenerateTextResult<any, any>;
|
|
365
365
|
type OpenAIAgentOptions$1<CALL_OPTIONS = never, TOOLS = ai.ToolSet> = OpenAIAgentOptions$2<CALL_OPTIONS, TOOLS>;
|
|
366
366
|
|
|
367
|
+
type HermesAgentOptions$2<CALL_OPTIONS = never, TOOLS extends ToolSet = {}> = Omit<SdkAgentOptions<CALL_OPTIONS, TOOLS, ReturnType<typeof openai>>, "model"> & {
|
|
368
|
+
model?: string;
|
|
369
|
+
baseURL?: string;
|
|
370
|
+
apiKey?: string;
|
|
371
|
+
nativeStructuredOutput?: boolean;
|
|
372
|
+
};
|
|
373
|
+
/**
|
|
374
|
+
* Hermes (Nous Research) agent, reached over its OpenAI-compatible HTTP API.
|
|
375
|
+
*/
|
|
376
|
+
declare class HermesAgent extends OpenAIAgent {
|
|
377
|
+
constructor(opts?: HermesAgentOptions$2);
|
|
378
|
+
}
|
|
379
|
+
|
|
367
380
|
/**
|
|
368
381
|
* Configuration options for the AmpAgent.
|
|
369
382
|
*/
|
|
@@ -425,6 +438,57 @@ declare class AmpAgent extends BaseCliAgent {
|
|
|
425
438
|
type AmpAgentOptions = AmpAgentOptions$1;
|
|
426
439
|
type CliOutputInterpreter$6 = CliOutputInterpreter$8;
|
|
427
440
|
|
|
441
|
+
type AntigravityAgentOptions$1 = BaseCliAgentOptions$1 & {
|
|
442
|
+
debug?: boolean;
|
|
443
|
+
model?: string;
|
|
444
|
+
sandbox?: boolean;
|
|
445
|
+
yolo?: boolean;
|
|
446
|
+
dangerouslySkipPermissions?: boolean;
|
|
447
|
+
allowedMcpServerNames?: string[];
|
|
448
|
+
allowedTools?: string[];
|
|
449
|
+
extensions?: string[];
|
|
450
|
+
listExtensions?: boolean;
|
|
451
|
+
resume?: string;
|
|
452
|
+
listSessions?: boolean;
|
|
453
|
+
deleteSession?: string;
|
|
454
|
+
includeDirectories?: string[];
|
|
455
|
+
screenReader?: boolean;
|
|
456
|
+
outputFormat?: "text" | "json" | "stream-json";
|
|
457
|
+
binary?: string;
|
|
458
|
+
configDir?: string;
|
|
459
|
+
geminiDir?: string;
|
|
460
|
+
apiKey?: string;
|
|
461
|
+
};
|
|
462
|
+
declare function createAntigravityCapabilityRegistry(opts?: AntigravityAgentOptions): AgentCapabilityRegistry$3;
|
|
463
|
+
declare class AntigravityAgent extends BaseCliAgent {
|
|
464
|
+
/**
|
|
465
|
+
* @param {AntigravityAgentOptions} [opts]
|
|
466
|
+
*/
|
|
467
|
+
constructor(opts?: AntigravityAgentOptions);
|
|
468
|
+
opts: AntigravityAgentOptions$1;
|
|
469
|
+
capabilities: AgentCapabilityRegistry$3;
|
|
470
|
+
cliEngine: string;
|
|
471
|
+
/**
|
|
472
|
+
* @returns {CliOutputInterpreter}
|
|
473
|
+
*/
|
|
474
|
+
createOutputInterpreter(): CliOutputInterpreter$6;
|
|
475
|
+
/**
|
|
476
|
+
* @param {{ prompt: string; systemPrompt?: string; cwd: string; options: any; }} params
|
|
477
|
+
*/
|
|
478
|
+
buildCommand(params: {
|
|
479
|
+
prompt: string;
|
|
480
|
+
systemPrompt?: string;
|
|
481
|
+
cwd: string;
|
|
482
|
+
options: any;
|
|
483
|
+
}): Promise<{
|
|
484
|
+
command: string;
|
|
485
|
+
args: string[];
|
|
486
|
+
outputFormat: "text" | "json" | "stream-json";
|
|
487
|
+
env: Record<string, string> | undefined;
|
|
488
|
+
}>;
|
|
489
|
+
}
|
|
490
|
+
type AntigravityAgentOptions = AntigravityAgentOptions$1;
|
|
491
|
+
|
|
428
492
|
type ClaudeCodeAgentOptions$1 = BaseCliAgentOptions$1 & {
|
|
429
493
|
addDir?: string[];
|
|
430
494
|
agent?: string;
|
|
@@ -887,6 +951,7 @@ type AgentToolDescriptor = AgentToolDescriptor$1;
|
|
|
887
951
|
type AnthropicAgentOptions<CALL_OPTIONS = never, TOOLS = ai.ToolSet> = AnthropicAgentOptions$2<CALL_OPTIONS, TOOLS>;
|
|
888
952
|
type OpenCodeAgentOptions = OpenCodeAgentOptions$1;
|
|
889
953
|
type OpenAIAgentOptions<CALL_OPTIONS = never, TOOLS = ai.ToolSet> = OpenAIAgentOptions$2<CALL_OPTIONS, TOOLS>;
|
|
954
|
+
type HermesAgentOptions<CALL_OPTIONS = never, TOOLS = ai.ToolSet> = HermesAgentOptions$2<CALL_OPTIONS, TOOLS>;
|
|
890
955
|
type PiAgentOptions = PiAgentOptions$2;
|
|
891
956
|
type PiExtensionUiRequest = PiExtensionUiRequest$1;
|
|
892
957
|
type PiExtensionUiResponse = PiExtensionUiResponse$1;
|
|
@@ -896,4 +961,4 @@ type SmithersAgentToolCategory = SmithersAgentToolCategory$1;
|
|
|
896
961
|
type SmithersListedTool = SmithersListedTool$2;
|
|
897
962
|
type SmithersToolSurface = SmithersToolSurface$2;
|
|
898
963
|
|
|
899
|
-
export { type AgentCapabilityRegistry, type AgentGenerateOptions, type AgentLike, type AgentToolDescriptor, AmpAgent, AnthropicAgent, type AnthropicAgentOptions, BaseCliAgent, ClaudeCodeAgent, CodexAgent, ForgeAgent, GeminiAgent, KimiAgent, OpenAIAgent, type OpenAIAgentOptions, OpenCodeAgent, type OpenCodeAgentOptions, PiAgent, type PiAgentOptions, type PiExtensionUiRequest, type PiExtensionUiResponse, type SmithersAgentContract, type SmithersAgentContractTool, type SmithersAgentToolCategory, type SmithersListedTool, type SmithersToolSurface, createSmithersAgentContract, hashCapabilityRegistry, renderSmithersAgentPromptGuidance, sanitizeForOpenAI, zodToOpenAISchema };
|
|
964
|
+
export { type AgentCapabilityRegistry, type AgentGenerateOptions, type AgentLike, type AgentToolDescriptor, AmpAgent, AnthropicAgent, type AnthropicAgentOptions, AntigravityAgent, BaseCliAgent, ClaudeCodeAgent, CodexAgent, ForgeAgent, GeminiAgent, HermesAgent, type HermesAgentOptions, KimiAgent, OpenAIAgent, type OpenAIAgentOptions, OpenCodeAgent, type OpenCodeAgentOptions, PiAgent, type PiAgentOptions, type PiExtensionUiRequest, type PiExtensionUiResponse, type SmithersAgentContract, type SmithersAgentContractTool, type SmithersAgentToolCategory, type SmithersListedTool, type SmithersToolSurface, createAntigravityCapabilityRegistry, createSmithersAgentContract, hashCapabilityRegistry, renderSmithersAgentPromptGuidance, sanitizeForOpenAI, zodToOpenAISchema };
|
package/src/index.js
CHANGED
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
* @template [TOOLS=import("ai").ToolSet]
|
|
14
14
|
* @typedef {import("./OpenAIAgentOptions.ts").OpenAIAgentOptions<CALL_OPTIONS, TOOLS>} OpenAIAgentOptions
|
|
15
15
|
*/
|
|
16
|
+
/**
|
|
17
|
+
* @template [CALL_OPTIONS=never]
|
|
18
|
+
* @template [TOOLS=import("ai").ToolSet]
|
|
19
|
+
* @typedef {import("./HermesAgentOptions.ts").HermesAgentOptions<CALL_OPTIONS, TOOLS>} HermesAgentOptions
|
|
20
|
+
*/
|
|
16
21
|
/** @typedef {import("./PiAgentOptions.ts").PiAgentOptions} PiAgentOptions */
|
|
17
22
|
/** @typedef {import("./BaseCliAgent/PiExtensionUiRequest.ts").PiExtensionUiRequest} PiExtensionUiRequest */
|
|
18
23
|
/** @typedef {import("./BaseCliAgent/PiExtensionUiResponse.ts").PiExtensionUiResponse} PiExtensionUiResponse */
|
|
@@ -28,7 +33,9 @@ export { BaseCliAgent } from "./BaseCliAgent/index.js";
|
|
|
28
33
|
export { hashCapabilityRegistry } from "./capability-registry/index.js";
|
|
29
34
|
export { AnthropicAgent } from "./AnthropicAgent.js";
|
|
30
35
|
export { OpenAIAgent } from "./OpenAIAgent.js";
|
|
36
|
+
export { HermesAgent } from "./HermesAgent.js";
|
|
31
37
|
export { AmpAgent } from "./AmpAgent.js";
|
|
38
|
+
export { AntigravityAgent, createAntigravityCapabilityRegistry } from "./AntigravityAgent.js";
|
|
32
39
|
export { ClaudeCodeAgent } from "./ClaudeCodeAgent.js";
|
|
33
40
|
export { CodexAgent } from "./CodexAgent.js";
|
|
34
41
|
export { GeminiAgent } from "./GeminiAgent.js";
|