agent-devkit 0.5.7 → 0.6.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/README.md +27 -0
- package/dist/main.js +1293 -113
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/i18n/en-US.json +16 -0
- package/src/assets/i18n/fr-FR.json +16 -0
- package/src/assets/i18n/ja-JP.json +16 -0
- package/src/assets/i18n/pt-BR.json +16 -0
- package/src/assets/i18n/zh-CN.json +16 -0
- package/src/assets/prompts/core/domain-decision.json +33 -0
package/dist/main.js
CHANGED
|
@@ -8,7 +8,7 @@ import React from "react";
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "agent-devkit",
|
|
11
|
-
version: "0.
|
|
11
|
+
version: "0.6.0",
|
|
12
12
|
description: "Agent DevKit CLI and TUI runtime for specialist AI agents, capabilities and provider-aware workflows.",
|
|
13
13
|
license: "MIT",
|
|
14
14
|
type: "module",
|
|
@@ -4295,6 +4295,9 @@ function createEnvironmentSurface() {
|
|
|
4295
4295
|
// src/app/cli/toolRuntime.ts
|
|
4296
4296
|
import { homedir as homedir12 } from "os";
|
|
4297
4297
|
|
|
4298
|
+
// src/infra/brain/claude_cli_provider.ts
|
|
4299
|
+
import { execFile } from "child_process";
|
|
4300
|
+
|
|
4298
4301
|
// src/infra/helpers/tool_schema_summary.ts
|
|
4299
4302
|
var MAX_VARIANTS = 12;
|
|
4300
4303
|
var MAX_PROPS = 10;
|
|
@@ -4506,9 +4509,9 @@ var ModelStore = class {
|
|
|
4506
4509
|
await once(writeStream, "drain");
|
|
4507
4510
|
}
|
|
4508
4511
|
}
|
|
4509
|
-
await new Promise((
|
|
4512
|
+
await new Promise((resolve11, reject) => {
|
|
4510
4513
|
writeStream.on("error", reject);
|
|
4511
|
-
writeStream.end(() =>
|
|
4514
|
+
writeStream.end(() => resolve11());
|
|
4512
4515
|
});
|
|
4513
4516
|
} finally {
|
|
4514
4517
|
reader.releaseLock();
|
|
@@ -4756,6 +4759,16 @@ var LocalLlamaBrainProvider = class {
|
|
|
4756
4759
|
constructor(options = {}) {
|
|
4757
4760
|
this.#store = options.store ?? new ModelStore({ stateDirectory: options.stateDirectory });
|
|
4758
4761
|
}
|
|
4762
|
+
describe() {
|
|
4763
|
+
return {
|
|
4764
|
+
id: "local",
|
|
4765
|
+
kind: "local",
|
|
4766
|
+
supports: { embeddings: false, stream: true, structured: true }
|
|
4767
|
+
};
|
|
4768
|
+
}
|
|
4769
|
+
async isAvailable() {
|
|
4770
|
+
return (await this.#ensureNodeLlama()).isOk();
|
|
4771
|
+
}
|
|
4759
4772
|
generate(request) {
|
|
4760
4773
|
return this.#run(request);
|
|
4761
4774
|
}
|
|
@@ -4875,6 +4888,96 @@ var LocalLlamaBrainProvider = class {
|
|
|
4875
4888
|
}
|
|
4876
4889
|
};
|
|
4877
4890
|
|
|
4891
|
+
// src/infra/brain/claude_cli_provider.ts
|
|
4892
|
+
var defaultCommand = "claude";
|
|
4893
|
+
var defaultTimeoutMs = 12e4;
|
|
4894
|
+
var maxOutputBufferBytes = 16 * 1024 * 1024;
|
|
4895
|
+
function defaultExecutor(command, args, options) {
|
|
4896
|
+
return new Promise((resolve11) => {
|
|
4897
|
+
execFile(
|
|
4898
|
+
command,
|
|
4899
|
+
args,
|
|
4900
|
+
{ maxBuffer: maxOutputBufferBytes, timeout: options.timeoutMs },
|
|
4901
|
+
(error, stdout, stderr) => {
|
|
4902
|
+
if (error !== null) {
|
|
4903
|
+
resolve11(Result.fail(ErrorCodes.BrainProviderUnavailable));
|
|
4904
|
+
return;
|
|
4905
|
+
}
|
|
4906
|
+
resolve11(Result.ok({ stderr, stdout }));
|
|
4907
|
+
}
|
|
4908
|
+
);
|
|
4909
|
+
});
|
|
4910
|
+
}
|
|
4911
|
+
function parsePayload(stdout) {
|
|
4912
|
+
try {
|
|
4913
|
+
const payload = JSON.parse(stdout);
|
|
4914
|
+
if (typeof payload === "object" && payload !== null && typeof payload.result === "string") {
|
|
4915
|
+
const inputTokens = typeof payload.usage?.input_tokens === "number" ? payload.usage.input_tokens : void 0;
|
|
4916
|
+
const outputTokens2 = typeof payload.usage?.output_tokens === "number" ? payload.usage.output_tokens : void 0;
|
|
4917
|
+
const usage = inputTokens === void 0 && outputTokens2 === void 0 ? void 0 : { inputTokens, outputTokens: outputTokens2 };
|
|
4918
|
+
return { text: payload.result, usage };
|
|
4919
|
+
}
|
|
4920
|
+
} catch {
|
|
4921
|
+
}
|
|
4922
|
+
return { text: stdout.trim() };
|
|
4923
|
+
}
|
|
4924
|
+
var ClaudeCliBrainProvider = class {
|
|
4925
|
+
#command;
|
|
4926
|
+
#executor;
|
|
4927
|
+
#timeoutMs;
|
|
4928
|
+
#availability;
|
|
4929
|
+
constructor(options = {}) {
|
|
4930
|
+
this.#command = options.command ?? defaultCommand;
|
|
4931
|
+
this.#executor = options.executor ?? defaultExecutor;
|
|
4932
|
+
this.#timeoutMs = options.timeoutMs ?? defaultTimeoutMs;
|
|
4933
|
+
}
|
|
4934
|
+
describe() {
|
|
4935
|
+
return {
|
|
4936
|
+
id: "claude-cli",
|
|
4937
|
+
kind: "cli",
|
|
4938
|
+
supports: { embeddings: false, stream: false, structured: false }
|
|
4939
|
+
};
|
|
4940
|
+
}
|
|
4941
|
+
async isAvailable() {
|
|
4942
|
+
if (this.#availability !== void 0) {
|
|
4943
|
+
return this.#availability;
|
|
4944
|
+
}
|
|
4945
|
+
const probed = await this.#executor(this.#command, ["--version"], { timeoutMs: 1e4 });
|
|
4946
|
+
this.#availability = probed.isOk();
|
|
4947
|
+
return this.#availability;
|
|
4948
|
+
}
|
|
4949
|
+
async generate(request) {
|
|
4950
|
+
if (!await this.isAvailable()) {
|
|
4951
|
+
return Result.fail(ErrorCodes.BrainProviderUnavailable);
|
|
4952
|
+
}
|
|
4953
|
+
const promptText = [
|
|
4954
|
+
systemPromptFrom(request.prompt),
|
|
4955
|
+
"",
|
|
4956
|
+
`User: ${request.prompt.task.userMessage}`
|
|
4957
|
+
].join("\n");
|
|
4958
|
+
const args = ["-p", promptText, "--output-format", "json"];
|
|
4959
|
+
if (request.options.model !== void 0) {
|
|
4960
|
+
args.push("--model", request.options.model);
|
|
4961
|
+
}
|
|
4962
|
+
const executed = await this.#executor(this.#command, args, { timeoutMs: this.#timeoutMs });
|
|
4963
|
+
if (executed.isErr()) {
|
|
4964
|
+
return Result.fail(executed.unwrapError());
|
|
4965
|
+
}
|
|
4966
|
+
const { text: text2, usage } = parsePayload(executed.unwrap().stdout);
|
|
4967
|
+
if (text2.length === 0) {
|
|
4968
|
+
return Result.fail(ErrorCodes.BrainProviderUnavailable);
|
|
4969
|
+
}
|
|
4970
|
+
return Result.ok({
|
|
4971
|
+
finishReason: "stop",
|
|
4972
|
+
model: request.options.model,
|
|
4973
|
+
provider: "claude-cli",
|
|
4974
|
+
schema: "agent-devkit.brain-response/v1",
|
|
4975
|
+
text: text2,
|
|
4976
|
+
usage
|
|
4977
|
+
});
|
|
4978
|
+
}
|
|
4979
|
+
};
|
|
4980
|
+
|
|
4878
4981
|
// src/infra/brain/mock_provider.ts
|
|
4879
4982
|
function reply(request) {
|
|
4880
4983
|
const text2 = `Entendi. Vou responder no contexto da sess\xE3o atual: "${request.prompt.task.userMessage}".`;
|
|
@@ -4894,6 +4997,16 @@ function reply(request) {
|
|
|
4894
4997
|
};
|
|
4895
4998
|
}
|
|
4896
4999
|
var MockBrainProvider = class {
|
|
5000
|
+
describe() {
|
|
5001
|
+
return {
|
|
5002
|
+
id: "mock",
|
|
5003
|
+
kind: "local",
|
|
5004
|
+
supports: { embeddings: false, stream: true, structured: true }
|
|
5005
|
+
};
|
|
5006
|
+
}
|
|
5007
|
+
async isAvailable() {
|
|
5008
|
+
return true;
|
|
5009
|
+
}
|
|
4897
5010
|
async generate(request) {
|
|
4898
5011
|
return Result.ok(reply(request));
|
|
4899
5012
|
}
|
|
@@ -4911,83 +5024,183 @@ var MockBrainProvider = class {
|
|
|
4911
5024
|
}
|
|
4912
5025
|
};
|
|
4913
5026
|
|
|
5027
|
+
// src/infra/brain/structured_text_fallback.ts
|
|
5028
|
+
function extractJsonObject(text2) {
|
|
5029
|
+
const start = text2.indexOf("{");
|
|
5030
|
+
const end = text2.lastIndexOf("}");
|
|
5031
|
+
if (start === -1 || end === -1 || end <= start) {
|
|
5032
|
+
return void 0;
|
|
5033
|
+
}
|
|
5034
|
+
try {
|
|
5035
|
+
return JSON.parse(text2.slice(start, end + 1));
|
|
5036
|
+
} catch {
|
|
5037
|
+
return void 0;
|
|
5038
|
+
}
|
|
5039
|
+
}
|
|
5040
|
+
function withJsonInstruction(request, jsonSchema) {
|
|
5041
|
+
const instruction = [
|
|
5042
|
+
request.prompt.task.userMessage,
|
|
5043
|
+
"",
|
|
5044
|
+
"Responda SOMENTE com um objeto JSON v\xE1lido que satisfa\xE7a este JSON Schema:",
|
|
5045
|
+
JSON.stringify(jsonSchema),
|
|
5046
|
+
"Sem markdown, sem cercas de c\xF3digo, sem texto antes ou depois do JSON."
|
|
5047
|
+
].join("\n");
|
|
5048
|
+
return {
|
|
5049
|
+
...request,
|
|
5050
|
+
prompt: {
|
|
5051
|
+
...request.prompt,
|
|
5052
|
+
output: { ...request.prompt.output, format: "json" },
|
|
5053
|
+
task: { ...request.prompt.task, userMessage: instruction }
|
|
5054
|
+
}
|
|
5055
|
+
};
|
|
5056
|
+
}
|
|
5057
|
+
function withRepairInstruction(request, previousRaw) {
|
|
5058
|
+
const instruction = [
|
|
5059
|
+
request.prompt.task.userMessage,
|
|
5060
|
+
"",
|
|
5061
|
+
"A resposta anterior n\xE3o era um JSON v\xE1lido:",
|
|
5062
|
+
previousRaw.slice(0, 800),
|
|
5063
|
+
"Corrija e responda apenas com o objeto JSON v\xE1lido."
|
|
5064
|
+
].join("\n");
|
|
5065
|
+
return {
|
|
5066
|
+
...request,
|
|
5067
|
+
prompt: { ...request.prompt, task: { ...request.prompt.task, userMessage: instruction } }
|
|
5068
|
+
};
|
|
5069
|
+
}
|
|
5070
|
+
async function generateStructuredViaText(provider, request, jsonSchema) {
|
|
5071
|
+
const constrained = withJsonInstruction(request, jsonSchema);
|
|
5072
|
+
const first = await provider.generate(constrained);
|
|
5073
|
+
if (first.isErr()) {
|
|
5074
|
+
return Result.fail(first.unwrapError());
|
|
5075
|
+
}
|
|
5076
|
+
const firstRaw = first.unwrap().text;
|
|
5077
|
+
const firstJson = extractJsonObject(firstRaw);
|
|
5078
|
+
if (firstJson !== void 0) {
|
|
5079
|
+
return Result.ok({ json: firstJson, raw: firstRaw });
|
|
5080
|
+
}
|
|
5081
|
+
const repaired = await provider.generate(withRepairInstruction(constrained, firstRaw));
|
|
5082
|
+
if (repaired.isErr()) {
|
|
5083
|
+
return Result.fail(repaired.unwrapError());
|
|
5084
|
+
}
|
|
5085
|
+
const repairedRaw = repaired.unwrap().text;
|
|
5086
|
+
const repairedJson = extractJsonObject(repairedRaw);
|
|
5087
|
+
if (repairedJson === void 0) {
|
|
5088
|
+
return Result.fail(ErrorCodes.InvalidInput);
|
|
5089
|
+
}
|
|
5090
|
+
return Result.ok({ json: repairedJson, raw: repairedRaw });
|
|
5091
|
+
}
|
|
5092
|
+
|
|
4914
5093
|
// src/infra/brain/brain_dock.ts
|
|
4915
|
-
var
|
|
5094
|
+
var defaultRouting = {
|
|
5095
|
+
agent: ["claude-cli", "local", "mock"],
|
|
5096
|
+
chat: ["claude-cli", "local", "mock"],
|
|
5097
|
+
embed: ["local"]
|
|
5098
|
+
};
|
|
4916
5099
|
var fallbackProvider = "mock";
|
|
5100
|
+
var defaultRole = "chat";
|
|
4917
5101
|
function shouldFallback(error) {
|
|
4918
5102
|
return error === ErrorCodes.BrainProviderUnavailable || error === ErrorCodes.ModelNotFound;
|
|
4919
5103
|
}
|
|
5104
|
+
function chainFromEnv(role) {
|
|
5105
|
+
const raw = process.env[`AGENT_DEVKIT_BRAIN_${role.toUpperCase()}`];
|
|
5106
|
+
if (raw === void 0) {
|
|
5107
|
+
return void 0;
|
|
5108
|
+
}
|
|
5109
|
+
const chain = raw.split(",").map((id) => id.trim()).filter((id) => id.length > 0);
|
|
5110
|
+
return chain.length > 0 ? chain : void 0;
|
|
5111
|
+
}
|
|
5112
|
+
function resolveRouting(overrides = {}) {
|
|
5113
|
+
const roles = ["agent", "chat", "embed"];
|
|
5114
|
+
const routing = { ...defaultRouting };
|
|
5115
|
+
for (const role of roles) {
|
|
5116
|
+
routing[role] = overrides[role] ?? chainFromEnv(role) ?? routing[role];
|
|
5117
|
+
}
|
|
5118
|
+
return routing;
|
|
5119
|
+
}
|
|
4920
5120
|
var BrainDockProvider = class {
|
|
4921
5121
|
#factories;
|
|
4922
5122
|
#instances = /* @__PURE__ */ new Map();
|
|
5123
|
+
#routing;
|
|
4923
5124
|
constructor(options = {}) {
|
|
5125
|
+
this.#routing = resolveRouting(options.routing);
|
|
4924
5126
|
this.#factories = /* @__PURE__ */ new Map([
|
|
5127
|
+
["claude-cli", () => new ClaudeCliBrainProvider()],
|
|
4925
5128
|
["local", () => new LocalLlamaBrainProvider({ stateDirectory: options.stateDirectory })],
|
|
4926
5129
|
["mock", () => new MockBrainProvider()]
|
|
4927
5130
|
]);
|
|
5131
|
+
for (const [id, factory] of Object.entries(options.providers ?? {})) {
|
|
5132
|
+
this.#factories.set(id, factory);
|
|
5133
|
+
}
|
|
5134
|
+
}
|
|
5135
|
+
async describeProviders() {
|
|
5136
|
+
const statuses = [];
|
|
5137
|
+
for (const id of this.#factories.keys()) {
|
|
5138
|
+
const provider = this.#resolveById(id);
|
|
5139
|
+
const descriptor = provider.describe?.() ?? {
|
|
5140
|
+
id,
|
|
5141
|
+
kind: "local",
|
|
5142
|
+
supports: { embeddings: false, stream: false, structured: false }
|
|
5143
|
+
};
|
|
5144
|
+
const available = await provider.isAvailable?.() ?? true;
|
|
5145
|
+
statuses.push({ ...descriptor, available });
|
|
5146
|
+
}
|
|
5147
|
+
return statuses;
|
|
5148
|
+
}
|
|
5149
|
+
routingPolicy() {
|
|
5150
|
+
return { ...this.#routing };
|
|
4928
5151
|
}
|
|
4929
5152
|
async generate(request) {
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
5153
|
+
return this.#withChain(request, (provider, chained) => provider.generate(chained));
|
|
5154
|
+
}
|
|
5155
|
+
async generateStream(request, onToken) {
|
|
5156
|
+
return this.#withChain(request, async (provider, chained) => {
|
|
5157
|
+
if (provider.generateStream !== void 0) {
|
|
5158
|
+
return provider.generateStream(chained, onToken);
|
|
5159
|
+
}
|
|
5160
|
+
const response = await provider.generate(chained);
|
|
5161
|
+
if (response.isOk()) {
|
|
5162
|
+
onToken(response.unwrap().text);
|
|
5163
|
+
}
|
|
4933
5164
|
return response;
|
|
4934
|
-
}
|
|
4935
|
-
return this.#resolveById(fallbackProvider).generate({
|
|
4936
|
-
...request,
|
|
4937
|
-
options: { ...request.options, provider: fallbackProvider }
|
|
4938
5165
|
});
|
|
4939
5166
|
}
|
|
4940
|
-
async
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
if (response2.isOk() || request.options.provider === fallbackProvider || !shouldFallback(response2.unwrapError())) {
|
|
4945
|
-
return response2;
|
|
5167
|
+
async generateStructured(request, jsonSchema) {
|
|
5168
|
+
return this.#withChain(request, (provider, chained) => {
|
|
5169
|
+
if (provider.generateStructured !== void 0) {
|
|
5170
|
+
return provider.generateStructured(chained, jsonSchema);
|
|
4946
5171
|
}
|
|
4947
|
-
return
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
) ?? this.#resolveById(fallbackProvider).generate({
|
|
4954
|
-
...request,
|
|
4955
|
-
options: { ...request.options, provider: fallbackProvider }
|
|
4956
|
-
});
|
|
4957
|
-
}
|
|
4958
|
-
const response = await provider.generate(request);
|
|
4959
|
-
if (response.isOk()) {
|
|
4960
|
-
onToken(response.unwrap().text);
|
|
5172
|
+
return generateStructuredViaText(provider, chained, jsonSchema);
|
|
5173
|
+
});
|
|
5174
|
+
}
|
|
5175
|
+
#chainFor(request) {
|
|
5176
|
+
if (request.options.provider !== void 0) {
|
|
5177
|
+
return request.options.provider === fallbackProvider ? [fallbackProvider] : [request.options.provider, fallbackProvider];
|
|
4961
5178
|
}
|
|
4962
|
-
return
|
|
5179
|
+
return this.#routing[request.options.role ?? defaultRole];
|
|
4963
5180
|
}
|
|
4964
|
-
async
|
|
4965
|
-
const
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
5181
|
+
async #withChain(request, operation) {
|
|
5182
|
+
const chain = this.#chainFor(request);
|
|
5183
|
+
let lastError = ErrorCodes.BrainProviderUnavailable;
|
|
5184
|
+
for (const id of chain) {
|
|
5185
|
+
const provider = this.#resolveById(id);
|
|
5186
|
+
const chained = {
|
|
5187
|
+
...request,
|
|
5188
|
+
options: { ...request.options, provider: id }
|
|
5189
|
+
};
|
|
5190
|
+
const response = await operation(provider, chained);
|
|
5191
|
+
if (response.isOk() || !shouldFallback(response.unwrapError())) {
|
|
4969
5192
|
return response;
|
|
4970
5193
|
}
|
|
4971
|
-
|
|
4972
|
-
{
|
|
4973
|
-
...request,
|
|
4974
|
-
options: { ...request.options, provider: fallbackProvider }
|
|
4975
|
-
},
|
|
4976
|
-
jsonSchema
|
|
4977
|
-
) ?? Result.fail(ErrorCodes.BrainProviderUnavailable);
|
|
5194
|
+
lastError = response.unwrapError();
|
|
4978
5195
|
}
|
|
4979
|
-
return Result.fail(
|
|
4980
|
-
}
|
|
4981
|
-
#resolve(request) {
|
|
4982
|
-
const id = request.options.provider ?? defaultProvider;
|
|
4983
|
-
return this.#resolveById(id);
|
|
5196
|
+
return Result.fail(lastError);
|
|
4984
5197
|
}
|
|
4985
5198
|
#resolveById(id) {
|
|
4986
5199
|
const cached = this.#instances.get(id);
|
|
4987
5200
|
if (cached !== void 0) {
|
|
4988
5201
|
return cached;
|
|
4989
5202
|
}
|
|
4990
|
-
const factory = this.#factories.get(id)
|
|
5203
|
+
const factory = this.#factories.get(id);
|
|
4991
5204
|
const provider = factory === void 0 ? new MockBrainProvider() : factory();
|
|
4992
5205
|
this.#instances.set(id, provider);
|
|
4993
5206
|
return provider;
|
|
@@ -8787,12 +9000,13 @@ import { z as z27 } from "zod";
|
|
|
8787
9000
|
|
|
8788
9001
|
// src/infra/bases/brain.ts
|
|
8789
9002
|
import { z as z26 } from "zod";
|
|
9003
|
+
var BrainRoleSchema = z26.enum(["agent", "chat", "embed"]);
|
|
8790
9004
|
var BrainGenerationOptionsSchema = z26.object({
|
|
8791
9005
|
maxInputTokens: z26.number().int().positive().optional(),
|
|
8792
9006
|
maxOutputTokens: z26.number().int().positive().optional(),
|
|
8793
9007
|
model: z26.string().min(1).optional(),
|
|
8794
|
-
provider: z26.
|
|
8795
|
-
role:
|
|
9008
|
+
provider: z26.string().min(1).optional(),
|
|
9009
|
+
role: BrainRoleSchema.optional(),
|
|
8796
9010
|
seed: z26.number().int().optional(),
|
|
8797
9011
|
stop: z26.array(z26.string().min(1)).optional(),
|
|
8798
9012
|
stream: z26.boolean().optional(),
|
|
@@ -8801,7 +9015,7 @@ var BrainGenerationOptionsSchema = z26.object({
|
|
|
8801
9015
|
topP: z26.number().min(0).max(1).optional()
|
|
8802
9016
|
}).strict();
|
|
8803
9017
|
var BrainRequestSchema = z26.object({
|
|
8804
|
-
options: BrainGenerationOptionsSchema.default({
|
|
9018
|
+
options: BrainGenerationOptionsSchema.default({}),
|
|
8805
9019
|
prompt: AgentPromptSchema,
|
|
8806
9020
|
schema: z26.literal("agent-devkit.brain-request/v1")
|
|
8807
9021
|
}).strict();
|
|
@@ -8912,7 +9126,7 @@ var ConversationChatService = class extends BaseCapabilityService {
|
|
|
8912
9126
|
return Result.fail(prepared.unwrapError());
|
|
8913
9127
|
}
|
|
8914
9128
|
const request = {
|
|
8915
|
-
options: {
|
|
9129
|
+
options: { ...parsed.data.brain, role: "chat" },
|
|
8916
9130
|
prompt: prepared.unwrap().prompt,
|
|
8917
9131
|
schema: "agent-devkit.brain-request/v1"
|
|
8918
9132
|
};
|
|
@@ -11481,9 +11695,9 @@ function createSecretsSurface() {
|
|
|
11481
11695
|
}
|
|
11482
11696
|
|
|
11483
11697
|
// src/modules/self/capabilities/update/update.repository.ts
|
|
11484
|
-
import { execFile } from "child_process";
|
|
11698
|
+
import { execFile as execFile2 } from "child_process";
|
|
11485
11699
|
import { promisify } from "util";
|
|
11486
|
-
var execFileAsync = promisify(
|
|
11700
|
+
var execFileAsync = promisify(execFile2);
|
|
11487
11701
|
var UpdateRepository = class {
|
|
11488
11702
|
repositoryId = "self.update.repository";
|
|
11489
11703
|
async getPackageVersions(packageName) {
|
|
@@ -12369,6 +12583,19 @@ var agentRouteJsonSchema = {
|
|
|
12369
12583
|
},
|
|
12370
12584
|
required: ["action"]
|
|
12371
12585
|
};
|
|
12586
|
+
var AgentDomainRouteSchema = z41.discriminatedUnion("action", [
|
|
12587
|
+
z41.object({ action: z41.literal("domains"), domains: z41.array(z41.string().min(1)).min(1) }),
|
|
12588
|
+
z41.object({ action: z41.literal("final"), reply: z41.string() })
|
|
12589
|
+
]);
|
|
12590
|
+
var agentDomainRouteJsonSchema = {
|
|
12591
|
+
type: "object",
|
|
12592
|
+
properties: {
|
|
12593
|
+
action: { type: "string", enum: ["domains", "final"] },
|
|
12594
|
+
domains: { type: "array", items: { type: "string" } },
|
|
12595
|
+
reply: { type: "string" }
|
|
12596
|
+
},
|
|
12597
|
+
required: ["action"]
|
|
12598
|
+
};
|
|
12372
12599
|
var AgentPlanStepSchema = z41.object({
|
|
12373
12600
|
dependsOn: z41.array(z41.string().min(1)).default([]),
|
|
12374
12601
|
id: z41.string().min(1),
|
|
@@ -12515,6 +12742,24 @@ async function buildToolDecisionPrompt(input) {
|
|
|
12515
12742
|
}
|
|
12516
12743
|
});
|
|
12517
12744
|
}
|
|
12745
|
+
async function buildDomainDecisionPrompt(input) {
|
|
12746
|
+
return promptComposer.compose("core/domain-decision", {
|
|
12747
|
+
agent: input.agent ?? agentPersona,
|
|
12748
|
+
context: {
|
|
12749
|
+
knowledge: recoveredKnowledge({
|
|
12750
|
+
contextSnapshot: input.contextSnapshot,
|
|
12751
|
+
memories: input.memories
|
|
12752
|
+
}),
|
|
12753
|
+
project: input.contextSnapshot?.project,
|
|
12754
|
+
session: input.contextSnapshot?.session
|
|
12755
|
+
},
|
|
12756
|
+
messages: input.transcript,
|
|
12757
|
+
variables: {
|
|
12758
|
+
domains: input.domains.map((domain) => `- ${domain.id} (${domain.toolCount} tools): ${domain.summary}`).join("\n"),
|
|
12759
|
+
task: input.task
|
|
12760
|
+
}
|
|
12761
|
+
});
|
|
12762
|
+
}
|
|
12518
12763
|
async function buildTaskPlanPrompt(input) {
|
|
12519
12764
|
return promptComposer.compose("core/task-plan", {
|
|
12520
12765
|
agent: input.agent ?? agentPersona,
|
|
@@ -12623,6 +12868,178 @@ function approvalGrantForTool(tool, input) {
|
|
|
12623
12868
|
});
|
|
12624
12869
|
}
|
|
12625
12870
|
|
|
12871
|
+
// src/agent/agent.router.ts
|
|
12872
|
+
var defaultMaxToolsPerDecision = 20;
|
|
12873
|
+
var maxDomainSummaryLength = 200;
|
|
12874
|
+
function truncate(text2, length) {
|
|
12875
|
+
const compact3 = text2.replaceAll(/\s+/g, " ").trim();
|
|
12876
|
+
return compact3.length > length ? `${compact3.slice(0, length)}...` : compact3;
|
|
12877
|
+
}
|
|
12878
|
+
function approximatePromptTokens(prompt) {
|
|
12879
|
+
return Math.ceil(JSON.stringify(prompt).length / 4);
|
|
12880
|
+
}
|
|
12881
|
+
function domainsFor(tools, knowledge) {
|
|
12882
|
+
const byModule = /* @__PURE__ */ new Map();
|
|
12883
|
+
for (const tool of tools) {
|
|
12884
|
+
const grouped = byModule.get(tool.moduleId) ?? [];
|
|
12885
|
+
grouped.push(tool);
|
|
12886
|
+
byModule.set(tool.moduleId, grouped);
|
|
12887
|
+
}
|
|
12888
|
+
const knowledgeById = new Map(knowledge.map((module) => [module.moduleId, module]));
|
|
12889
|
+
return [...byModule.entries()].map(([moduleId, moduleTools]) => {
|
|
12890
|
+
const surface = knowledgeById.get(moduleId);
|
|
12891
|
+
const parts = [];
|
|
12892
|
+
if (surface !== void 0 && surface.summary.length > 0) {
|
|
12893
|
+
parts.push(surface.summary);
|
|
12894
|
+
}
|
|
12895
|
+
if (surface !== void 0 && surface.whenToUse.length > 0) {
|
|
12896
|
+
parts.push(`Use when: ${surface.whenToUse.join(" ")}`);
|
|
12897
|
+
}
|
|
12898
|
+
if (parts.length === 0) {
|
|
12899
|
+
parts.push(
|
|
12900
|
+
moduleTools.slice(0, 3).map((tool) => tool.description).join(" ")
|
|
12901
|
+
);
|
|
12902
|
+
}
|
|
12903
|
+
return {
|
|
12904
|
+
id: moduleId,
|
|
12905
|
+
summary: truncate(parts.join(" "), maxDomainSummaryLength),
|
|
12906
|
+
toolCount: moduleTools.length
|
|
12907
|
+
};
|
|
12908
|
+
});
|
|
12909
|
+
}
|
|
12910
|
+
var AgentToolRouter = class {
|
|
12911
|
+
#maxToolsPerDecision;
|
|
12912
|
+
constructor(options = {}) {
|
|
12913
|
+
this.#maxToolsPerDecision = options.maxToolsPerDecision ?? defaultMaxToolsPerDecision;
|
|
12914
|
+
}
|
|
12915
|
+
async route(input) {
|
|
12916
|
+
const scoped = await this.#scopeTools(input);
|
|
12917
|
+
if (scoped.isErr()) {
|
|
12918
|
+
return Result.fail(scoped.unwrapError());
|
|
12919
|
+
}
|
|
12920
|
+
const scopedValue = scoped.unwrap();
|
|
12921
|
+
if ("reply" in scopedValue) {
|
|
12922
|
+
return Result.ok(scopedValue);
|
|
12923
|
+
}
|
|
12924
|
+
return this.#decideTool(input, scopedValue.tools);
|
|
12925
|
+
}
|
|
12926
|
+
async #scopeTools(input) {
|
|
12927
|
+
if (input.tools.length <= this.#maxToolsPerDecision) {
|
|
12928
|
+
return Result.ok({ tools: input.tools });
|
|
12929
|
+
}
|
|
12930
|
+
const domains = domainsFor(input.tools, input.knowledge);
|
|
12931
|
+
const prompt = await buildDomainDecisionPrompt({
|
|
12932
|
+
agent: input.agent,
|
|
12933
|
+
contextSnapshot: input.contextSnapshot,
|
|
12934
|
+
domains,
|
|
12935
|
+
memories: input.memories,
|
|
12936
|
+
task: input.task,
|
|
12937
|
+
transcript: input.transcript
|
|
12938
|
+
});
|
|
12939
|
+
if (prompt.isErr()) {
|
|
12940
|
+
await input.onEvent?.({
|
|
12941
|
+
payload: { code: prompt.unwrapError(), phase: "route-domains-prompt" },
|
|
12942
|
+
type: "error"
|
|
12943
|
+
});
|
|
12944
|
+
return Result.fail(prompt.unwrapError());
|
|
12945
|
+
}
|
|
12946
|
+
const routed = await input.generateStructured(
|
|
12947
|
+
{
|
|
12948
|
+
options: { role: "agent" },
|
|
12949
|
+
prompt: prompt.unwrap(),
|
|
12950
|
+
schema: "agent-devkit.brain-request/v1"
|
|
12951
|
+
},
|
|
12952
|
+
agentDomainRouteJsonSchema
|
|
12953
|
+
);
|
|
12954
|
+
if (routed.isErr()) {
|
|
12955
|
+
await input.onEvent?.({
|
|
12956
|
+
payload: { code: routed.unwrapError(), phase: "route-domains" },
|
|
12957
|
+
type: "error"
|
|
12958
|
+
});
|
|
12959
|
+
return Result.fail(routed.unwrapError());
|
|
12960
|
+
}
|
|
12961
|
+
const route = AgentDomainRouteSchema.safeParse(routed.unwrap().json);
|
|
12962
|
+
if (!route.success) {
|
|
12963
|
+
await input.onEvent?.({
|
|
12964
|
+
payload: { phase: "route-domains", raw: routed.unwrap().raw },
|
|
12965
|
+
type: "error"
|
|
12966
|
+
});
|
|
12967
|
+
return Result.fail(ErrorCodes.InvalidInput);
|
|
12968
|
+
}
|
|
12969
|
+
if (route.data.action === "final") {
|
|
12970
|
+
return Result.ok({ reply: route.data.reply });
|
|
12971
|
+
}
|
|
12972
|
+
const selected = new Set(route.data.domains.slice(0, 2));
|
|
12973
|
+
const known = new Set(domains.map((domain) => domain.id));
|
|
12974
|
+
const validSelection = [...selected].filter((domain) => known.has(domain));
|
|
12975
|
+
const scoped = validSelection.length === 0 ? input.tools : input.tools.filter((tool) => selected.has(tool.moduleId));
|
|
12976
|
+
await input.onEvent?.({
|
|
12977
|
+
payload: {
|
|
12978
|
+
approximatePromptTokens: approximatePromptTokens(prompt.unwrap()),
|
|
12979
|
+
domainCount: domains.length,
|
|
12980
|
+
domains: validSelection,
|
|
12981
|
+
phase: "route-domains",
|
|
12982
|
+
scopedToolCount: Math.min(scoped.length, this.#maxToolsPerDecision),
|
|
12983
|
+
totalToolCount: input.tools.length
|
|
12984
|
+
},
|
|
12985
|
+
type: "thought"
|
|
12986
|
+
});
|
|
12987
|
+
return Result.ok({ tools: scoped.slice(0, this.#maxToolsPerDecision) });
|
|
12988
|
+
}
|
|
12989
|
+
async #decideTool(input, tools) {
|
|
12990
|
+
const prompt = await buildToolDecisionPrompt({
|
|
12991
|
+
agent: input.agent,
|
|
12992
|
+
contextSnapshot: input.contextSnapshot,
|
|
12993
|
+
knowledge: input.knowledge.filter(
|
|
12994
|
+
(module) => tools.some((tool) => tool.moduleId === module.moduleId)
|
|
12995
|
+
),
|
|
12996
|
+
memories: input.memories,
|
|
12997
|
+
task: input.task,
|
|
12998
|
+
tools,
|
|
12999
|
+
transcript: input.transcript
|
|
13000
|
+
});
|
|
13001
|
+
if (prompt.isErr()) {
|
|
13002
|
+
await input.onEvent?.({
|
|
13003
|
+
payload: { code: prompt.unwrapError(), phase: "route-prompt" },
|
|
13004
|
+
type: "error"
|
|
13005
|
+
});
|
|
13006
|
+
return Result.fail(prompt.unwrapError());
|
|
13007
|
+
}
|
|
13008
|
+
const routed = await input.generateStructured(
|
|
13009
|
+
{
|
|
13010
|
+
options: { role: "agent" },
|
|
13011
|
+
prompt: prompt.unwrap(),
|
|
13012
|
+
schema: "agent-devkit.brain-request/v1"
|
|
13013
|
+
},
|
|
13014
|
+
agentRouteJsonSchema
|
|
13015
|
+
);
|
|
13016
|
+
if (routed.isErr()) {
|
|
13017
|
+
await input.onEvent?.({
|
|
13018
|
+
payload: { code: routed.unwrapError(), phase: "route" },
|
|
13019
|
+
type: "error"
|
|
13020
|
+
});
|
|
13021
|
+
return Result.fail(routed.unwrapError());
|
|
13022
|
+
}
|
|
13023
|
+
const route = AgentRouteSchema.safeParse(routed.unwrap().json);
|
|
13024
|
+
if (!route.success) {
|
|
13025
|
+
await input.onEvent?.({
|
|
13026
|
+
payload: { phase: "route", raw: routed.unwrap().raw },
|
|
13027
|
+
type: "error"
|
|
13028
|
+
});
|
|
13029
|
+
return Result.fail(ErrorCodes.InvalidInput);
|
|
13030
|
+
}
|
|
13031
|
+
await input.onEvent?.({
|
|
13032
|
+
payload: {
|
|
13033
|
+
approximatePromptTokens: approximatePromptTokens(prompt.unwrap()),
|
|
13034
|
+
phase: "route-tool",
|
|
13035
|
+
toolCount: tools.length
|
|
13036
|
+
},
|
|
13037
|
+
type: "thought"
|
|
13038
|
+
});
|
|
13039
|
+
return route.data.action === "final" ? Result.ok({ reply: route.data.reply }) : Result.ok({ tool: route.data.tool });
|
|
13040
|
+
}
|
|
13041
|
+
};
|
|
13042
|
+
|
|
12626
13043
|
// src/agent/agent.loop.ts
|
|
12627
13044
|
function summarize(value) {
|
|
12628
13045
|
const text2 = typeof value === "string" ? value : JSON.stringify(value ?? "");
|
|
@@ -12648,6 +13065,7 @@ var AgentToolLoop = class {
|
|
|
12648
13065
|
#contextAssembler;
|
|
12649
13066
|
#knowledge;
|
|
12650
13067
|
#memoryRetriever;
|
|
13068
|
+
#router;
|
|
12651
13069
|
#tools;
|
|
12652
13070
|
constructor(options) {
|
|
12653
13071
|
this.#agent = options.agent;
|
|
@@ -12655,6 +13073,7 @@ var AgentToolLoop = class {
|
|
|
12655
13073
|
this.#contextAssembler = options.contextAssembler;
|
|
12656
13074
|
this.#knowledge = options.knowledge;
|
|
12657
13075
|
this.#memoryRetriever = options.memoryRetriever;
|
|
13076
|
+
this.#router = options.router ?? new AgentToolRouter();
|
|
12658
13077
|
this.#tools = options.toolRuntime;
|
|
12659
13078
|
}
|
|
12660
13079
|
async run(input, context) {
|
|
@@ -12976,7 +13395,7 @@ var AgentToolLoop = class {
|
|
|
12976
13395
|
});
|
|
12977
13396
|
const planned = prompt.isErr() ? void 0 : await input.generateStructured(
|
|
12978
13397
|
{
|
|
12979
|
-
options: {
|
|
13398
|
+
options: { role: "agent" },
|
|
12980
13399
|
prompt: prompt.unwrap(),
|
|
12981
13400
|
schema: "agent-devkit.brain-request/v1"
|
|
12982
13401
|
},
|
|
@@ -13065,7 +13484,7 @@ var AgentToolLoop = class {
|
|
|
13065
13484
|
return Result.fail(prompt.unwrapError());
|
|
13066
13485
|
}
|
|
13067
13486
|
const request = {
|
|
13068
|
-
options: {
|
|
13487
|
+
options: { role: "agent" },
|
|
13069
13488
|
prompt: prompt.unwrap(),
|
|
13070
13489
|
schema: "agent-devkit.brain-request/v1"
|
|
13071
13490
|
};
|
|
@@ -13075,47 +13494,29 @@ var AgentToolLoop = class {
|
|
|
13075
13494
|
}
|
|
13076
13495
|
return Result.ok(produced.unwrap().json ?? {});
|
|
13077
13496
|
}
|
|
13497
|
+
/**
|
|
13498
|
+
* Decision phase adapter: hierarchical routing lives in `AgentToolRouter`
|
|
13499
|
+
* (domain stage + tool stage); the loop only forwards context and events.
|
|
13500
|
+
*/
|
|
13078
13501
|
async #routeToolOrFinal(input) {
|
|
13079
|
-
const
|
|
13502
|
+
const routed = await this.#router.route({
|
|
13080
13503
|
agent: input.agent,
|
|
13081
13504
|
contextSnapshot: input.contextSnapshot,
|
|
13505
|
+
generateStructured: input.generateStructured,
|
|
13082
13506
|
knowledge: input.knowledge,
|
|
13083
13507
|
memories: input.memories,
|
|
13508
|
+
onEvent: async (event) => {
|
|
13509
|
+
await input.context?.eventSink?.appendEvent(event);
|
|
13510
|
+
},
|
|
13084
13511
|
task: input.input.task,
|
|
13085
13512
|
tools: input.tools,
|
|
13086
13513
|
transcript: input.transcript
|
|
13087
13514
|
});
|
|
13088
|
-
if (routePrompt.isErr()) {
|
|
13089
|
-
await input.context?.eventSink?.appendEvent({
|
|
13090
|
-
payload: { code: routePrompt.unwrapError(), phase: "route-prompt" },
|
|
13091
|
-
type: "error"
|
|
13092
|
-
});
|
|
13093
|
-
return Result.fail(routePrompt.unwrapError());
|
|
13094
|
-
}
|
|
13095
|
-
const routed = await input.generateStructured(
|
|
13096
|
-
{
|
|
13097
|
-
options: { provider: "local", role: "agent" },
|
|
13098
|
-
prompt: routePrompt.unwrap(),
|
|
13099
|
-
schema: "agent-devkit.brain-request/v1"
|
|
13100
|
-
},
|
|
13101
|
-
agentRouteJsonSchema
|
|
13102
|
-
);
|
|
13103
13515
|
if (routed.isErr()) {
|
|
13104
|
-
await input.context?.eventSink?.appendEvent({
|
|
13105
|
-
payload: { code: routed.unwrapError(), phase: "route" },
|
|
13106
|
-
type: "error"
|
|
13107
|
-
});
|
|
13108
13516
|
return Result.fail(routed.unwrapError());
|
|
13109
13517
|
}
|
|
13110
|
-
const
|
|
13111
|
-
|
|
13112
|
-
await input.context?.eventSink?.appendEvent({
|
|
13113
|
-
payload: { phase: "route", raw: routed.unwrap().raw },
|
|
13114
|
-
type: "error"
|
|
13115
|
-
});
|
|
13116
|
-
return Result.fail(ErrorCodes.InvalidInput);
|
|
13117
|
-
}
|
|
13118
|
-
return route.data.action === "final" ? Result.ok({ reply: route.data.reply }) : Result.ok(route.data.tool);
|
|
13518
|
+
const decision = routed.unwrap();
|
|
13519
|
+
return "reply" in decision ? Result.ok(decision) : Result.ok(decision.tool);
|
|
13119
13520
|
}
|
|
13120
13521
|
async #reflect(input) {
|
|
13121
13522
|
const prompt = await buildReflectionPrompt(input);
|
|
@@ -13124,7 +13525,7 @@ var AgentToolLoop = class {
|
|
|
13124
13525
|
}
|
|
13125
13526
|
const reflected = await input.generateStructured(
|
|
13126
13527
|
{
|
|
13127
|
-
options: {
|
|
13528
|
+
options: { role: "agent" },
|
|
13128
13529
|
prompt: prompt.unwrap(),
|
|
13129
13530
|
schema: "agent-devkit.brain-request/v1"
|
|
13130
13531
|
},
|
|
@@ -13151,7 +13552,7 @@ var AgentToolLoop = class {
|
|
|
13151
13552
|
}
|
|
13152
13553
|
const summarized = await input.generateStructured(
|
|
13153
13554
|
{
|
|
13154
|
-
options: {
|
|
13555
|
+
options: { role: "agent" },
|
|
13155
13556
|
prompt: prompt.unwrap(),
|
|
13156
13557
|
schema: "agent-devkit.brain-request/v1"
|
|
13157
13558
|
},
|
|
@@ -13828,8 +14229,8 @@ async function startMcpHttpServer(options) {
|
|
|
13828
14229
|
}
|
|
13829
14230
|
}
|
|
13830
14231
|
});
|
|
13831
|
-
await new Promise((
|
|
13832
|
-
httpServer.listen(options.port, options.host,
|
|
14232
|
+
await new Promise((resolve11) => {
|
|
14233
|
+
httpServer.listen(options.port, options.host, resolve11);
|
|
13833
14234
|
});
|
|
13834
14235
|
return httpServer;
|
|
13835
14236
|
}
|
|
@@ -14371,6 +14772,36 @@ function registerModelsCommand(program2, options) {
|
|
|
14371
14772
|
}
|
|
14372
14773
|
)
|
|
14373
14774
|
);
|
|
14775
|
+
const providersCommand = modelsCommand.command("providers").description(options.translator.t("cli.models.providers.description")).option("--json", options.translator.t("cli.models.providers.option.json"));
|
|
14776
|
+
providersCommand.action(
|
|
14777
|
+
options.usageLogging.track(
|
|
14778
|
+
{
|
|
14779
|
+
area: "system",
|
|
14780
|
+
command: "models.providers",
|
|
14781
|
+
createStateIfMissing: false,
|
|
14782
|
+
options: () => providersCommand.opts()
|
|
14783
|
+
},
|
|
14784
|
+
async (commandOptions) => {
|
|
14785
|
+
const dock = createBrainDockProvider({ stateDirectory: `${homedir16()}/.agent-devkit` });
|
|
14786
|
+
const providers = await dock.describeProviders();
|
|
14787
|
+
const routing = dock.routingPolicy();
|
|
14788
|
+
if (wantsJson(commandOptions) === true) {
|
|
14789
|
+
console.log(JSON.stringify({ providers, routing }, null, 2));
|
|
14790
|
+
return;
|
|
14791
|
+
}
|
|
14792
|
+
for (const provider of providers) {
|
|
14793
|
+
const supports = Object.entries(provider.supports).filter(([, enabled]) => enabled).map(([name]) => name).join(", ");
|
|
14794
|
+
console.log(
|
|
14795
|
+
`${provider.available ? "\u25CF" : "\u25CB"} ${provider.id} (${provider.kind})${supports.length > 0 ? ` \u2014 ${supports}` : ""}`
|
|
14796
|
+
);
|
|
14797
|
+
}
|
|
14798
|
+
console.log("");
|
|
14799
|
+
for (const [role, chain] of Object.entries(routing)) {
|
|
14800
|
+
console.log(`${role}: ${chain.join(" \u2192 ")}`);
|
|
14801
|
+
}
|
|
14802
|
+
}
|
|
14803
|
+
)
|
|
14804
|
+
);
|
|
14374
14805
|
const useCommand = modelsCommand.command("use").argument("<id>", options.translator.t("cli.models.argument.id")).description(options.translator.t("cli.models.use.description")).option("--agent", options.translator.t("cli.models.use.option.agent")).option("--chat", options.translator.t("cli.models.use.option.chat")).option("--json", options.translator.t("cli.models.option.json"));
|
|
14375
14806
|
useCommand.action(
|
|
14376
14807
|
options.usageLogging.track(
|
|
@@ -15841,11 +16272,20 @@ function cliConversationStatePathForScope(scope) {
|
|
|
15841
16272
|
segments: [`cli-state-${sanitizeCliScope(scope)}.json`]
|
|
15842
16273
|
};
|
|
15843
16274
|
}
|
|
16275
|
+
function conversationStatePathForScope(invocationInterface, scope) {
|
|
16276
|
+
if (invocationInterface === "cli") {
|
|
16277
|
+
return cliConversationStatePathForScope(scope);
|
|
16278
|
+
}
|
|
16279
|
+
return {
|
|
16280
|
+
namespace: "conversation",
|
|
16281
|
+
segments: [`${invocationInterface}-state-${sanitizeCliScope(scope)}.json`]
|
|
16282
|
+
};
|
|
16283
|
+
}
|
|
15844
16284
|
function isCliConversationState(value) {
|
|
15845
16285
|
const record = value;
|
|
15846
16286
|
return typeof value === "object" && value !== null && "activeSessionId" in value && "schema" in value && typeof record.activeSessionId === "string" && record.activeSessionId.length > 0 && record.schema === "agent-devkit.cli-conversation-state/v1";
|
|
15847
16287
|
}
|
|
15848
|
-
async function loadActiveCliSessionId(dataStore, sessions, statePath) {
|
|
16288
|
+
async function loadActiveCliSessionId(dataStore, sessions, statePath, expectedOrigin) {
|
|
15849
16289
|
const state = await dataStore.readJson(statePath);
|
|
15850
16290
|
if (state.isErr()) {
|
|
15851
16291
|
return void 0;
|
|
@@ -15863,7 +16303,7 @@ async function loadActiveCliSessionId(dataStore, sessions, statePath) {
|
|
|
15863
16303
|
return void 0;
|
|
15864
16304
|
}
|
|
15865
16305
|
const result = current.unwrap();
|
|
15866
|
-
if (result.action !== "show" || result.session.origin !==
|
|
16306
|
+
if (result.action !== "show" || result.session.origin !== expectedOrigin || result.session.status !== "active") {
|
|
15867
16307
|
return void 0;
|
|
15868
16308
|
}
|
|
15869
16309
|
return result.session.id;
|
|
@@ -15903,8 +16343,9 @@ function createConversationPort(chat) {
|
|
|
15903
16343
|
}
|
|
15904
16344
|
};
|
|
15905
16345
|
}
|
|
15906
|
-
|
|
16346
|
+
function createCliAgentEnvironment(options) {
|
|
15907
16347
|
const homeDirectory = homedir25();
|
|
16348
|
+
const invocationInterface = options.interface ?? "cli";
|
|
15908
16349
|
const dataStore = new LocalAgentDataStore({
|
|
15909
16350
|
rootDirectory: `${homeDirectory}/.agent-devkit/data`
|
|
15910
16351
|
});
|
|
@@ -15935,12 +16376,8 @@ async function runRootConversation(message, options) {
|
|
|
15935
16376
|
if (contextBindings.isErr()) {
|
|
15936
16377
|
throw new Error(contextBindings.unwrapError());
|
|
15937
16378
|
}
|
|
15938
|
-
const
|
|
15939
|
-
const
|
|
15940
|
-
dataStore,
|
|
15941
|
-
contextBindings.unwrap().capabilities.sessions,
|
|
15942
|
-
cliStatePath
|
|
15943
|
-
);
|
|
16379
|
+
const sessions = contextBindings.unwrap().capabilities.sessions;
|
|
16380
|
+
const cliStatePath = conversationStatePathForScope(invocationInterface, currentCliSessionScope());
|
|
15944
16381
|
const agent = new AgentRuntime({
|
|
15945
16382
|
brainProvider: createBrainDockProvider({ stateDirectory: `${homeDirectory}/.agent-devkit` }),
|
|
15946
16383
|
conversation: createConversationPort(bindings.unwrap().capabilities.chat),
|
|
@@ -15952,7 +16389,17 @@ async function runRootConversation(message, options) {
|
|
|
15952
16389
|
packageName: options.packageName
|
|
15953
16390
|
})
|
|
15954
16391
|
});
|
|
15955
|
-
|
|
16392
|
+
return {
|
|
16393
|
+
agent,
|
|
16394
|
+
loadActiveSessionId: () => loadActiveCliSessionId(dataStore, sessions, cliStatePath, invocationInterface),
|
|
16395
|
+
saveActiveSessionId: (sessionId) => saveActiveCliSessionId(dataStore, sessionId, cliStatePath),
|
|
16396
|
+
sessions
|
|
16397
|
+
};
|
|
16398
|
+
}
|
|
16399
|
+
async function runRootConversation(message, options) {
|
|
16400
|
+
const environment = createCliAgentEnvironment(options);
|
|
16401
|
+
const activeSessionId = await environment.loadActiveSessionId();
|
|
16402
|
+
const result = await environment.agent.run({
|
|
15956
16403
|
interface: "cli",
|
|
15957
16404
|
message,
|
|
15958
16405
|
mode: "chat",
|
|
@@ -15966,7 +16413,7 @@ async function runRootConversation(message, options) {
|
|
|
15966
16413
|
if (payload.conversation === void 0 || !isConversationChatResult(rawConversation)) {
|
|
15967
16414
|
throw new Error("Agent did not return a conversation result.");
|
|
15968
16415
|
}
|
|
15969
|
-
await
|
|
16416
|
+
await environment.saveActiveSessionId(payload.conversation.sessionId);
|
|
15970
16417
|
console.log(formatConversationChatText(rawConversation));
|
|
15971
16418
|
}
|
|
15972
16419
|
function isConversationChatResult(value) {
|
|
@@ -16050,21 +16497,748 @@ var CliUsageLoggingMiddleware = class {
|
|
|
16050
16497
|
};
|
|
16051
16498
|
|
|
16052
16499
|
// src/app/tui/App.tsx
|
|
16500
|
+
import { Box as Box12, Text as Text14 } from "ink";
|
|
16501
|
+
import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as useState5 } from "react";
|
|
16502
|
+
|
|
16503
|
+
// src/app/tui/commands.ts
|
|
16504
|
+
function parseTuiCommand(value, pendingApproval) {
|
|
16505
|
+
const trimmed = value.trim();
|
|
16506
|
+
if (trimmed.length === 0) {
|
|
16507
|
+
return { type: "empty" };
|
|
16508
|
+
}
|
|
16509
|
+
if (pendingApproval) {
|
|
16510
|
+
const answer = trimmed.toLowerCase();
|
|
16511
|
+
if (answer === "s" || answer === "sim" || answer === "y" || answer === "yes") {
|
|
16512
|
+
return { type: "approve-yes" };
|
|
16513
|
+
}
|
|
16514
|
+
if (answer === "n" || answer === "nao" || answer === "n\xE3o" || answer === "no") {
|
|
16515
|
+
return { type: "approve-no" };
|
|
16516
|
+
}
|
|
16517
|
+
}
|
|
16518
|
+
if (trimmed === "/sessions" || trimmed === "/sessoes" || trimmed === "/sess\xF5es") {
|
|
16519
|
+
return { type: "sessions" };
|
|
16520
|
+
}
|
|
16521
|
+
if (trimmed === "/task") {
|
|
16522
|
+
return { type: "empty" };
|
|
16523
|
+
}
|
|
16524
|
+
if (trimmed.startsWith("/task ")) {
|
|
16525
|
+
const task = trimmed.slice("/task ".length).trim();
|
|
16526
|
+
return task.length === 0 ? { type: "empty" } : { type: "task", task };
|
|
16527
|
+
}
|
|
16528
|
+
return { type: "chat", message: trimmed };
|
|
16529
|
+
}
|
|
16530
|
+
function approvalRequiredTool(steps) {
|
|
16531
|
+
const waiting = [...steps].reverse().find((step) => !step.ok && step.summary.startsWith("approval_required"));
|
|
16532
|
+
return waiting?.tool;
|
|
16533
|
+
}
|
|
16534
|
+
function moodForEvent(event) {
|
|
16535
|
+
if (event.type === "tool") {
|
|
16536
|
+
return "working";
|
|
16537
|
+
}
|
|
16538
|
+
if (event.type === "observation") {
|
|
16539
|
+
return event.ok === false ? "concerned" : "working";
|
|
16540
|
+
}
|
|
16541
|
+
if (event.type === "final") {
|
|
16542
|
+
return "happy";
|
|
16543
|
+
}
|
|
16544
|
+
return "thinking";
|
|
16545
|
+
}
|
|
16546
|
+
|
|
16547
|
+
// src/app/tui/design/components/KbdBar.tsx
|
|
16053
16548
|
import { Box, Text } from "ink";
|
|
16054
|
-
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16058
|
-
|
|
16059
|
-
|
|
16549
|
+
|
|
16550
|
+
// src/app/tui/design/TokensContext.tsx
|
|
16551
|
+
import { createContext, useContext, useMemo } from "react";
|
|
16552
|
+
|
|
16553
|
+
// src/app/tui/design/tokens.ts
|
|
16554
|
+
function resolveTokens(theme, semantics) {
|
|
16555
|
+
const colors2 = theme.colors;
|
|
16556
|
+
const toColor = (tokenName) => colors2[tokenName] ?? theme.colors.textMuted;
|
|
16557
|
+
return {
|
|
16558
|
+
theme,
|
|
16559
|
+
semantics,
|
|
16560
|
+
glyphs: semantics.glyphs,
|
|
16561
|
+
color: (name) => theme.colors[name],
|
|
16562
|
+
statusColor: (status) => toColor(semantics.status[status]),
|
|
16563
|
+
riskColor: (risk) => toColor(semantics.risk[risk])
|
|
16564
|
+
};
|
|
16565
|
+
}
|
|
16566
|
+
|
|
16567
|
+
// src/app/tui/design/TokensContext.tsx
|
|
16568
|
+
import { jsx } from "react/jsx-runtime";
|
|
16569
|
+
var TokensContext = createContext(null);
|
|
16570
|
+
function TokensProvider({ theme, semantics, kit, children }) {
|
|
16571
|
+
const value = useMemo(
|
|
16572
|
+
() => ({ ...resolveTokens(theme, semantics), kit }),
|
|
16573
|
+
[theme, semantics, kit]
|
|
16574
|
+
);
|
|
16575
|
+
return /* @__PURE__ */ jsx(TokensContext.Provider, { value, children });
|
|
16576
|
+
}
|
|
16577
|
+
function useTokens() {
|
|
16578
|
+
const value = useContext(TokensContext);
|
|
16579
|
+
if (value === null) {
|
|
16580
|
+
throw new Error("useTokens must be used within a TokensProvider.");
|
|
16581
|
+
}
|
|
16582
|
+
return value;
|
|
16583
|
+
}
|
|
16584
|
+
|
|
16585
|
+
// src/app/tui/design/components/KbdBar.tsx
|
|
16586
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
16587
|
+
function KbdBar({ keys }) {
|
|
16588
|
+
const tokens2 = useTokens();
|
|
16589
|
+
return /* @__PURE__ */ jsx2(Box, { gap: 2, children: keys.map((key) => /* @__PURE__ */ jsx2(Text, { color: tokens2.color("textDim"), children: key }, key)) });
|
|
16590
|
+
}
|
|
16591
|
+
|
|
16592
|
+
// src/app/tui/design/components/Kit.tsx
|
|
16593
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
16594
|
+
import { useState as useState2 } from "react";
|
|
16595
|
+
|
|
16596
|
+
// src/app/tui/design/kit_cells.ts
|
|
16597
|
+
function applyOverrides(grid, overrides) {
|
|
16598
|
+
for (const [row, col, char] of overrides) {
|
|
16599
|
+
const line2 = grid[row];
|
|
16600
|
+
if (line2 !== void 0 && col >= 0 && col < line2.length) {
|
|
16601
|
+
line2[col] = char;
|
|
16602
|
+
}
|
|
16603
|
+
}
|
|
16604
|
+
}
|
|
16605
|
+
function kitCells(kit, mood, blink, background) {
|
|
16606
|
+
const grid = kit.base.map((line2) => line2.split(""));
|
|
16607
|
+
const moodDefinition = kit.moods[mood] ?? kit.moods.idle;
|
|
16608
|
+
if (moodDefinition !== void 0) {
|
|
16609
|
+
applyOverrides(grid, moodDefinition.overrides);
|
|
16610
|
+
}
|
|
16611
|
+
if (blink) {
|
|
16612
|
+
applyOverrides(grid, kit.blink.overrides);
|
|
16613
|
+
}
|
|
16614
|
+
const palette = { ...kit.palette };
|
|
16615
|
+
if (moodDefinition?.body !== void 0) {
|
|
16616
|
+
palette.B = moodDefinition.body;
|
|
16617
|
+
}
|
|
16618
|
+
if (moodDefinition?.dark !== void 0) {
|
|
16619
|
+
palette.D = moodDefinition.dark;
|
|
16620
|
+
}
|
|
16621
|
+
const colorFor = (char) => {
|
|
16622
|
+
const value = palette[char];
|
|
16623
|
+
return value === void 0 || value === "transparent" ? background : value;
|
|
16624
|
+
};
|
|
16625
|
+
const cellAt = (row, col) => grid[row]?.[col] ?? ".";
|
|
16626
|
+
const rows = [];
|
|
16627
|
+
for (let row = 0; row + 1 < kit.base.length; row += 2) {
|
|
16628
|
+
const cells = [];
|
|
16629
|
+
for (let col = 0; col < kit.size.cols; col += 1) {
|
|
16630
|
+
cells.push({ top: colorFor(cellAt(row, col)), bottom: colorFor(cellAt(row + 1, col)) });
|
|
16631
|
+
}
|
|
16632
|
+
rows.push(cells);
|
|
16633
|
+
}
|
|
16634
|
+
return rows;
|
|
16635
|
+
}
|
|
16636
|
+
|
|
16637
|
+
// src/app/tui/design/useTimers.ts
|
|
16638
|
+
import { useEffect, useRef, useState } from "react";
|
|
16639
|
+
function useInterval(callback, delayMs) {
|
|
16640
|
+
const saved = useRef(callback);
|
|
16641
|
+
saved.current = callback;
|
|
16642
|
+
useEffect(() => {
|
|
16643
|
+
if (delayMs === null) {
|
|
16644
|
+
return;
|
|
16645
|
+
}
|
|
16646
|
+
const id = setInterval(() => saved.current(), delayMs);
|
|
16647
|
+
return () => clearInterval(id);
|
|
16648
|
+
}, [delayMs]);
|
|
16649
|
+
}
|
|
16650
|
+
function useBlink(periodMs = 3600, durationMs3 = 150) {
|
|
16651
|
+
const [blinking, setBlinking] = useState(false);
|
|
16652
|
+
useInterval(() => {
|
|
16653
|
+
setBlinking(true);
|
|
16654
|
+
setTimeout(() => setBlinking(false), durationMs3);
|
|
16655
|
+
}, periodMs);
|
|
16656
|
+
return blinking;
|
|
16657
|
+
}
|
|
16658
|
+
|
|
16659
|
+
// src/app/tui/design/components/Kit.tsx
|
|
16660
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
16661
|
+
var spinnerFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
16662
|
+
function Kit({ mood = "idle", animate = true }) {
|
|
16663
|
+
const tokens2 = useTokens();
|
|
16664
|
+
const blink = useBlink();
|
|
16665
|
+
const [frame, setFrame] = useState2(0);
|
|
16666
|
+
const badge = tokens2.kit.moods[mood]?.badge;
|
|
16667
|
+
const isSpinner = badge === "spinner";
|
|
16668
|
+
useInterval(
|
|
16669
|
+
() => setFrame((current) => (current + 1) % spinnerFrames.length),
|
|
16670
|
+
animate && isSpinner ? 90 : null
|
|
16671
|
+
);
|
|
16672
|
+
const rows = kitCells(tokens2.kit, mood, animate && blink, tokens2.color("background"));
|
|
16673
|
+
const keyedRows = rows.map((cells) => ({
|
|
16674
|
+
cells: cells.map((cell, colIndex) => ({
|
|
16675
|
+
...cell,
|
|
16676
|
+
key: `${cell.top}-${cell.bottom}-${colIndex}`
|
|
16677
|
+
})),
|
|
16678
|
+
key: cells.map((cell) => `${cell.top}/${cell.bottom}`).join("|")
|
|
16679
|
+
}));
|
|
16680
|
+
const badgeText = isSpinner ? spinnerFrames[frame] ?? "" : badge;
|
|
16681
|
+
return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", children: keyedRows.map((row, rowIndex) => /* @__PURE__ */ jsxs(Box2, { children: [
|
|
16682
|
+
row.cells.map((cell) => /* @__PURE__ */ jsx3(Text2, { color: cell.top, backgroundColor: cell.bottom, children: "\u2580" }, cell.key)),
|
|
16683
|
+
rowIndex === 0 && badgeText !== void 0 && badgeText.length > 0 ? /* @__PURE__ */ jsxs(Text2, { color: tokens2.color("primaryStrong"), children: [
|
|
16684
|
+
" ",
|
|
16685
|
+
badgeText
|
|
16686
|
+
] }) : null
|
|
16687
|
+
] }, row.key)) });
|
|
16688
|
+
}
|
|
16689
|
+
|
|
16690
|
+
// src/app/tui/design/components/Pill.tsx
|
|
16691
|
+
import { Text as Text3 } from "ink";
|
|
16692
|
+
import { jsxs as jsxs2 } from "react/jsx-runtime";
|
|
16693
|
+
|
|
16694
|
+
// src/app/tui/design/components/ProgressBar.tsx
|
|
16695
|
+
import { Box as Box3, Text as Text4 } from "ink";
|
|
16696
|
+
import { jsxs as jsxs3 } from "react/jsx-runtime";
|
|
16697
|
+
|
|
16698
|
+
// src/app/tui/design/components/PromptInput.tsx
|
|
16699
|
+
import { Box as Box4, Text as Text5, useInput } from "ink";
|
|
16700
|
+
import { useState as useState3 } from "react";
|
|
16701
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
16702
|
+
function PromptInput({ placeholder, onSubmit, isActive = true }) {
|
|
16703
|
+
const tokens2 = useTokens();
|
|
16704
|
+
const [value, setValue] = useState3("");
|
|
16705
|
+
useInput(
|
|
16706
|
+
(input, key) => {
|
|
16707
|
+
if (key.return) {
|
|
16708
|
+
onSubmit?.(value);
|
|
16709
|
+
setValue("");
|
|
16710
|
+
} else if (key.backspace || key.delete) {
|
|
16711
|
+
setValue((current) => current.slice(0, -1));
|
|
16712
|
+
} else if (input.length > 0 && !key.ctrl && !key.meta) {
|
|
16713
|
+
setValue((current) => current + input);
|
|
16714
|
+
}
|
|
16715
|
+
},
|
|
16716
|
+
{ isActive }
|
|
16717
|
+
);
|
|
16718
|
+
const showPlaceholder = value.length === 0 && placeholder !== void 0;
|
|
16719
|
+
return /* @__PURE__ */ jsxs4(Box4, { gap: 1, children: [
|
|
16720
|
+
/* @__PURE__ */ jsx4(Text5, { color: tokens2.color("primary"), children: tokens2.glyphs.prompt }),
|
|
16721
|
+
/* @__PURE__ */ jsx4(Text5, { color: showPlaceholder ? tokens2.color("textDim") : tokens2.color("text"), children: showPlaceholder ? placeholder : value })
|
|
16060
16722
|
] });
|
|
16061
16723
|
}
|
|
16062
16724
|
|
|
16063
|
-
// src/
|
|
16725
|
+
// src/app/tui/design/components/primitives.tsx
|
|
16726
|
+
import { Text as Text6 } from "ink";
|
|
16727
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
16728
|
+
|
|
16729
|
+
// src/app/tui/design/components/SelectionList.tsx
|
|
16730
|
+
import { Box as Box5, Text as Text7, useInput as useInput2 } from "ink";
|
|
16731
|
+
import { useState as useState4 } from "react";
|
|
16732
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
16733
|
+
function SelectionList({ items, onSelect, isActive = true }) {
|
|
16734
|
+
const tokens2 = useTokens();
|
|
16735
|
+
const [index, setIndex] = useState4(0);
|
|
16736
|
+
useInput2(
|
|
16737
|
+
(_input, key) => {
|
|
16738
|
+
if (items.length === 0) {
|
|
16739
|
+
return;
|
|
16740
|
+
}
|
|
16741
|
+
if (key.upArrow) {
|
|
16742
|
+
setIndex((current) => (current - 1 + items.length) % items.length);
|
|
16743
|
+
} else if (key.downArrow) {
|
|
16744
|
+
setIndex((current) => (current + 1) % items.length);
|
|
16745
|
+
} else if (key.return) {
|
|
16746
|
+
onSelect?.(items[index]?.value ?? "");
|
|
16747
|
+
}
|
|
16748
|
+
},
|
|
16749
|
+
{ isActive }
|
|
16750
|
+
);
|
|
16751
|
+
return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", children: items.map((item, itemIndex) => {
|
|
16752
|
+
const selected = itemIndex === index;
|
|
16753
|
+
return /* @__PURE__ */ jsxs5(Box5, { gap: 1, children: [
|
|
16754
|
+
/* @__PURE__ */ jsx6(Text7, { color: tokens2.color("primary"), children: selected ? tokens2.glyphs.prompt : " " }),
|
|
16755
|
+
/* @__PURE__ */ jsx6(Text7, { color: selected ? tokens2.color("text") : tokens2.color("textMuted"), children: item.label }),
|
|
16756
|
+
item.hint !== void 0 ? /* @__PURE__ */ jsx6(Text7, { color: tokens2.statusColor("ok"), children: item.hint }) : null
|
|
16757
|
+
] }, item.value);
|
|
16758
|
+
}) });
|
|
16759
|
+
}
|
|
16760
|
+
|
|
16761
|
+
// src/app/tui/design/components/SpeechBubble.tsx
|
|
16762
|
+
import { Box as Box6, Text as Text8 } from "ink";
|
|
16763
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
16764
|
+
function SpeechBubble({
|
|
16765
|
+
text: text2,
|
|
16766
|
+
mood = "thinking",
|
|
16767
|
+
label,
|
|
16768
|
+
animate = true
|
|
16769
|
+
}) {
|
|
16770
|
+
const tokens2 = useTokens();
|
|
16771
|
+
return /* @__PURE__ */ jsxs6(Box6, { gap: 1, children: [
|
|
16772
|
+
/* @__PURE__ */ jsx7(Kit, { mood, animate }),
|
|
16773
|
+
/* @__PURE__ */ jsxs6(
|
|
16774
|
+
Box6,
|
|
16775
|
+
{
|
|
16776
|
+
flexDirection: "column",
|
|
16777
|
+
borderStyle: "round",
|
|
16778
|
+
borderColor: tokens2.color("border"),
|
|
16779
|
+
paddingX: 1,
|
|
16780
|
+
children: [
|
|
16781
|
+
label !== void 0 ? /* @__PURE__ */ jsx7(Text8, { color: tokens2.color("textDim"), children: label }) : null,
|
|
16782
|
+
/* @__PURE__ */ jsx7(Text8, { color: tokens2.color("text"), children: text2 })
|
|
16783
|
+
]
|
|
16784
|
+
}
|
|
16785
|
+
)
|
|
16786
|
+
] });
|
|
16787
|
+
}
|
|
16788
|
+
|
|
16789
|
+
// src/app/tui/design/components/StatCard.tsx
|
|
16790
|
+
import { Box as Box7, Text as Text9 } from "ink";
|
|
16791
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
16792
|
+
|
|
16793
|
+
// src/app/tui/design/components/StepList.tsx
|
|
16794
|
+
import { Box as Box8, Text as Text10 } from "ink";
|
|
16795
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
16796
|
+
|
|
16797
|
+
// src/app/tui/design/components/Table.tsx
|
|
16798
|
+
import { Box as Box9, Text as Text11 } from "ink";
|
|
16799
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
16800
|
+
|
|
16801
|
+
// src/app/tui/design/layouts/Panel.tsx
|
|
16802
|
+
import { Box as Box10, Text as Text12 } from "ink";
|
|
16803
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
16804
|
+
|
|
16805
|
+
// src/app/tui/design/layouts/TerminalChrome.tsx
|
|
16806
|
+
import { Box as Box11, Text as Text13 } from "ink";
|
|
16807
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
16808
|
+
|
|
16809
|
+
// src/app/tui/tokens.ts
|
|
16810
|
+
import { existsSync as existsSync9 } from "fs";
|
|
16064
16811
|
import { homedir as homedir26 } from "os";
|
|
16812
|
+
import { dirname as dirname24, resolve as resolve10 } from "path";
|
|
16813
|
+
import { fileURLToPath as fileURLToPath19 } from "url";
|
|
16814
|
+
|
|
16815
|
+
// src/infra/assets/design_catalog.ts
|
|
16816
|
+
import { existsSync as existsSync8 } from "fs";
|
|
16817
|
+
import { dirname as dirname23, resolve as resolve9 } from "path";
|
|
16818
|
+
import { fileURLToPath as fileURLToPath18 } from "url";
|
|
16819
|
+
|
|
16820
|
+
// src/infra/bases/design.ts
|
|
16821
|
+
import { z as z42 } from "zod";
|
|
16822
|
+
var DesignSemanticsSchema = z42.object({
|
|
16823
|
+
schema: z42.literal("agent-devkit.design-semantics/v1"),
|
|
16824
|
+
status: z42.object({
|
|
16825
|
+
ok: z42.string().min(1),
|
|
16826
|
+
attention: z42.string().min(1),
|
|
16827
|
+
blocked: z42.string().min(1),
|
|
16828
|
+
"needs-setup": z42.string().min(1),
|
|
16829
|
+
pending: z42.string().min(1)
|
|
16830
|
+
}),
|
|
16831
|
+
risk: z42.object({
|
|
16832
|
+
destructive: z42.string().min(1),
|
|
16833
|
+
"external-write": z42.string().min(1),
|
|
16834
|
+
"read-only": z42.string().min(1),
|
|
16835
|
+
"writes-global-state": z42.string().min(1),
|
|
16836
|
+
"writes-project-state": z42.string().min(1)
|
|
16837
|
+
}),
|
|
16838
|
+
glyphs: z42.object({
|
|
16839
|
+
prompt: z42.string().min(1),
|
|
16840
|
+
check: z42.string().min(1),
|
|
16841
|
+
bulletActive: z42.string().min(1),
|
|
16842
|
+
bulletIdle: z42.string().min(1),
|
|
16843
|
+
progressFull: z42.string().min(1),
|
|
16844
|
+
progressEmpty: z42.string().min(1)
|
|
16845
|
+
})
|
|
16846
|
+
});
|
|
16847
|
+
var KitCellOverrideSchema = z42.tuple([z42.number().int(), z42.number().int(), z42.string().min(1)]);
|
|
16848
|
+
var KitMoodSchema = z42.object({
|
|
16849
|
+
overrides: z42.array(KitCellOverrideSchema).default([]),
|
|
16850
|
+
body: z42.string().optional(),
|
|
16851
|
+
dark: z42.string().optional(),
|
|
16852
|
+
badge: z42.string().optional()
|
|
16853
|
+
});
|
|
16854
|
+
var KitSpriteSchema = z42.object({
|
|
16855
|
+
schema: z42.literal("agent-devkit.kit/v1"),
|
|
16856
|
+
size: z42.object({
|
|
16857
|
+
rows: z42.number().int().positive(),
|
|
16858
|
+
cols: z42.number().int().positive()
|
|
16859
|
+
}),
|
|
16860
|
+
palette: z42.record(z42.string().min(1), z42.string().min(1)),
|
|
16861
|
+
base: z42.array(z42.string().min(1)).min(1),
|
|
16862
|
+
blink: KitMoodSchema,
|
|
16863
|
+
moods: z42.record(z42.string().min(1), KitMoodSchema)
|
|
16864
|
+
});
|
|
16865
|
+
|
|
16866
|
+
// src/infra/assets/design_catalog.ts
|
|
16867
|
+
function defaultAssetsRoot3() {
|
|
16868
|
+
const moduleDirectory13 = dirname23(fileURLToPath18(import.meta.url));
|
|
16869
|
+
const candidates = [
|
|
16870
|
+
resolve9(moduleDirectory13, "../../assets"),
|
|
16871
|
+
resolve9(moduleDirectory13, "../src/assets"),
|
|
16872
|
+
resolve9(process.cwd(), "src/assets")
|
|
16873
|
+
];
|
|
16874
|
+
return candidates.find((candidate) => existsSync8(candidate)) ?? resolve9(process.cwd(), "src/assets");
|
|
16875
|
+
}
|
|
16876
|
+
var DesignCatalog = class {
|
|
16877
|
+
#loader;
|
|
16878
|
+
#semantics;
|
|
16879
|
+
#kit;
|
|
16880
|
+
constructor(options = {}) {
|
|
16881
|
+
this.#loader = options.loader ?? new AssetLoader({ rootDirectory: defaultAssetsRoot3() });
|
|
16882
|
+
}
|
|
16883
|
+
async semantics() {
|
|
16884
|
+
if (this.#semantics !== void 0) {
|
|
16885
|
+
return Result.ok(this.#semantics);
|
|
16886
|
+
}
|
|
16887
|
+
const payload = await this.#loader.loadJson("design", "semantics.json");
|
|
16888
|
+
if (payload.isErr()) {
|
|
16889
|
+
return Result.fail(payload.unwrapError());
|
|
16890
|
+
}
|
|
16891
|
+
const parsed = DesignSemanticsSchema.safeParse(payload.unwrap());
|
|
16892
|
+
if (!parsed.success) {
|
|
16893
|
+
return Result.fail(ErrorCodes.InvalidInput);
|
|
16894
|
+
}
|
|
16895
|
+
this.#semantics = parsed.data;
|
|
16896
|
+
return Result.ok(this.#semantics);
|
|
16897
|
+
}
|
|
16898
|
+
async kit() {
|
|
16899
|
+
if (this.#kit !== void 0) {
|
|
16900
|
+
return Result.ok(this.#kit);
|
|
16901
|
+
}
|
|
16902
|
+
const payload = await this.#loader.loadJson("design", "kit.json");
|
|
16903
|
+
if (payload.isErr()) {
|
|
16904
|
+
return Result.fail(payload.unwrapError());
|
|
16905
|
+
}
|
|
16906
|
+
const parsed = KitSpriteSchema.safeParse(payload.unwrap());
|
|
16907
|
+
if (!parsed.success) {
|
|
16908
|
+
return Result.fail(ErrorCodes.InvalidInput);
|
|
16909
|
+
}
|
|
16910
|
+
this.#kit = parsed.data;
|
|
16911
|
+
return Result.ok(this.#kit);
|
|
16912
|
+
}
|
|
16913
|
+
};
|
|
16914
|
+
|
|
16915
|
+
// src/app/tui/tokens.ts
|
|
16916
|
+
function assetsRoot() {
|
|
16917
|
+
const moduleDirectory13 = dirname24(fileURLToPath19(import.meta.url));
|
|
16918
|
+
const candidates = [
|
|
16919
|
+
resolve10(moduleDirectory13, "../../assets"),
|
|
16920
|
+
resolve10(moduleDirectory13, "../src/assets"),
|
|
16921
|
+
resolve10(process.cwd(), "src/assets")
|
|
16922
|
+
];
|
|
16923
|
+
return candidates.find((candidate) => existsSync9(candidate)) ?? resolve10(process.cwd(), "src/assets");
|
|
16924
|
+
}
|
|
16925
|
+
async function activeThemeId() {
|
|
16926
|
+
const bindings = createUserModuleBindings({ homeDirectory: homedir26() });
|
|
16927
|
+
if (bindings.isErr()) {
|
|
16928
|
+
return "default-purple";
|
|
16929
|
+
}
|
|
16930
|
+
const preferences = await bindings.unwrap().capabilities.preferences.execute({ action: "view" });
|
|
16931
|
+
if (preferences.isErr()) {
|
|
16932
|
+
return "default-purple";
|
|
16933
|
+
}
|
|
16934
|
+
const payload = preferences.unwrap();
|
|
16935
|
+
return "preferences" in payload ? payload.preferences.theme : "default-purple";
|
|
16936
|
+
}
|
|
16937
|
+
async function loadTuiTokens() {
|
|
16938
|
+
const loader = new AssetLoader({ rootDirectory: assetsRoot() });
|
|
16939
|
+
const catalog = new DesignCatalog({ loader });
|
|
16940
|
+
const themeId = await activeThemeId();
|
|
16941
|
+
const themePayload = await loader.loadJson("themes", `${themeId}.json`);
|
|
16942
|
+
const fallbackPayload = themePayload.isErr() ? await loader.loadJson("themes", "default-purple.json") : themePayload;
|
|
16943
|
+
const theme = ThemeDefinitionSchema.safeParse(
|
|
16944
|
+
fallbackPayload.isOk() ? fallbackPayload.unwrap() : void 0
|
|
16945
|
+
);
|
|
16946
|
+
const semantics = await catalog.semantics();
|
|
16947
|
+
const kit = await catalog.kit();
|
|
16948
|
+
if (!theme.success || semantics.isErr() || kit.isErr()) {
|
|
16949
|
+
throw new Error("TUI design assets could not be loaded.");
|
|
16950
|
+
}
|
|
16951
|
+
return { kit: kit.unwrap(), semantics: semantics.unwrap(), theme: theme.data };
|
|
16952
|
+
}
|
|
16953
|
+
|
|
16954
|
+
// src/app/tui/App.tsx
|
|
16955
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
16956
|
+
var visibleMessages = 10;
|
|
16957
|
+
var happyMoodMs = 1500;
|
|
16958
|
+
var messageSequence = 0;
|
|
16959
|
+
function nextMessageId() {
|
|
16960
|
+
messageSequence += 1;
|
|
16961
|
+
return messageSequence;
|
|
16962
|
+
}
|
|
16963
|
+
function App({ currentVersion, initialPrompt, packageName, translator: translator2 }) {
|
|
16964
|
+
const [tokens2, setTokens] = useState5();
|
|
16965
|
+
const [bootError, setBootError] = useState5();
|
|
16966
|
+
const [messages, setMessages] = useState5([]);
|
|
16967
|
+
const [mood, setMood] = useState5("idle");
|
|
16968
|
+
const [busy, setBusy] = useState5(false);
|
|
16969
|
+
const [pendingApproval, setPendingApproval] = useState5();
|
|
16970
|
+
const [view, setView] = useState5("chat");
|
|
16971
|
+
const [sessionItems, setSessionItems] = useState5([]);
|
|
16972
|
+
const environmentRef = useRef2(void 0);
|
|
16973
|
+
const sessionIdRef = useRef2(void 0);
|
|
16974
|
+
const moodTimerRef = useRef2(void 0);
|
|
16975
|
+
const pushMessage = useCallback((role, text2) => {
|
|
16976
|
+
setMessages((current) => [...current, { id: nextMessageId(), role, text: text2 }]);
|
|
16977
|
+
}, []);
|
|
16978
|
+
const settleMood = useCallback((finalMood) => {
|
|
16979
|
+
setMood(finalMood);
|
|
16980
|
+
if (moodTimerRef.current !== void 0) {
|
|
16981
|
+
clearTimeout(moodTimerRef.current);
|
|
16982
|
+
}
|
|
16983
|
+
moodTimerRef.current = setTimeout(() => setMood("idle"), happyMoodMs);
|
|
16984
|
+
}, []);
|
|
16985
|
+
const runChat = useCallback(
|
|
16986
|
+
async (message) => {
|
|
16987
|
+
const environment = environmentRef.current;
|
|
16988
|
+
if (environment === void 0) {
|
|
16989
|
+
return;
|
|
16990
|
+
}
|
|
16991
|
+
setBusy(true);
|
|
16992
|
+
setMood("thinking");
|
|
16993
|
+
pushMessage("user", message);
|
|
16994
|
+
const result = await environment.agent.run({
|
|
16995
|
+
interface: "tui",
|
|
16996
|
+
message,
|
|
16997
|
+
mode: "chat",
|
|
16998
|
+
sessionId: sessionIdRef.current
|
|
16999
|
+
});
|
|
17000
|
+
if (result.isErr()) {
|
|
17001
|
+
pushMessage("info", translator2.t("tui.error", { error: result.unwrapError() }));
|
|
17002
|
+
settleMood("concerned");
|
|
17003
|
+
setBusy(false);
|
|
17004
|
+
return;
|
|
17005
|
+
}
|
|
17006
|
+
const payload = result.unwrap();
|
|
17007
|
+
if (payload.conversation !== void 0) {
|
|
17008
|
+
sessionIdRef.current = payload.conversation.sessionId;
|
|
17009
|
+
await environment.saveActiveSessionId(payload.conversation.sessionId);
|
|
17010
|
+
}
|
|
17011
|
+
pushMessage("agent", payload.reply);
|
|
17012
|
+
settleMood("happy");
|
|
17013
|
+
setBusy(false);
|
|
17014
|
+
},
|
|
17015
|
+
[pushMessage, settleMood, translator2.t]
|
|
17016
|
+
);
|
|
17017
|
+
const runTask = useCallback(
|
|
17018
|
+
async (task, approvedTools) => {
|
|
17019
|
+
const environment = environmentRef.current;
|
|
17020
|
+
if (environment === void 0) {
|
|
17021
|
+
return;
|
|
17022
|
+
}
|
|
17023
|
+
setBusy(true);
|
|
17024
|
+
setMood("thinking");
|
|
17025
|
+
if (approvedTools === void 0) {
|
|
17026
|
+
pushMessage("user", `/task ${task}`);
|
|
17027
|
+
}
|
|
17028
|
+
const onEvent = (event) => {
|
|
17029
|
+
setMood(moodForEvent(event));
|
|
17030
|
+
if (event.type === "tool") {
|
|
17031
|
+
pushMessage("info", `\u2192 ${event.tool}`);
|
|
17032
|
+
}
|
|
17033
|
+
if (event.type === "observation") {
|
|
17034
|
+
pushMessage("info", `${event.ok ? "\u2713" : "\u2717"} ${event.tool}: ${event.summary}`);
|
|
17035
|
+
}
|
|
17036
|
+
};
|
|
17037
|
+
const result = await environment.agent.run({
|
|
17038
|
+
approvedTools,
|
|
17039
|
+
interface: "tui",
|
|
17040
|
+
mode: "task",
|
|
17041
|
+
onEvent,
|
|
17042
|
+
sessionId: sessionIdRef.current,
|
|
17043
|
+
task
|
|
17044
|
+
});
|
|
17045
|
+
if (result.isErr()) {
|
|
17046
|
+
pushMessage("info", translator2.t("tui.error", { error: result.unwrapError() }));
|
|
17047
|
+
settleMood("concerned");
|
|
17048
|
+
setBusy(false);
|
|
17049
|
+
return;
|
|
17050
|
+
}
|
|
17051
|
+
const payload = result.unwrap();
|
|
17052
|
+
const waitingTool = approvalRequiredTool(payload.steps);
|
|
17053
|
+
pushMessage("agent", payload.reply);
|
|
17054
|
+
if (waitingTool !== void 0) {
|
|
17055
|
+
setPendingApproval({ task, tool: waitingTool });
|
|
17056
|
+
pushMessage("info", translator2.t("tui.approvalRequired", { tool: waitingTool }));
|
|
17057
|
+
setMood("concerned");
|
|
17058
|
+
setBusy(false);
|
|
17059
|
+
return;
|
|
17060
|
+
}
|
|
17061
|
+
settleMood("happy");
|
|
17062
|
+
setBusy(false);
|
|
17063
|
+
},
|
|
17064
|
+
[pushMessage, settleMood, translator2.t]
|
|
17065
|
+
);
|
|
17066
|
+
const openSessions = useCallback(async () => {
|
|
17067
|
+
const environment = environmentRef.current;
|
|
17068
|
+
if (environment === void 0) {
|
|
17069
|
+
return;
|
|
17070
|
+
}
|
|
17071
|
+
const listed = await environment.sessions.execute({
|
|
17072
|
+
action: "list",
|
|
17073
|
+
limit: 10,
|
|
17074
|
+
status: "active"
|
|
17075
|
+
});
|
|
17076
|
+
if (listed.isErr() || listed.unwrap().action !== "list") {
|
|
17077
|
+
pushMessage("info", translator2.t("tui.sessionsListFailed"));
|
|
17078
|
+
return;
|
|
17079
|
+
}
|
|
17080
|
+
const payload = listed.unwrap();
|
|
17081
|
+
const items = payload.action === "list" ? payload.sessions.map((session) => ({
|
|
17082
|
+
hint: session.sessionId,
|
|
17083
|
+
label: session.title,
|
|
17084
|
+
value: session.sessionId
|
|
17085
|
+
})) : [];
|
|
17086
|
+
if (items.length === 0) {
|
|
17087
|
+
pushMessage("info", translator2.t("tui.sessionsEmpty"));
|
|
17088
|
+
return;
|
|
17089
|
+
}
|
|
17090
|
+
setSessionItems(items);
|
|
17091
|
+
setView("sessions");
|
|
17092
|
+
}, [pushMessage, translator2.t]);
|
|
17093
|
+
const submit = useCallback(
|
|
17094
|
+
(value) => {
|
|
17095
|
+
if (busy) {
|
|
17096
|
+
return;
|
|
17097
|
+
}
|
|
17098
|
+
const command = parseTuiCommand(value, pendingApproval !== void 0);
|
|
17099
|
+
if (command.type === "empty") {
|
|
17100
|
+
return;
|
|
17101
|
+
}
|
|
17102
|
+
if (command.type === "approve-yes" && pendingApproval !== void 0) {
|
|
17103
|
+
const approval = pendingApproval;
|
|
17104
|
+
setPendingApproval(void 0);
|
|
17105
|
+
pushMessage("info", translator2.t("tui.approvalAccepted", { tool: approval.tool }));
|
|
17106
|
+
void runTask(approval.task, [approval.tool]);
|
|
17107
|
+
return;
|
|
17108
|
+
}
|
|
17109
|
+
if (command.type === "approve-no" && pendingApproval !== void 0) {
|
|
17110
|
+
setPendingApproval(void 0);
|
|
17111
|
+
pushMessage("info", translator2.t("tui.approvalDenied"));
|
|
17112
|
+
setMood("idle");
|
|
17113
|
+
return;
|
|
17114
|
+
}
|
|
17115
|
+
if (command.type === "sessions") {
|
|
17116
|
+
void openSessions();
|
|
17117
|
+
return;
|
|
17118
|
+
}
|
|
17119
|
+
if (command.type === "task") {
|
|
17120
|
+
void runTask(command.task);
|
|
17121
|
+
return;
|
|
17122
|
+
}
|
|
17123
|
+
if (command.type === "chat") {
|
|
17124
|
+
void runChat(command.message);
|
|
17125
|
+
}
|
|
17126
|
+
},
|
|
17127
|
+
[busy, openSessions, pendingApproval, pushMessage, runChat, runTask, translator2.t]
|
|
17128
|
+
);
|
|
17129
|
+
useEffect2(() => {
|
|
17130
|
+
let mounted = true;
|
|
17131
|
+
(async () => {
|
|
17132
|
+
try {
|
|
17133
|
+
const [loadedTokens, environment] = await Promise.all([
|
|
17134
|
+
loadTuiTokens(),
|
|
17135
|
+
Promise.resolve(
|
|
17136
|
+
createCliAgentEnvironment({ currentVersion, interface: "tui", packageName })
|
|
17137
|
+
)
|
|
17138
|
+
]);
|
|
17139
|
+
const activeSessionId = await environment.loadActiveSessionId();
|
|
17140
|
+
if (!mounted) {
|
|
17141
|
+
return;
|
|
17142
|
+
}
|
|
17143
|
+
environmentRef.current = environment;
|
|
17144
|
+
sessionIdRef.current = activeSessionId;
|
|
17145
|
+
setTokens(loadedTokens);
|
|
17146
|
+
} catch (error) {
|
|
17147
|
+
if (mounted) {
|
|
17148
|
+
setBootError(error instanceof Error ? error.message : String(error));
|
|
17149
|
+
}
|
|
17150
|
+
}
|
|
17151
|
+
})();
|
|
17152
|
+
return () => {
|
|
17153
|
+
mounted = false;
|
|
17154
|
+
if (moodTimerRef.current !== void 0) {
|
|
17155
|
+
clearTimeout(moodTimerRef.current);
|
|
17156
|
+
}
|
|
17157
|
+
};
|
|
17158
|
+
}, [currentVersion, packageName]);
|
|
17159
|
+
useEffect2(() => {
|
|
17160
|
+
if (tokens2 !== void 0 && initialPrompt !== void 0 && initialPrompt.length > 0) {
|
|
17161
|
+
void runChat(initialPrompt);
|
|
17162
|
+
}
|
|
17163
|
+
}, [tokens2, initialPrompt, runChat]);
|
|
17164
|
+
if (bootError !== void 0) {
|
|
17165
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", children: [
|
|
17166
|
+
/* @__PURE__ */ jsx13(Text14, { bold: true, color: "red", children: translator2.t("tui.title") }),
|
|
17167
|
+
/* @__PURE__ */ jsx13(Text14, { children: bootError })
|
|
17168
|
+
] });
|
|
17169
|
+
}
|
|
17170
|
+
if (tokens2 === void 0) {
|
|
17171
|
+
return /* @__PURE__ */ jsxs12(Text14, { children: [
|
|
17172
|
+
translator2.t("tui.title"),
|
|
17173
|
+
"..."
|
|
17174
|
+
] });
|
|
17175
|
+
}
|
|
17176
|
+
const recent = messages.slice(-visibleMessages);
|
|
17177
|
+
const lastAgentMessage = [...messages].reverse().find((message) => message.role === "agent");
|
|
17178
|
+
return /* @__PURE__ */ jsx13(TokensProvider, { kit: tokens2.kit, semantics: tokens2.semantics, theme: tokens2.theme, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, gap: 1, children: [
|
|
17179
|
+
/* @__PURE__ */ jsxs12(Box12, { gap: 2, children: [
|
|
17180
|
+
/* @__PURE__ */ jsx13(Kit, { mood }),
|
|
17181
|
+
/* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", justifyContent: "center", children: [
|
|
17182
|
+
/* @__PURE__ */ jsxs12(Text14, { bold: true, children: [
|
|
17183
|
+
packageName,
|
|
17184
|
+
" v",
|
|
17185
|
+
currentVersion
|
|
17186
|
+
] }),
|
|
17187
|
+
/* @__PURE__ */ jsx13(Text14, { dimColor: true, children: sessionIdRef.current === void 0 ? translator2.t("tui.newSession") : translator2.t("tui.session", { sessionId: sessionIdRef.current }) })
|
|
17188
|
+
] })
|
|
17189
|
+
] }),
|
|
17190
|
+
/* @__PURE__ */ jsx13(Box12, { flexDirection: "column", children: recent.map(
|
|
17191
|
+
(message) => message.role === "agent" && message.id === lastAgentMessage?.id ? /* @__PURE__ */ jsx13(SpeechBubble, { mood, text: message.text }, message.id) : /* @__PURE__ */ jsxs12(
|
|
17192
|
+
Text14,
|
|
17193
|
+
{
|
|
17194
|
+
dimColor: message.role === "info",
|
|
17195
|
+
color: message.role === "user" ? "cyan" : void 0,
|
|
17196
|
+
children: [
|
|
17197
|
+
message.role === "user" ? "\u276F " : message.role === "info" ? "\xB7 " : "",
|
|
17198
|
+
message.text
|
|
17199
|
+
]
|
|
17200
|
+
},
|
|
17201
|
+
message.id
|
|
17202
|
+
)
|
|
17203
|
+
) }),
|
|
17204
|
+
view === "sessions" ? /* @__PURE__ */ jsx13(
|
|
17205
|
+
SelectionList,
|
|
17206
|
+
{
|
|
17207
|
+
items: sessionItems,
|
|
17208
|
+
onSelect: (value) => {
|
|
17209
|
+
sessionIdRef.current = value;
|
|
17210
|
+
void environmentRef.current?.saveActiveSessionId(value);
|
|
17211
|
+
setView("chat");
|
|
17212
|
+
pushMessage("info", translator2.t("tui.sessionResumed", { sessionId: value }));
|
|
17213
|
+
}
|
|
17214
|
+
}
|
|
17215
|
+
) : /* @__PURE__ */ jsx13(
|
|
17216
|
+
PromptInput,
|
|
17217
|
+
{
|
|
17218
|
+
isActive: !busy,
|
|
17219
|
+
onSubmit: submit,
|
|
17220
|
+
placeholder: pendingApproval !== void 0 ? translator2.t("tui.approvalPlaceholder") : busy ? translator2.t("tui.thinking") : translator2.t("tui.helpHint")
|
|
17221
|
+
}
|
|
17222
|
+
),
|
|
17223
|
+
/* @__PURE__ */ jsx13(
|
|
17224
|
+
KbdBar,
|
|
17225
|
+
{
|
|
17226
|
+
keys: [
|
|
17227
|
+
translator2.t("tui.kbd.send"),
|
|
17228
|
+
translator2.t("tui.kbd.task"),
|
|
17229
|
+
"/sessions",
|
|
17230
|
+
translator2.t("tui.kbd.exit")
|
|
17231
|
+
]
|
|
17232
|
+
}
|
|
17233
|
+
)
|
|
17234
|
+
] }) });
|
|
17235
|
+
}
|
|
17236
|
+
|
|
17237
|
+
// src/infra/logging/json_technical_logger.ts
|
|
17238
|
+
import { homedir as homedir27 } from "os";
|
|
16065
17239
|
import { join as join18 } from "path";
|
|
16066
17240
|
function defaultStateDirectory4() {
|
|
16067
|
-
return join18(
|
|
17241
|
+
return join18(homedir27(), ".agent-devkit");
|
|
16068
17242
|
}
|
|
16069
17243
|
function logFileName(timestamp) {
|
|
16070
17244
|
return `technical-${timestamp.toISOString().slice(0, 10)}.jsonl`;
|
|
@@ -16153,10 +17327,10 @@ var JsonTechnicalLogger = class {
|
|
|
16153
17327
|
};
|
|
16154
17328
|
|
|
16155
17329
|
// src/infra/logging/json_usage_logger.ts
|
|
16156
|
-
import { homedir as
|
|
17330
|
+
import { homedir as homedir28 } from "os";
|
|
16157
17331
|
import { join as join19 } from "path";
|
|
16158
17332
|
function defaultStateDirectory5() {
|
|
16159
|
-
return join19(
|
|
17333
|
+
return join19(homedir28(), ".agent-devkit");
|
|
16160
17334
|
}
|
|
16161
17335
|
function logFileName2(timestamp) {
|
|
16162
17336
|
return `usage-${timestamp.toISOString().slice(0, 10)}.jsonl`;
|
|
@@ -16266,7 +17440,13 @@ program.name("agent").description(translator.t("cli.root.description")).version(
|
|
|
16266
17440
|
return;
|
|
16267
17441
|
}
|
|
16268
17442
|
await ensureFirstRunModel(translator);
|
|
16269
|
-
render(
|
|
17443
|
+
render(
|
|
17444
|
+
React.createElement(App, {
|
|
17445
|
+
currentVersion: package_default.version,
|
|
17446
|
+
packageName: package_default.name,
|
|
17447
|
+
translator
|
|
17448
|
+
})
|
|
17449
|
+
);
|
|
16270
17450
|
})
|
|
16271
17451
|
);
|
|
16272
17452
|
registerDoctorCommand(program, { appVersion: package_default.version, translator, usageLogging });
|