agent-devkit 0.3.3 → 0.3.5
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 +4 -4
- package/dist/main.js +435 -93
- package/dist/main.js.map +1 -1
- package/package.json +2 -2
- package/src/assets/i18n/en-US.json +1 -1
- package/src/assets/i18n/fr-FR.json +1 -1
- package/src/assets/i18n/ja-JP.json +1 -1
- package/src/assets/i18n/pt-BR.json +1 -1
- package/src/assets/i18n/zh-CN.json +1 -1
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.3.
|
|
11
|
+
version: "0.3.5",
|
|
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",
|
|
@@ -50,7 +50,7 @@ var package_default = {
|
|
|
50
50
|
"release:verify": "node scripts/verify-release-alignment.mjs",
|
|
51
51
|
test: "npm run test:architecture && npm run test:infra && npm run test:app && npm run test:modules",
|
|
52
52
|
"test:app": "vitest run src/app/cli/commands src/app/mcp src/app/tui src/package.test.ts",
|
|
53
|
-
"test:architecture": "vitest run src/architecture.test.ts src/modules/capability_registry.test.ts src/modules/capability_tool_runtime.test.ts src/modules/modules.registry.test.ts",
|
|
53
|
+
"test:architecture": "vitest run src/agent src/architecture.test.ts src/modules/capability_registry.test.ts src/modules/capability_tool_runtime.test.ts src/modules/modules.registry.test.ts",
|
|
54
54
|
"test:infra": "vitest run src/infra",
|
|
55
55
|
"test:module": "tsx scripts/test-modules.ts",
|
|
56
56
|
"test:modules": "tsx scripts/test-modules.ts",
|
|
@@ -3648,6 +3648,43 @@ var ModelStore = class {
|
|
|
3648
3648
|
|
|
3649
3649
|
// src/infra/brain/local_llama_provider.ts
|
|
3650
3650
|
var nodeLlamaModuleName = "node-llama-cpp";
|
|
3651
|
+
function shouldSuppressNodeLlamaLog(line) {
|
|
3652
|
+
return line.startsWith("[node-llama-cpp]");
|
|
3653
|
+
}
|
|
3654
|
+
var defaultLocalGenerationOptions = {
|
|
3655
|
+
maxTokens: 512,
|
|
3656
|
+
temperature: 0.25,
|
|
3657
|
+
topK: 40,
|
|
3658
|
+
topP: 0.9
|
|
3659
|
+
};
|
|
3660
|
+
async function suppressNodeLlamaLogs(operation) {
|
|
3661
|
+
const originalWrite = process.stderr.write;
|
|
3662
|
+
let pending = "";
|
|
3663
|
+
const filteredWrite = ((chunk, encodingOrCallback, callback) => {
|
|
3664
|
+
const encoding = typeof encodingOrCallback === "string" ? encodingOrCallback : "utf8";
|
|
3665
|
+
const done = typeof encodingOrCallback === "function" ? encodingOrCallback : callback;
|
|
3666
|
+
const text2 = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString(encoding) : String(chunk);
|
|
3667
|
+
const lines = `${pending}${text2}`.split(/\r?\n/);
|
|
3668
|
+
pending = lines.pop() ?? "";
|
|
3669
|
+
for (const line of lines) {
|
|
3670
|
+
if (!shouldSuppressNodeLlamaLog(line)) {
|
|
3671
|
+
originalWrite.call(process.stderr, `${line}
|
|
3672
|
+
`);
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
done?.();
|
|
3676
|
+
return true;
|
|
3677
|
+
});
|
|
3678
|
+
process.stderr.write = filteredWrite;
|
|
3679
|
+
try {
|
|
3680
|
+
return await operation();
|
|
3681
|
+
} finally {
|
|
3682
|
+
if (pending.length > 0 && !shouldSuppressNodeLlamaLog(pending)) {
|
|
3683
|
+
originalWrite.call(process.stderr, pending);
|
|
3684
|
+
}
|
|
3685
|
+
process.stderr.write = originalWrite;
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3651
3688
|
async function loadNodeLlama() {
|
|
3652
3689
|
try {
|
|
3653
3690
|
return Result.ok(await import(nodeLlamaModuleName));
|
|
@@ -3658,8 +3695,11 @@ async function loadNodeLlama() {
|
|
|
3658
3695
|
function systemPromptFrom(prompt) {
|
|
3659
3696
|
const { agent } = prompt;
|
|
3660
3697
|
const lines = [
|
|
3661
|
-
`You are ${agent.name}.`,
|
|
3662
|
-
|
|
3698
|
+
`You are ${agent.name}, the user's configured Agent DevKit personality.`,
|
|
3699
|
+
"You operate inside Agent DevKit, a local AI agent toolkit exposed through the `agent` CLI, TUI and MCP.",
|
|
3700
|
+
"Answer as the agent. Do not answer as the user, as a generic person, or as a generic chatbot.",
|
|
3701
|
+
`Behavior: ${agent.behavior}. Tone: ${agent.tone}. Detail level: ${agent.detailLevel}.`,
|
|
3702
|
+
"If the user asks personal questions about you, your personality or what you can do, answer from your configured persona and conversation abilities. Do not list generic human activities. Do not describe Agent DevKit internals unless the user explicitly asks about Agent DevKit, tools, commands, MCP, modules or project capabilities."
|
|
3663
3703
|
];
|
|
3664
3704
|
if (agent.traits.length > 0) {
|
|
3665
3705
|
lines.push(`Traits: ${agent.traits.join(", ")}.`);
|
|
@@ -3670,6 +3710,38 @@ function systemPromptFrom(prompt) {
|
|
|
3670
3710
|
`Project: ${project.name}${project.description === void 0 ? "" : ` \u2014 ${project.description}`}.`
|
|
3671
3711
|
);
|
|
3672
3712
|
}
|
|
3713
|
+
const { session } = prompt.context;
|
|
3714
|
+
if (session !== void 0) {
|
|
3715
|
+
lines.push(
|
|
3716
|
+
`Session: ${session.id}. Title: ${session.title}. Messages: ${session.messageCount}.`
|
|
3717
|
+
);
|
|
3718
|
+
}
|
|
3719
|
+
if (prompt.context.knowledge.length > 0) {
|
|
3720
|
+
lines.push(
|
|
3721
|
+
"",
|
|
3722
|
+
"Agent DevKit knowledge:",
|
|
3723
|
+
...prompt.context.knowledge.map((knowledge) => `- ${knowledge.content}`)
|
|
3724
|
+
);
|
|
3725
|
+
}
|
|
3726
|
+
if (prompt.tools.length > 0) {
|
|
3727
|
+
lines.push(
|
|
3728
|
+
"",
|
|
3729
|
+
"Available tools:",
|
|
3730
|
+
...prompt.tools.map((tool) => `- ${tool.id} (${tool.risk}): ${tool.description}`)
|
|
3731
|
+
);
|
|
3732
|
+
}
|
|
3733
|
+
lines.push(
|
|
3734
|
+
"",
|
|
3735
|
+
"Tool policy:",
|
|
3736
|
+
`- Tool calls allowed: ${prompt.policies.allowToolCalls ? "yes" : "no"}.`,
|
|
3737
|
+
`- Approval required: ${prompt.policies.approvalRequired ? "yes" : "no"}.`,
|
|
3738
|
+
`- Max tool calls: ${prompt.policies.maxToolCalls}.`
|
|
3739
|
+
);
|
|
3740
|
+
if (!prompt.policies.allowToolCalls) {
|
|
3741
|
+
lines.push(
|
|
3742
|
+
"- In this mode, do not claim that you already executed actions. If the user asks for a concrete action, explain that direct tool execution is unavailable in this chat turn."
|
|
3743
|
+
);
|
|
3744
|
+
}
|
|
3673
3745
|
lines.push(`Reply in ${prompt.output.language}.`);
|
|
3674
3746
|
const history = prompt.messages.filter((message) => message.role === "user" || message.role === "assistant").slice(0, -1).map((message) => `${message.role === "user" ? "User" : agent.name}: ${message.content}`);
|
|
3675
3747
|
if (history.length > 0) {
|
|
@@ -3727,30 +3799,32 @@ var LocalLlamaBrainProvider = class {
|
|
|
3727
3799
|
return Result.fail(nodeLlama.unwrapError());
|
|
3728
3800
|
}
|
|
3729
3801
|
try {
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3802
|
+
return await suppressNodeLlamaLogs(async () => {
|
|
3803
|
+
const llama = nodeLlama.unwrap();
|
|
3804
|
+
const loadedModel = await this.#loadModel(llama, model.unwrap().path);
|
|
3805
|
+
const context = await loadedModel.createContext();
|
|
3806
|
+
const session = new llama.LlamaChatSession({
|
|
3807
|
+
contextSequence: context.getSequence(),
|
|
3808
|
+
systemPrompt: systemPromptFrom(request.prompt)
|
|
3809
|
+
});
|
|
3810
|
+
const text2 = await session.prompt(request.prompt.task.userMessage, {
|
|
3811
|
+
grammar: await this.#grammarFor(options.jsonSchema),
|
|
3812
|
+
maxTokens: request.options.maxOutputTokens ?? defaultLocalGenerationOptions.maxTokens,
|
|
3813
|
+
onTextChunk: options.onToken,
|
|
3814
|
+
seed: request.options.seed,
|
|
3815
|
+
temperature: request.options.temperature ?? defaultLocalGenerationOptions.temperature,
|
|
3816
|
+
topK: request.options.topK ?? defaultLocalGenerationOptions.topK,
|
|
3817
|
+
topP: request.options.topP ?? defaultLocalGenerationOptions.topP
|
|
3818
|
+
});
|
|
3819
|
+
const outputTokens = text2.split(/\s+/g).filter(Boolean).length;
|
|
3820
|
+
return Result.ok({
|
|
3821
|
+
finishReason: "stop",
|
|
3822
|
+
model: model.unwrap().id,
|
|
3823
|
+
provider: "local",
|
|
3824
|
+
schema: "agent-devkit.brain-response/v1",
|
|
3825
|
+
text: text2,
|
|
3826
|
+
usage: { outputTokens }
|
|
3827
|
+
});
|
|
3754
3828
|
});
|
|
3755
3829
|
} catch {
|
|
3756
3830
|
return Result.fail(ErrorCodes.BrainProviderUnavailable);
|
|
@@ -5326,6 +5400,33 @@ function characterName2(character) {
|
|
|
5326
5400
|
function compact(value) {
|
|
5327
5401
|
return value.replaceAll(/\s+/g, " ").trim();
|
|
5328
5402
|
}
|
|
5403
|
+
var agentDevKitConversationKnowledge = [
|
|
5404
|
+
{
|
|
5405
|
+
content: "Agent DevKit is a local AI agent toolkit exposed through the `agent` CLI, a TUI and MCP. It helps users operate this project through capabilities, local state, sessions, projects, preferences, personalization, logs, secrets, dependencies and local models.",
|
|
5406
|
+
id: "agent-devkit.identity",
|
|
5407
|
+
source: "conversation.chat"
|
|
5408
|
+
},
|
|
5409
|
+
{
|
|
5410
|
+
content: "When the user asks personal questions about you, your personality or what you can do, answer as the configured character using your behavior, tone, detail level and traits. Do not answer as a generic human and do not list unrelated human activities.",
|
|
5411
|
+
id: "agent-devkit.self-description-rule",
|
|
5412
|
+
source: "conversation.chat"
|
|
5413
|
+
},
|
|
5414
|
+
{
|
|
5415
|
+
content: "Only describe Agent DevKit internals, modules, tools, MCP, CLI commands or project capabilities when the user explicitly asks about Agent DevKit, the project, tools, commands, MCP or capabilities.",
|
|
5416
|
+
id: "agent-devkit.project-scope-rule",
|
|
5417
|
+
source: "conversation.chat"
|
|
5418
|
+
},
|
|
5419
|
+
{
|
|
5420
|
+
content: "This conversation mode can answer, keep session memory and use project context. Direct tool execution is disabled in this chat prompt.",
|
|
5421
|
+
id: "agent-devkit.chat-mode-limits",
|
|
5422
|
+
source: "conversation.chat"
|
|
5423
|
+
},
|
|
5424
|
+
{
|
|
5425
|
+
content: "Current capability areas include project doctor/init/reset, package update, preferences, themes, aliases, personalization characters, logs, encrypted secrets, dependency inspection/planning, models, projects, sessions and conversation.",
|
|
5426
|
+
id: "agent-devkit.capability-map",
|
|
5427
|
+
source: "conversation.chat"
|
|
5428
|
+
}
|
|
5429
|
+
];
|
|
5329
5430
|
var ConversationChatRepository = class {
|
|
5330
5431
|
repositoryId = "conversation.chat.repository";
|
|
5331
5432
|
#clock;
|
|
@@ -5470,7 +5571,7 @@ var ConversationChatRepository = class {
|
|
|
5470
5571
|
traits: input.character.profile.traits
|
|
5471
5572
|
},
|
|
5472
5573
|
context: {
|
|
5473
|
-
knowledge:
|
|
5574
|
+
knowledge: agentDevKitConversationKnowledge,
|
|
5474
5575
|
project: input.project === void 0 ? void 0 : {
|
|
5475
5576
|
description: input.project.description,
|
|
5476
5577
|
id: input.project.id,
|
|
@@ -5575,6 +5676,38 @@ var conversationChatCapabilityConfig = defineCapabilityConfig({
|
|
|
5575
5676
|
kind: "brain-assisted",
|
|
5576
5677
|
risk: "writes-global-state"
|
|
5577
5678
|
});
|
|
5679
|
+
function normalizeQuestion(value) {
|
|
5680
|
+
return value.normalize("NFD").replaceAll(new RegExp("\\p{Diacritic}", "gu"), "").toLowerCase().replaceAll(/[^\p{Letter}\p{Number}\s]/gu, " ").replaceAll(/\s+/g, " ").trim();
|
|
5681
|
+
}
|
|
5682
|
+
function isSelfDescriptionQuestion(message) {
|
|
5683
|
+
const normalized = normalizeQuestion(message);
|
|
5684
|
+
return normalized === "o que voce pode fazer" || normalized === "o que voce faz" || normalized === "quais sao suas capacidades" || normalized === "quais suas capacidades" || normalized === "what can you do" || normalized === "what do you do";
|
|
5685
|
+
}
|
|
5686
|
+
function countPromptTokens(request) {
|
|
5687
|
+
return request.prompt.messages.map((message) => message.content.split(/\s+/g).filter(Boolean).length).reduce((total, count) => total + count, 0);
|
|
5688
|
+
}
|
|
5689
|
+
function selfDescriptionResponse(request) {
|
|
5690
|
+
if (!isSelfDescriptionQuestion(request.prompt.task.userMessage)) {
|
|
5691
|
+
return void 0;
|
|
5692
|
+
}
|
|
5693
|
+
const { agent } = request.prompt;
|
|
5694
|
+
const traits = agent.traits.length === 0 ? "sem tracos extras configurados" : agent.traits.join(", ");
|
|
5695
|
+
const text2 = `${agent.name}: Eu posso conversar com voce mantendo o contexto da sessao, ajudar a raciocinar, organizar ideias, analisar informacoes e responder no meu estilo configurado. Minha postura e ${agent.behavior}, meu tom e ${agent.tone}, meu nivel de detalhe e ${agent.detailLevel}, e meus tracos atuais sao: ${traits}.`;
|
|
5696
|
+
const inputTokens = countPromptTokens(request);
|
|
5697
|
+
const outputTokens = text2.split(/\s+/g).filter(Boolean).length;
|
|
5698
|
+
return {
|
|
5699
|
+
finishReason: "stop",
|
|
5700
|
+
model: "self-description",
|
|
5701
|
+
provider: "system",
|
|
5702
|
+
schema: "agent-devkit.brain-response/v1",
|
|
5703
|
+
text: text2,
|
|
5704
|
+
usage: {
|
|
5705
|
+
inputTokens,
|
|
5706
|
+
outputTokens,
|
|
5707
|
+
totalTokens: inputTokens + outputTokens
|
|
5708
|
+
}
|
|
5709
|
+
};
|
|
5710
|
+
}
|
|
5578
5711
|
var ConversationChatService = class extends BaseCapabilityService {
|
|
5579
5712
|
inputSchema = ConversationChatOptionsSchema;
|
|
5580
5713
|
outputSchema = ConversationChatResultSchema;
|
|
@@ -5622,7 +5755,11 @@ var ConversationChatService = class extends BaseCapabilityService {
|
|
|
5622
5755
|
prompt: prepared.unwrap().prompt,
|
|
5623
5756
|
schema: "agent-devkit.brain-request/v1"
|
|
5624
5757
|
};
|
|
5625
|
-
const
|
|
5758
|
+
const selfDescription = selfDescriptionResponse(request);
|
|
5759
|
+
const brain = selfDescription === void 0 ? onToken !== void 0 && this.#brainProvider.generateStream !== void 0 ? await this.#brainProvider.generateStream(request, onToken) : await this.#brainProvider.generate(request) : Result.ok(selfDescription);
|
|
5760
|
+
if (selfDescription !== void 0) {
|
|
5761
|
+
onToken?.(selfDescription.text);
|
|
5762
|
+
}
|
|
5626
5763
|
if (brain.isErr()) {
|
|
5627
5764
|
return Result.fail(brain.unwrapError());
|
|
5628
5765
|
}
|
|
@@ -8016,7 +8153,7 @@ import {
|
|
|
8016
8153
|
ListToolsRequestSchema
|
|
8017
8154
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
8018
8155
|
|
|
8019
|
-
// src/
|
|
8156
|
+
// src/agent/agent.brain.ts
|
|
8020
8157
|
import { z as z23 } from "zod";
|
|
8021
8158
|
var AgentDecisionSchema = z23.discriminatedUnion("action", [
|
|
8022
8159
|
z23.object({ action: z23.literal("tool"), input: z23.unknown(), tool: z23.string().min(1) }),
|
|
@@ -8032,10 +8169,68 @@ var agentDecisionJsonSchema = {
|
|
|
8032
8169
|
},
|
|
8033
8170
|
required: ["action"]
|
|
8034
8171
|
};
|
|
8172
|
+
function maxToolCallsFor(tools) {
|
|
8173
|
+
return Math.max(1, tools.length);
|
|
8174
|
+
}
|
|
8175
|
+
function buildToolDecisionPrompt(input) {
|
|
8176
|
+
const toolList = input.tools.map((tool) => `- ${tool.id} (${tool.risk}): ${tool.description}`).join("\n");
|
|
8177
|
+
const instruction = [
|
|
8178
|
+
`Tarefa do usu\xE1rio: ${input.task}`,
|
|
8179
|
+
"",
|
|
8180
|
+
"Ferramentas dispon\xEDveis:",
|
|
8181
|
+
toolList,
|
|
8182
|
+
"",
|
|
8183
|
+
'Responda SOMENTE com JSON. Para usar uma ferramenta: {"action":"tool","tool":"<id>","input":{...}}. Para responder ao usu\xE1rio: {"action":"final","reply":"<texto>"}. Uma a\xE7\xE3o por vez.'
|
|
8184
|
+
].join("\n");
|
|
8185
|
+
return AgentPromptSchema.parse({
|
|
8186
|
+
agent: {
|
|
8187
|
+
behavior: "balanced",
|
|
8188
|
+
characterId: "agent",
|
|
8189
|
+
detailLevel: "concise",
|
|
8190
|
+
name: "Agent",
|
|
8191
|
+
tone: "direct",
|
|
8192
|
+
traits: []
|
|
8193
|
+
},
|
|
8194
|
+
context: {
|
|
8195
|
+
knowledge: [
|
|
8196
|
+
{
|
|
8197
|
+
content: "You are the Agent DevKit orchestration runtime. Choose tools only when they directly help complete the user's task.",
|
|
8198
|
+
id: "agent.runtime.identity"
|
|
8199
|
+
}
|
|
8200
|
+
]
|
|
8201
|
+
},
|
|
8202
|
+
locale: "pt-BR",
|
|
8203
|
+
messages: input.transcript,
|
|
8204
|
+
output: { format: "json", language: "pt-BR" },
|
|
8205
|
+
policies: {
|
|
8206
|
+
allowToolCalls: true,
|
|
8207
|
+
approvalRequired: false,
|
|
8208
|
+
maxToolCalls: maxToolCallsFor(input.tools)
|
|
8209
|
+
},
|
|
8210
|
+
schema: "agent-devkit.prompt/v1",
|
|
8211
|
+
task: { userMessage: instruction },
|
|
8212
|
+
tools: input.tools.map((tool) => ({
|
|
8213
|
+
description: tool.description,
|
|
8214
|
+
id: tool.id,
|
|
8215
|
+
inputSchema: tool.inputSchema,
|
|
8216
|
+
risk: tool.risk
|
|
8217
|
+
}))
|
|
8218
|
+
});
|
|
8219
|
+
}
|
|
8220
|
+
|
|
8221
|
+
// src/agent/agent.policy.ts
|
|
8222
|
+
function isToolApproved(tool, input) {
|
|
8223
|
+
if (input.approvedTools !== void 0) {
|
|
8224
|
+
return input.approvedTools.includes(tool);
|
|
8225
|
+
}
|
|
8226
|
+
return input.approved === true;
|
|
8227
|
+
}
|
|
8228
|
+
|
|
8229
|
+
// src/agent/agent.loop.ts
|
|
8035
8230
|
function summarize(value) {
|
|
8036
8231
|
const text2 = typeof value === "string" ? value : JSON.stringify(value ?? "");
|
|
8037
8232
|
const compact2 = text2.replaceAll(/\s+/g, " ").trim();
|
|
8038
|
-
return compact2.length > 240 ? `${compact2.slice(0, 240)}
|
|
8233
|
+
return compact2.length > 240 ? `${compact2.slice(0, 240)}...` : compact2;
|
|
8039
8234
|
}
|
|
8040
8235
|
function observationSummary(result) {
|
|
8041
8236
|
if (result.status === "succeeded") {
|
|
@@ -8043,7 +8238,7 @@ function observationSummary(result) {
|
|
|
8043
8238
|
}
|
|
8044
8239
|
return `${result.status}${result.error === void 0 ? "" : `: ${result.error.message}`}`;
|
|
8045
8240
|
}
|
|
8046
|
-
var
|
|
8241
|
+
var AgentToolLoop = class {
|
|
8047
8242
|
#brain;
|
|
8048
8243
|
#tools;
|
|
8049
8244
|
constructor(options) {
|
|
@@ -8063,7 +8258,11 @@ var AgentRuntime = class {
|
|
|
8063
8258
|
}));
|
|
8064
8259
|
const tools = this.#tools.listTools();
|
|
8065
8260
|
for (let step = 0; step < maxSteps; step += 1) {
|
|
8066
|
-
const prompt =
|
|
8261
|
+
const prompt = buildToolDecisionPrompt({
|
|
8262
|
+
task: input.task,
|
|
8263
|
+
tools,
|
|
8264
|
+
transcript
|
|
8265
|
+
});
|
|
8067
8266
|
const request = {
|
|
8068
8267
|
options: { provider: "local", role: "agent" },
|
|
8069
8268
|
prompt,
|
|
@@ -8075,19 +8274,19 @@ var AgentRuntime = class {
|
|
|
8075
8274
|
}
|
|
8076
8275
|
const decision = AgentDecisionSchema.safeParse(structured.unwrap().json);
|
|
8077
8276
|
if (!decision.success) {
|
|
8078
|
-
return Result.ok({ reply: structured.unwrap().raw.trim(), steps });
|
|
8277
|
+
return Result.ok({ mode: "task", reply: structured.unwrap().raw.trim(), steps });
|
|
8079
8278
|
}
|
|
8080
8279
|
if (decision.data.action === "final") {
|
|
8081
8280
|
input.onEvent?.({ reply: decision.data.reply, type: "final" });
|
|
8082
|
-
return Result.ok({ reply: decision.data.reply, steps });
|
|
8281
|
+
return Result.ok({ mode: "task", reply: decision.data.reply, steps });
|
|
8083
8282
|
}
|
|
8084
8283
|
const tool = decision.data.tool;
|
|
8085
8284
|
input.onEvent?.({ tool, type: "tool" });
|
|
8086
8285
|
const execution = await this.#tools.execute({
|
|
8087
|
-
approved:
|
|
8286
|
+
approved: isToolApproved(tool, input),
|
|
8088
8287
|
capabilityId: tool,
|
|
8089
8288
|
input: decision.data.input,
|
|
8090
|
-
interface: "agent",
|
|
8289
|
+
interface: input.interface ?? "agent",
|
|
8091
8290
|
requestedBy: "agent.run"
|
|
8092
8291
|
});
|
|
8093
8292
|
const ok = execution.status === "succeeded";
|
|
@@ -8097,64 +8296,86 @@ var AgentRuntime = class {
|
|
|
8097
8296
|
transcript.push({ content: `Observation from ${tool}: ${summary}`, role: "tool" });
|
|
8098
8297
|
if (execution.status === "approval_required") {
|
|
8099
8298
|
return Result.ok({
|
|
8299
|
+
mode: "task",
|
|
8100
8300
|
reply: `A ferramenta ${tool} requer aprova\xE7\xE3o expl\xEDcita. Reexecute autorizando para continuar.`,
|
|
8101
8301
|
steps
|
|
8102
8302
|
});
|
|
8103
8303
|
}
|
|
8104
8304
|
}
|
|
8105
8305
|
return Result.ok({
|
|
8306
|
+
mode: "task",
|
|
8106
8307
|
reply: "Limite de passos do agente atingido sem uma resposta final.",
|
|
8107
8308
|
steps
|
|
8108
8309
|
});
|
|
8109
8310
|
}
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8311
|
+
};
|
|
8312
|
+
|
|
8313
|
+
// src/agent/agent.runtime.ts
|
|
8314
|
+
function textInput(input) {
|
|
8315
|
+
return (input.message ?? input.task ?? "").trim();
|
|
8316
|
+
}
|
|
8317
|
+
function resolveMode(input) {
|
|
8318
|
+
if (input.mode === "chat" || input.mode === "task") {
|
|
8319
|
+
return input.mode;
|
|
8320
|
+
}
|
|
8321
|
+
if (input.message !== void 0) {
|
|
8322
|
+
return "chat";
|
|
8323
|
+
}
|
|
8324
|
+
return "task";
|
|
8325
|
+
}
|
|
8326
|
+
function chatInput(input, message) {
|
|
8327
|
+
return {
|
|
8328
|
+
characterId: input.characterId,
|
|
8329
|
+
includeHistory: input.includeHistory,
|
|
8330
|
+
interface: input.interface ?? "cli",
|
|
8331
|
+
message,
|
|
8332
|
+
projectId: input.projectId,
|
|
8333
|
+
sessionId: input.sessionId
|
|
8334
|
+
};
|
|
8335
|
+
}
|
|
8336
|
+
var AgentRuntime = class {
|
|
8337
|
+
#conversation;
|
|
8338
|
+
#toolLoop;
|
|
8339
|
+
constructor(options) {
|
|
8340
|
+
this.#conversation = options.conversation;
|
|
8341
|
+
this.#toolLoop = new AgentToolLoop({
|
|
8342
|
+
brainProvider: options.brainProvider,
|
|
8343
|
+
toolRuntime: options.toolRuntime
|
|
8344
|
+
});
|
|
8345
|
+
}
|
|
8346
|
+
async run(input) {
|
|
8347
|
+
const message = textInput(input);
|
|
8348
|
+
if (message.length === 0) {
|
|
8349
|
+
return Result.fail(ErrorCodes.InvalidInput);
|
|
8113
8350
|
}
|
|
8114
|
-
|
|
8351
|
+
const mode = resolveMode(input);
|
|
8352
|
+
if (mode === "chat") {
|
|
8353
|
+
return this.#runChat(input, message);
|
|
8354
|
+
}
|
|
8355
|
+
return this.#toolLoop.run({ ...input, task: message });
|
|
8115
8356
|
}
|
|
8116
|
-
#
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
""
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
context: { knowledge: [] },
|
|
8136
|
-
locale: "pt-BR",
|
|
8137
|
-
messages: transcript,
|
|
8138
|
-
output: { format: "json", language: "pt-BR" },
|
|
8139
|
-
policies: {
|
|
8140
|
-
allowToolCalls: true,
|
|
8141
|
-
approvalRequired: false,
|
|
8142
|
-
maxToolCalls: maxToolCallsFor(tools)
|
|
8143
|
-
},
|
|
8144
|
-
schema: "agent-devkit.prompt/v1",
|
|
8145
|
-
task: { userMessage: instruction },
|
|
8146
|
-
tools: tools.map((tool) => ({
|
|
8147
|
-
description: tool.description,
|
|
8148
|
-
id: tool.id,
|
|
8149
|
-
inputSchema: tool.inputSchema,
|
|
8150
|
-
risk: tool.risk
|
|
8151
|
-
}))
|
|
8357
|
+
async #runChat(input, message) {
|
|
8358
|
+
if (this.#conversation === void 0) {
|
|
8359
|
+
return Result.fail(ErrorCodes.BrainProviderUnavailable);
|
|
8360
|
+
}
|
|
8361
|
+
const result = await this.#conversation.chat(chatInput(input, message), {
|
|
8362
|
+
approved: input.approved,
|
|
8363
|
+
interface: input.interface ?? "cli",
|
|
8364
|
+
requestedBy: "agent.chat"
|
|
8365
|
+
});
|
|
8366
|
+
if (result.isErr()) {
|
|
8367
|
+
return Result.fail(result.unwrapError());
|
|
8368
|
+
}
|
|
8369
|
+
const conversation = result.unwrap();
|
|
8370
|
+
input.onEvent?.({ reply: conversation.reply, type: "final" });
|
|
8371
|
+
return Result.ok({
|
|
8372
|
+
conversation,
|
|
8373
|
+
mode: "chat",
|
|
8374
|
+
reply: conversation.reply,
|
|
8375
|
+
steps: []
|
|
8152
8376
|
});
|
|
8153
8377
|
}
|
|
8154
8378
|
};
|
|
8155
|
-
function maxToolCallsFor(tools) {
|
|
8156
|
-
return Math.max(1, tools.length);
|
|
8157
|
-
}
|
|
8158
8379
|
|
|
8159
8380
|
// src/app/mcp/mcp_result_mapper.ts
|
|
8160
8381
|
function inputSchemaWithAgentControl(tool) {
|
|
@@ -8309,7 +8530,7 @@ function createAgentMcpServer(options) {
|
|
|
8309
8530
|
if (task.length === 0) {
|
|
8310
8531
|
return { content: [{ type: "text", text: "Missing 'task'." }], isError: true };
|
|
8311
8532
|
}
|
|
8312
|
-
const run = await agent.run({ approvedTools, task });
|
|
8533
|
+
const run = await agent.run({ approvedTools, interface: "mcp", mode: "task", task });
|
|
8313
8534
|
if (run.isErr()) {
|
|
8314
8535
|
return {
|
|
8315
8536
|
content: [{ type: "text", text: `Agent run failed: ${run.unwrapError()}` }],
|
|
@@ -9936,30 +10157,148 @@ import { homedir as homedir22 } from "os";
|
|
|
9936
10157
|
|
|
9937
10158
|
// src/modules/conversation/capabilities/chat/chat.viewmodel.ts
|
|
9938
10159
|
function formatConversationChatText(result) {
|
|
9939
|
-
const
|
|
10160
|
+
const agentName = result.prompt.agent.name.trim();
|
|
10161
|
+
const reply2 = result.reply.trim();
|
|
10162
|
+
const speakerPrefix = `${agentName}:`;
|
|
10163
|
+
const normalizedReply = reply2.toLowerCase().startsWith(speakerPrefix.toLowerCase()) ? reply2 : `${speakerPrefix} ${reply2}`;
|
|
10164
|
+
const metadata = [`Session: ${result.sessionId}`];
|
|
9940
10165
|
if (result.projectId !== void 0) {
|
|
9941
|
-
|
|
10166
|
+
metadata.push(`Project: ${result.projectId}`);
|
|
9942
10167
|
}
|
|
9943
|
-
|
|
10168
|
+
if (result.brain.model !== void 0 || result.brain.provider !== void 0) {
|
|
10169
|
+
metadata.push(
|
|
10170
|
+
`Model: ${[result.brain.provider, result.brain.model].filter(Boolean).join("/")}`
|
|
10171
|
+
);
|
|
10172
|
+
}
|
|
10173
|
+
if (result.brain.usage !== void 0) {
|
|
10174
|
+
const tokens = [
|
|
10175
|
+
result.brain.usage.inputTokens === void 0 ? void 0 : `input ${result.brain.usage.inputTokens}`,
|
|
10176
|
+
result.brain.usage.outputTokens === void 0 ? void 0 : `output ${result.brain.usage.outputTokens}`,
|
|
10177
|
+
result.brain.usage.totalTokens === void 0 ? void 0 : `total ${result.brain.usage.totalTokens}`
|
|
10178
|
+
].filter(Boolean);
|
|
10179
|
+
if (tokens.length > 0) {
|
|
10180
|
+
metadata.push(`Tokens: ${tokens.join(", ")}`);
|
|
10181
|
+
}
|
|
10182
|
+
}
|
|
10183
|
+
return [normalizedReply, "", ...metadata].join("\n");
|
|
9944
10184
|
}
|
|
9945
10185
|
|
|
9946
10186
|
// src/app/cli/rootConversation.ts
|
|
9947
|
-
|
|
10187
|
+
var cliConversationStatePath = {
|
|
10188
|
+
namespace: "conversation",
|
|
10189
|
+
segments: ["cli-state.json"]
|
|
10190
|
+
};
|
|
10191
|
+
function isCliConversationState(value) {
|
|
10192
|
+
const record = value;
|
|
10193
|
+
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";
|
|
10194
|
+
}
|
|
10195
|
+
async function loadActiveCliSessionId(dataStore, sessions) {
|
|
10196
|
+
const state = await dataStore.readJson(cliConversationStatePath);
|
|
10197
|
+
if (state.isErr()) {
|
|
10198
|
+
return void 0;
|
|
10199
|
+
}
|
|
10200
|
+
const statePayload = state.unwrap();
|
|
10201
|
+
if (!isCliConversationState(statePayload)) {
|
|
10202
|
+
return void 0;
|
|
10203
|
+
}
|
|
10204
|
+
const current = await sessions.execute({
|
|
10205
|
+
action: "show",
|
|
10206
|
+
includeMessages: false,
|
|
10207
|
+
sessionId: statePayload.activeSessionId
|
|
10208
|
+
});
|
|
10209
|
+
if (current.isErr()) {
|
|
10210
|
+
return void 0;
|
|
10211
|
+
}
|
|
10212
|
+
const result = current.unwrap();
|
|
10213
|
+
if (result.action !== "show" || result.session.origin !== "cli" || result.session.status !== "active") {
|
|
10214
|
+
return void 0;
|
|
10215
|
+
}
|
|
10216
|
+
return result.session.id;
|
|
10217
|
+
}
|
|
10218
|
+
async function saveActiveCliSessionId(dataStore, sessionId) {
|
|
10219
|
+
await dataStore.writeJson(
|
|
10220
|
+
cliConversationStatePath,
|
|
10221
|
+
{
|
|
10222
|
+
activeSessionId: sessionId,
|
|
10223
|
+
schema: "agent-devkit.cli-conversation-state/v1",
|
|
10224
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10225
|
+
},
|
|
10226
|
+
{ atomic: true }
|
|
10227
|
+
);
|
|
10228
|
+
}
|
|
10229
|
+
function createConversationPort(chat) {
|
|
10230
|
+
return {
|
|
10231
|
+
chat: async (input, context) => {
|
|
10232
|
+
const result = await chat.invoke(
|
|
10233
|
+
{
|
|
10234
|
+
action: "send",
|
|
10235
|
+
characterId: input.characterId,
|
|
10236
|
+
includeHistory: input.includeHistory,
|
|
10237
|
+
message: input.message,
|
|
10238
|
+
projectId: input.projectId,
|
|
10239
|
+
sessionId: input.sessionId
|
|
10240
|
+
},
|
|
10241
|
+
context
|
|
10242
|
+
);
|
|
10243
|
+
return result.map((payload) => ({
|
|
10244
|
+
brain: payload.brain,
|
|
10245
|
+
projectId: payload.projectId,
|
|
10246
|
+
raw: payload,
|
|
10247
|
+
reply: payload.reply,
|
|
10248
|
+
sessionId: payload.sessionId
|
|
10249
|
+
}));
|
|
10250
|
+
}
|
|
10251
|
+
};
|
|
10252
|
+
}
|
|
10253
|
+
async function runRootConversation(message, options) {
|
|
10254
|
+
const homeDirectory = homedir22();
|
|
10255
|
+
const dataStore = new LocalAgentDataStore({
|
|
10256
|
+
rootDirectory: `${homeDirectory}/.agent-devkit/data`
|
|
10257
|
+
});
|
|
9948
10258
|
const bindings = createConversationModuleBindings({
|
|
9949
|
-
brainProvider: createBrainDockProvider({ stateDirectory: `${
|
|
9950
|
-
|
|
10259
|
+
brainProvider: createBrainDockProvider({ stateDirectory: `${homeDirectory}/.agent-devkit` }),
|
|
10260
|
+
dataStore,
|
|
10261
|
+
homeDirectory
|
|
9951
10262
|
});
|
|
10263
|
+
const contextBindings = createContextModuleBindings({ dataStore, homeDirectory });
|
|
9952
10264
|
if (bindings.isErr()) {
|
|
9953
10265
|
throw new Error(bindings.unwrapError());
|
|
9954
10266
|
}
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
10267
|
+
if (contextBindings.isErr()) {
|
|
10268
|
+
throw new Error(contextBindings.unwrapError());
|
|
10269
|
+
}
|
|
10270
|
+
const activeSessionId = await loadActiveCliSessionId(
|
|
10271
|
+
dataStore,
|
|
10272
|
+
contextBindings.unwrap().capabilities.sessions
|
|
10273
|
+
);
|
|
10274
|
+
const agent = new AgentRuntime({
|
|
10275
|
+
brainProvider: createBrainDockProvider({ stateDirectory: `${homeDirectory}/.agent-devkit` }),
|
|
10276
|
+
conversation: createConversationPort(bindings.unwrap().capabilities.chat),
|
|
10277
|
+
toolRuntime: createCliToolRuntime({
|
|
10278
|
+
currentVersion: options.currentVersion,
|
|
10279
|
+
packageName: options.packageName
|
|
10280
|
+
})
|
|
10281
|
+
});
|
|
10282
|
+
const result = await agent.run({
|
|
10283
|
+
interface: "cli",
|
|
10284
|
+
message,
|
|
10285
|
+
mode: "chat",
|
|
10286
|
+
sessionId: activeSessionId
|
|
9958
10287
|
});
|
|
9959
10288
|
if (result.isErr()) {
|
|
9960
10289
|
throw new Error(result.unwrapError());
|
|
9961
10290
|
}
|
|
9962
|
-
|
|
10291
|
+
const payload = result.unwrap();
|
|
10292
|
+
const rawConversation = payload.conversation?.raw;
|
|
10293
|
+
if (payload.conversation === void 0 || !isConversationChatResult(rawConversation)) {
|
|
10294
|
+
throw new Error("Agent did not return a conversation result.");
|
|
10295
|
+
}
|
|
10296
|
+
await saveActiveCliSessionId(dataStore, payload.conversation.sessionId);
|
|
10297
|
+
console.log(formatConversationChatText(rawConversation));
|
|
10298
|
+
}
|
|
10299
|
+
function isConversationChatResult(value) {
|
|
10300
|
+
const candidate = value;
|
|
10301
|
+
return typeof value === "object" && value !== null && candidate.action === "send" && typeof candidate.reply === "string" && typeof candidate.sessionId === "string";
|
|
9963
10302
|
}
|
|
9964
10303
|
|
|
9965
10304
|
// src/infra/helpers/redaction.ts
|
|
@@ -10300,7 +10639,10 @@ program.name("agent").description(translator.t("cli.root.description")).version(
|
|
|
10300
10639
|
program.error(translator.t("cli.root.removedChatCommand"));
|
|
10301
10640
|
}
|
|
10302
10641
|
if (initialPrompt.length > 0) {
|
|
10303
|
-
await runRootConversation(initialPrompt
|
|
10642
|
+
await runRootConversation(initialPrompt, {
|
|
10643
|
+
currentVersion: package_default.version,
|
|
10644
|
+
packageName: package_default.name
|
|
10645
|
+
});
|
|
10304
10646
|
return;
|
|
10305
10647
|
}
|
|
10306
10648
|
await ensureFirstRunModel(translator);
|