agent-devkit 0.3.4 → 0.5.6
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 +547 -148
- 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.
|
|
11
|
+
version: "0.5.6",
|
|
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",
|
|
@@ -3385,6 +3385,80 @@ function createEnvironmentSurface() {
|
|
|
3385
3385
|
// src/app/cli/toolRuntime.ts
|
|
3386
3386
|
import { homedir as homedir11 } from "os";
|
|
3387
3387
|
|
|
3388
|
+
// src/infra/helpers/tool_schema_summary.ts
|
|
3389
|
+
var MAX_VARIANTS = 12;
|
|
3390
|
+
var MAX_PROPS = 10;
|
|
3391
|
+
var MAX_ENUM = 6;
|
|
3392
|
+
function asRecord(value) {
|
|
3393
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
3394
|
+
}
|
|
3395
|
+
function propHint(name, schema, required) {
|
|
3396
|
+
const suffix = required ? "" : "?";
|
|
3397
|
+
const enumValues = Array.isArray(schema?.enum) ? schema?.enum : void 0;
|
|
3398
|
+
if (enumValues !== void 0 && enumValues.length > 0) {
|
|
3399
|
+
const shown = enumValues.slice(0, MAX_ENUM).map(String).join("|");
|
|
3400
|
+
const more = enumValues.length > MAX_ENUM ? "|..." : "";
|
|
3401
|
+
return `${name}[${shown}${more}]${suffix}`;
|
|
3402
|
+
}
|
|
3403
|
+
return `${name}${suffix}`;
|
|
3404
|
+
}
|
|
3405
|
+
function detectDiscriminator(variants) {
|
|
3406
|
+
const first = asRecord(variants[0]?.properties);
|
|
3407
|
+
if (first === void 0) {
|
|
3408
|
+
return void 0;
|
|
3409
|
+
}
|
|
3410
|
+
for (const name of Object.keys(first)) {
|
|
3411
|
+
const isDiscriminator = variants.every((variant) => {
|
|
3412
|
+
const property = asRecord(asRecord(variant.properties)?.[name]);
|
|
3413
|
+
return property !== void 0 && (typeof property.const === "string" || Array.isArray(property.enum));
|
|
3414
|
+
});
|
|
3415
|
+
if (isDiscriminator) {
|
|
3416
|
+
return name;
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
return void 0;
|
|
3420
|
+
}
|
|
3421
|
+
function variantSummary(variant, discriminator) {
|
|
3422
|
+
const props = asRecord(variant.properties);
|
|
3423
|
+
if (props === void 0) {
|
|
3424
|
+
return void 0;
|
|
3425
|
+
}
|
|
3426
|
+
const required = new Set(Array.isArray(variant.required) ? variant.required : []);
|
|
3427
|
+
const discriminatorSchema = asRecord(props[discriminator]);
|
|
3428
|
+
const label = typeof discriminatorSchema?.const === "string" ? discriminatorSchema.const : Array.isArray(discriminatorSchema?.enum) ? String((discriminatorSchema?.enum)[0]) : void 0;
|
|
3429
|
+
if (label === void 0) {
|
|
3430
|
+
return void 0;
|
|
3431
|
+
}
|
|
3432
|
+
const params = Object.keys(props).filter((name) => name !== discriminator).slice(0, MAX_PROPS).map((name) => propHint(name, asRecord(props[name]), required.has(name)));
|
|
3433
|
+
const paramText = params.length > 0 ? `(${params.join(", ")})` : "";
|
|
3434
|
+
return `${label}${paramText}`;
|
|
3435
|
+
}
|
|
3436
|
+
function summarizeToolSchema(schema) {
|
|
3437
|
+
const union = Array.isArray(schema.oneOf) ? schema.oneOf : Array.isArray(schema.anyOf) ? schema.anyOf : void 0;
|
|
3438
|
+
if (union !== void 0) {
|
|
3439
|
+
const variants = union.map(asRecord).filter((variant) => variant !== void 0);
|
|
3440
|
+
const discriminator = detectDiscriminator(variants) ?? "action";
|
|
3441
|
+
const summaries = variants.slice(0, MAX_VARIANTS).map((variant) => variantSummary(variant, discriminator)).filter((summary) => summary !== void 0);
|
|
3442
|
+
if (summaries.length === 0) {
|
|
3443
|
+
return "";
|
|
3444
|
+
}
|
|
3445
|
+
const more2 = variants.length > MAX_VARIANTS ? " | ..." : "";
|
|
3446
|
+
return `${discriminator} = ${summaries.join(" | ")}${more2}`;
|
|
3447
|
+
}
|
|
3448
|
+
const props = asRecord(schema.properties);
|
|
3449
|
+
if (props === void 0) {
|
|
3450
|
+
return "";
|
|
3451
|
+
}
|
|
3452
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
3453
|
+
const names = Object.keys(props);
|
|
3454
|
+
const fields = names.slice(0, MAX_PROPS).map((name) => propHint(name, asRecord(props[name]), required.has(name)));
|
|
3455
|
+
if (fields.length === 0) {
|
|
3456
|
+
return "";
|
|
3457
|
+
}
|
|
3458
|
+
const more = names.length > MAX_PROPS ? ", ..." : "";
|
|
3459
|
+
return `fields: ${fields.join(", ")}${more}`;
|
|
3460
|
+
}
|
|
3461
|
+
|
|
3388
3462
|
// src/infra/models/model_store.ts
|
|
3389
3463
|
import { createHash } from "crypto";
|
|
3390
3464
|
import { once } from "events";
|
|
@@ -3724,11 +3798,14 @@ function systemPromptFrom(prompt) {
|
|
|
3724
3798
|
);
|
|
3725
3799
|
}
|
|
3726
3800
|
if (prompt.tools.length > 0) {
|
|
3727
|
-
lines.push(
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3801
|
+
lines.push("", "Available tools:");
|
|
3802
|
+
for (const tool of prompt.tools) {
|
|
3803
|
+
lines.push(`- ${tool.id} (${tool.risk}): ${tool.description}`);
|
|
3804
|
+
const schema = tool.inputSchema === void 0 ? "" : summarizeToolSchema(tool.inputSchema);
|
|
3805
|
+
if (schema.length > 0) {
|
|
3806
|
+
lines.push(` input: ${schema}`);
|
|
3807
|
+
}
|
|
3808
|
+
}
|
|
3732
3809
|
}
|
|
3733
3810
|
lines.push(
|
|
3734
3811
|
"",
|
|
@@ -3743,7 +3820,7 @@ function systemPromptFrom(prompt) {
|
|
|
3743
3820
|
);
|
|
3744
3821
|
}
|
|
3745
3822
|
lines.push(`Reply in ${prompt.output.language}.`);
|
|
3746
|
-
const history = prompt.messages.filter((message) => message.role === "user" || message.role === "assistant").slice(0, -1).map((message) => `${message.role
|
|
3823
|
+
const history = prompt.messages.filter((message) => message.role === "user" || message.role === "assistant").slice(0, -1).map((message) => `${message.role}: ${message.content}`);
|
|
3747
3824
|
if (history.length > 0) {
|
|
3748
3825
|
lines.push("", "Conversation so far:", ...history);
|
|
3749
3826
|
}
|
|
@@ -3878,7 +3955,9 @@ var LocalLlamaBrainProvider = class {
|
|
|
3878
3955
|
return cached;
|
|
3879
3956
|
}
|
|
3880
3957
|
if (this.#llama === void 0) {
|
|
3881
|
-
this.#llama = await llama.getLlama(
|
|
3958
|
+
this.#llama = await llama.getLlama({
|
|
3959
|
+
logLevel: llama.LlamaLogLevel?.error ?? llama.LlamaLogLevel?.fatal
|
|
3960
|
+
});
|
|
3882
3961
|
}
|
|
3883
3962
|
const model = await this.#llama.loadModel({ modelPath });
|
|
3884
3963
|
this.#models.set(modelPath, model);
|
|
@@ -3888,7 +3967,7 @@ var LocalLlamaBrainProvider = class {
|
|
|
3888
3967
|
|
|
3889
3968
|
// src/infra/brain/mock_provider.ts
|
|
3890
3969
|
function reply(request) {
|
|
3891
|
-
const text2 =
|
|
3970
|
+
const text2 = `Entendi. Vou responder no contexto da sess\xE3o atual: "${request.prompt.task.userMessage}".`;
|
|
3892
3971
|
const inputTokens = request.prompt.messages.map((message) => message.content.split(/\s+/g).filter(Boolean).length).reduce((total, count) => total + count, 0);
|
|
3893
3972
|
const outputTokens = text2.split(/\s+/g).filter(Boolean).length;
|
|
3894
3973
|
return {
|
|
@@ -3913,8 +3992,11 @@ var MockBrainProvider = class {
|
|
|
3913
3992
|
onToken(response.text);
|
|
3914
3993
|
return Result.ok(response);
|
|
3915
3994
|
}
|
|
3916
|
-
async generateStructured(request,
|
|
3917
|
-
const
|
|
3995
|
+
async generateStructured(request, jsonSchema) {
|
|
3996
|
+
const properties = typeof jsonSchema.properties === "object" && jsonSchema.properties !== null && !Array.isArray(jsonSchema.properties) ? jsonSchema.properties : {};
|
|
3997
|
+
const isAgentRouteSchema = "action" in properties && "tool" in properties;
|
|
3998
|
+
const text2 = isAgentRouteSchema ? "Mock brain ativo. Instale ou configure um modelo local para executar roteamento agentic real." : reply(request).text;
|
|
3999
|
+
const raw = JSON.stringify({ action: "final", reply: text2 });
|
|
3918
4000
|
return Result.ok({ json: JSON.parse(raw), raw });
|
|
3919
4001
|
}
|
|
3920
4002
|
};
|
|
@@ -5676,37 +5758,19 @@ var conversationChatCapabilityConfig = defineCapabilityConfig({
|
|
|
5676
5758
|
kind: "brain-assisted",
|
|
5677
5759
|
risk: "writes-global-state"
|
|
5678
5760
|
});
|
|
5679
|
-
function
|
|
5680
|
-
|
|
5681
|
-
}
|
|
5682
|
-
|
|
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";
|
|
5761
|
+
function stripLeadingAgentPrefixes(text2, agentName) {
|
|
5762
|
+
const escaped = agentName.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5763
|
+
const prefixPattern = new RegExp(`^(?:\\s*${escaped}\\s*:\\s*)+`, "iu");
|
|
5764
|
+
return text2.replace(prefixPattern, "").trim();
|
|
5685
5765
|
}
|
|
5686
|
-
function
|
|
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);
|
|
5766
|
+
function responseWithText(response, text2) {
|
|
5697
5767
|
const outputTokens = text2.split(/\s+/g).filter(Boolean).length;
|
|
5698
|
-
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
schema: "agent-devkit.brain-response/v1",
|
|
5703
|
-
text: text2,
|
|
5704
|
-
usage: {
|
|
5705
|
-
inputTokens,
|
|
5706
|
-
outputTokens,
|
|
5707
|
-
totalTokens: inputTokens + outputTokens
|
|
5708
|
-
}
|
|
5768
|
+
const usage = response.usage === void 0 ? void 0 : {
|
|
5769
|
+
...response.usage,
|
|
5770
|
+
outputTokens,
|
|
5771
|
+
totalTokens: response.usage.inputTokens === void 0 ? response.usage.totalTokens : response.usage.inputTokens + outputTokens
|
|
5709
5772
|
};
|
|
5773
|
+
return { ...response, text: text2, usage };
|
|
5710
5774
|
}
|
|
5711
5775
|
var ConversationChatService = class extends BaseCapabilityService {
|
|
5712
5776
|
inputSchema = ConversationChatOptionsSchema;
|
|
@@ -5751,32 +5815,32 @@ var ConversationChatService = class extends BaseCapabilityService {
|
|
|
5751
5815
|
return Result.fail(prepared.unwrapError());
|
|
5752
5816
|
}
|
|
5753
5817
|
const request = {
|
|
5754
|
-
options: parsed.data.brain
|
|
5818
|
+
options: { provider: "local", ...parsed.data.brain, role: "chat" },
|
|
5755
5819
|
prompt: prepared.unwrap().prompt,
|
|
5756
5820
|
schema: "agent-devkit.brain-request/v1"
|
|
5757
5821
|
};
|
|
5758
|
-
const
|
|
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
|
-
}
|
|
5822
|
+
const brain = onToken !== void 0 && this.#brainProvider.generateStream !== void 0 ? await this.#brainProvider.generateStream(request, onToken) : await this.#brainProvider.generate(request);
|
|
5763
5823
|
if (brain.isErr()) {
|
|
5764
5824
|
return Result.fail(brain.unwrapError());
|
|
5765
5825
|
}
|
|
5826
|
+
const normalizedBrain = responseWithText(
|
|
5827
|
+
brain.unwrap(),
|
|
5828
|
+
stripLeadingAgentPrefixes(brain.unwrap().text, prepared.unwrap().prompt.agent.name)
|
|
5829
|
+
);
|
|
5766
5830
|
const messages = await this.#repository.appendAssistantMessage(
|
|
5767
5831
|
prepared.unwrap().sessionId,
|
|
5768
|
-
|
|
5832
|
+
normalizedBrain.text
|
|
5769
5833
|
);
|
|
5770
5834
|
if (messages.isErr()) {
|
|
5771
5835
|
return Result.fail(messages.unwrapError());
|
|
5772
5836
|
}
|
|
5773
5837
|
const result = this.outputSchema.safeParse({
|
|
5774
5838
|
action: "send",
|
|
5775
|
-
brain:
|
|
5839
|
+
brain: normalizedBrain,
|
|
5776
5840
|
messages: messages.unwrap(),
|
|
5777
5841
|
projectId: prepared.unwrap().projectId,
|
|
5778
5842
|
prompt: prepared.unwrap().prompt,
|
|
5779
|
-
reply:
|
|
5843
|
+
reply: normalizedBrain.text,
|
|
5780
5844
|
sessionId: prepared.unwrap().sessionId
|
|
5781
5845
|
});
|
|
5782
5846
|
return result.success ? Result.ok(result.data) : Result.fail(ErrorCodes.InvalidInput);
|
|
@@ -8140,6 +8204,37 @@ function registerLogsCommand(program2, options) {
|
|
|
8140
8204
|
);
|
|
8141
8205
|
}
|
|
8142
8206
|
|
|
8207
|
+
// src/modules/module_knowledge_catalog.ts
|
|
8208
|
+
function createModuleSurfaceKnowledge() {
|
|
8209
|
+
let cache;
|
|
8210
|
+
return {
|
|
8211
|
+
async all() {
|
|
8212
|
+
if (cache !== void 0) {
|
|
8213
|
+
return cache;
|
|
8214
|
+
}
|
|
8215
|
+
const modules = [];
|
|
8216
|
+
for (const definition of agentModuleDefinitions) {
|
|
8217
|
+
const surface = definition.surface();
|
|
8218
|
+
const [knowledge, skill, loop] = await Promise.all([
|
|
8219
|
+
surface.knowledge(),
|
|
8220
|
+
surface.skill(),
|
|
8221
|
+
surface.loop()
|
|
8222
|
+
]);
|
|
8223
|
+
modules.push({
|
|
8224
|
+
facts: knowledge.isOk() ? knowledge.unwrap().facts : [],
|
|
8225
|
+
forbiddenActions: loop.isOk() ? loop.unwrap().forbiddenActions : [],
|
|
8226
|
+
moduleId: definition.id,
|
|
8227
|
+
summary: knowledge.isOk() ? knowledge.unwrap().summary : "",
|
|
8228
|
+
whenNotToUse: skill.isOk() ? skill.unwrap().whenNotToUse : [],
|
|
8229
|
+
whenToUse: skill.isOk() ? skill.unwrap().whenToUse : []
|
|
8230
|
+
});
|
|
8231
|
+
}
|
|
8232
|
+
cache = modules;
|
|
8233
|
+
return modules;
|
|
8234
|
+
}
|
|
8235
|
+
};
|
|
8236
|
+
}
|
|
8237
|
+
|
|
8143
8238
|
// src/app/mcp/mcp_http_transport.ts
|
|
8144
8239
|
import { createServer } from "http";
|
|
8145
8240
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
@@ -8150,29 +8245,139 @@ import { join as join16 } from "path";
|
|
|
8150
8245
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
8151
8246
|
import {
|
|
8152
8247
|
CallToolRequestSchema,
|
|
8153
|
-
|
|
8248
|
+
ListResourcesRequestSchema,
|
|
8249
|
+
ListToolsRequestSchema,
|
|
8250
|
+
ReadResourceRequestSchema
|
|
8154
8251
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
8155
8252
|
|
|
8156
|
-
// src/
|
|
8253
|
+
// src/agent/agent.brain.ts
|
|
8157
8254
|
import { z as z23 } from "zod";
|
|
8158
|
-
var
|
|
8159
|
-
z23.object({ action: z23.literal("tool"),
|
|
8255
|
+
var AgentRouteSchema = z23.discriminatedUnion("action", [
|
|
8256
|
+
z23.object({ action: z23.literal("tool"), tool: z23.string().min(1) }),
|
|
8160
8257
|
z23.object({ action: z23.literal("final"), reply: z23.string() })
|
|
8161
8258
|
]);
|
|
8162
|
-
var
|
|
8259
|
+
var agentRouteJsonSchema = {
|
|
8163
8260
|
type: "object",
|
|
8164
8261
|
properties: {
|
|
8165
8262
|
action: { type: "string", enum: ["tool", "final"] },
|
|
8166
|
-
input: { type: "object" },
|
|
8167
8263
|
reply: { type: "string" },
|
|
8168
8264
|
tool: { type: "string" }
|
|
8169
8265
|
},
|
|
8170
8266
|
required: ["action"]
|
|
8171
8267
|
};
|
|
8268
|
+
var agentPersona = {
|
|
8269
|
+
behavior: "balanced",
|
|
8270
|
+
characterId: "agent",
|
|
8271
|
+
detailLevel: "concise",
|
|
8272
|
+
name: "Agent",
|
|
8273
|
+
tone: "direct",
|
|
8274
|
+
traits: []
|
|
8275
|
+
};
|
|
8276
|
+
var identityKnowledge = {
|
|
8277
|
+
content: "You are the Agent DevKit orchestration runtime. Choose tools only when they directly help complete the user's task.",
|
|
8278
|
+
id: "agent.runtime.identity"
|
|
8279
|
+
};
|
|
8280
|
+
function maxToolCallsFor(tools) {
|
|
8281
|
+
return Math.max(1, tools.length);
|
|
8282
|
+
}
|
|
8283
|
+
function moduleGuidance(knowledge) {
|
|
8284
|
+
const entries = [];
|
|
8285
|
+
for (const module of knowledge) {
|
|
8286
|
+
const parts = [];
|
|
8287
|
+
if (module.summary.length > 0) {
|
|
8288
|
+
parts.push(module.summary);
|
|
8289
|
+
}
|
|
8290
|
+
if (module.whenToUse.length > 0) {
|
|
8291
|
+
parts.push(`Use when: ${module.whenToUse.join(" ")}`);
|
|
8292
|
+
}
|
|
8293
|
+
if (module.whenNotToUse.length > 0) {
|
|
8294
|
+
parts.push(`Avoid when: ${module.whenNotToUse.join(" ")}`);
|
|
8295
|
+
}
|
|
8296
|
+
if (module.forbiddenActions.length > 0) {
|
|
8297
|
+
parts.push(`Never: ${module.forbiddenActions.join(" ")}`);
|
|
8298
|
+
}
|
|
8299
|
+
if (parts.length === 0) {
|
|
8300
|
+
continue;
|
|
8301
|
+
}
|
|
8302
|
+
entries.push({
|
|
8303
|
+
content: `${module.moduleId} \u2014 ${parts.join(" ")}`,
|
|
8304
|
+
id: `module.${module.moduleId}`
|
|
8305
|
+
});
|
|
8306
|
+
}
|
|
8307
|
+
return entries;
|
|
8308
|
+
}
|
|
8309
|
+
function buildToolDecisionPrompt(input) {
|
|
8310
|
+
const instruction = [
|
|
8311
|
+
`Tarefa do usu\xE1rio: ${input.task}`,
|
|
8312
|
+
"",
|
|
8313
|
+
"Escolha UMA ferramenta da lista dispon\xEDvel para avan\xE7ar na tarefa, ou responda ao usu\xE1rio se j\xE1 puder concluir.",
|
|
8314
|
+
'Responda SOMENTE com JSON. Para usar uma ferramenta: {"action":"tool","tool":"<id>"}. Para responder: {"action":"final","reply":"<texto>"}. Uma a\xE7\xE3o por vez. Os argumentos da ferramenta s\xE3o definidos no passo seguinte.'
|
|
8315
|
+
].join("\n");
|
|
8316
|
+
return AgentPromptSchema.parse({
|
|
8317
|
+
agent: input.agent ?? agentPersona,
|
|
8318
|
+
context: {
|
|
8319
|
+
knowledge: [identityKnowledge, ...moduleGuidance(input.knowledge ?? [])]
|
|
8320
|
+
},
|
|
8321
|
+
locale: "pt-BR",
|
|
8322
|
+
messages: input.transcript,
|
|
8323
|
+
output: { format: "json", language: "pt-BR" },
|
|
8324
|
+
policies: {
|
|
8325
|
+
allowToolCalls: true,
|
|
8326
|
+
approvalRequired: false,
|
|
8327
|
+
maxToolCalls: maxToolCallsFor(input.tools)
|
|
8328
|
+
},
|
|
8329
|
+
schema: "agent-devkit.prompt/v1",
|
|
8330
|
+
task: { userMessage: instruction },
|
|
8331
|
+
tools: input.tools.map((tool) => ({
|
|
8332
|
+
description: tool.description,
|
|
8333
|
+
id: tool.id,
|
|
8334
|
+
inputSchema: tool.inputSchema,
|
|
8335
|
+
risk: tool.risk
|
|
8336
|
+
}))
|
|
8337
|
+
});
|
|
8338
|
+
}
|
|
8339
|
+
function buildToolInputPrompt(input) {
|
|
8340
|
+
const schema = summarizeToolSchema(input.tool.inputSchema);
|
|
8341
|
+
const instruction = [
|
|
8342
|
+
`Tarefa do usu\xE1rio: ${input.task}`,
|
|
8343
|
+
"",
|
|
8344
|
+
`Gere APENAS o objeto JSON de entrada para a ferramenta ${input.tool.id}.`,
|
|
8345
|
+
schema.length > 0 ? `Formato esperado: ${schema}` : "",
|
|
8346
|
+
"Responda somente com o JSON do input, sem texto extra."
|
|
8347
|
+
].filter((line) => line.length > 0).join("\n");
|
|
8348
|
+
return AgentPromptSchema.parse({
|
|
8349
|
+
agent: input.agent ?? agentPersona,
|
|
8350
|
+
context: { knowledge: [identityKnowledge] },
|
|
8351
|
+
locale: "pt-BR",
|
|
8352
|
+
messages: input.transcript,
|
|
8353
|
+
output: { format: "json", language: "pt-BR" },
|
|
8354
|
+
policies: { allowToolCalls: true, approvalRequired: false, maxToolCalls: 1 },
|
|
8355
|
+
schema: "agent-devkit.prompt/v1",
|
|
8356
|
+
task: { userMessage: instruction },
|
|
8357
|
+
tools: [
|
|
8358
|
+
{
|
|
8359
|
+
description: input.tool.description,
|
|
8360
|
+
id: input.tool.id,
|
|
8361
|
+
inputSchema: input.tool.inputSchema,
|
|
8362
|
+
risk: input.tool.risk
|
|
8363
|
+
}
|
|
8364
|
+
]
|
|
8365
|
+
});
|
|
8366
|
+
}
|
|
8367
|
+
|
|
8368
|
+
// src/agent/agent.policy.ts
|
|
8369
|
+
function isToolApproved(tool, input) {
|
|
8370
|
+
if (input.approvedTools !== void 0) {
|
|
8371
|
+
return input.approvedTools.includes(tool);
|
|
8372
|
+
}
|
|
8373
|
+
return input.approved === true;
|
|
8374
|
+
}
|
|
8375
|
+
|
|
8376
|
+
// src/agent/agent.loop.ts
|
|
8172
8377
|
function summarize(value) {
|
|
8173
8378
|
const text2 = typeof value === "string" ? value : JSON.stringify(value ?? "");
|
|
8174
8379
|
const compact2 = text2.replaceAll(/\s+/g, " ").trim();
|
|
8175
|
-
return compact2.length > 240 ? `${compact2.slice(0, 240)}
|
|
8380
|
+
return compact2.length > 240 ? `${compact2.slice(0, 240)}...` : compact2;
|
|
8176
8381
|
}
|
|
8177
8382
|
function observationSummary(result) {
|
|
8178
8383
|
if (result.status === "succeeded") {
|
|
@@ -8180,11 +8385,15 @@ function observationSummary(result) {
|
|
|
8180
8385
|
}
|
|
8181
8386
|
return `${result.status}${result.error === void 0 ? "" : `: ${result.error.message}`}`;
|
|
8182
8387
|
}
|
|
8183
|
-
var
|
|
8388
|
+
var AgentToolLoop = class {
|
|
8389
|
+
#agent;
|
|
8184
8390
|
#brain;
|
|
8391
|
+
#knowledge;
|
|
8185
8392
|
#tools;
|
|
8186
8393
|
constructor(options) {
|
|
8394
|
+
this.#agent = options.agent;
|
|
8187
8395
|
this.#brain = options.brainProvider;
|
|
8396
|
+
this.#knowledge = options.knowledge;
|
|
8188
8397
|
this.#tools = options.toolRuntime;
|
|
8189
8398
|
}
|
|
8190
8399
|
async run(input) {
|
|
@@ -8199,32 +8408,51 @@ var AgentRuntime = class {
|
|
|
8199
8408
|
role: message.role
|
|
8200
8409
|
}));
|
|
8201
8410
|
const tools = this.#tools.listTools();
|
|
8411
|
+
const knowledge = await this.#knowledgeForTools(tools.map((tool) => tool.moduleId));
|
|
8202
8412
|
for (let step = 0; step < maxSteps; step += 1) {
|
|
8203
|
-
const
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8413
|
+
const routePrompt = buildToolDecisionPrompt({
|
|
8414
|
+
agent: input.agent ?? this.#agent,
|
|
8415
|
+
knowledge,
|
|
8416
|
+
task: input.task,
|
|
8417
|
+
tools,
|
|
8418
|
+
transcript
|
|
8419
|
+
});
|
|
8420
|
+
const routed = await generateStructured(
|
|
8421
|
+
{
|
|
8422
|
+
options: { provider: "local", role: "agent" },
|
|
8423
|
+
prompt: routePrompt,
|
|
8424
|
+
schema: "agent-devkit.brain-request/v1"
|
|
8425
|
+
},
|
|
8426
|
+
agentRouteJsonSchema
|
|
8427
|
+
);
|
|
8428
|
+
if (routed.isErr()) {
|
|
8429
|
+
return Result.fail(routed.unwrapError());
|
|
8212
8430
|
}
|
|
8213
|
-
const
|
|
8214
|
-
if (!
|
|
8215
|
-
return Result.
|
|
8431
|
+
const route = AgentRouteSchema.safeParse(routed.unwrap().json);
|
|
8432
|
+
if (!route.success) {
|
|
8433
|
+
return Result.fail(ErrorCodes.InvalidInput);
|
|
8216
8434
|
}
|
|
8217
|
-
if (
|
|
8218
|
-
input.onEvent?.({ reply:
|
|
8219
|
-
return Result.ok({ reply:
|
|
8435
|
+
if (route.data.action === "final") {
|
|
8436
|
+
input.onEvent?.({ reply: route.data.reply, type: "final" });
|
|
8437
|
+
return Result.ok({ mode: "task", reply: route.data.reply, steps });
|
|
8220
8438
|
}
|
|
8221
|
-
const tool =
|
|
8439
|
+
const tool = route.data.tool;
|
|
8222
8440
|
input.onEvent?.({ tool, type: "tool" });
|
|
8441
|
+
const toolInput = await this.#resolveToolInput(
|
|
8442
|
+
generateStructured,
|
|
8443
|
+
tool,
|
|
8444
|
+
input.task,
|
|
8445
|
+
transcript,
|
|
8446
|
+
input.agent ?? this.#agent
|
|
8447
|
+
);
|
|
8448
|
+
if (toolInput.isErr()) {
|
|
8449
|
+
return Result.fail(toolInput.unwrapError());
|
|
8450
|
+
}
|
|
8223
8451
|
const execution = await this.#tools.execute({
|
|
8224
|
-
approved:
|
|
8452
|
+
approved: isToolApproved(tool, input),
|
|
8225
8453
|
capabilityId: tool,
|
|
8226
|
-
input:
|
|
8227
|
-
interface: "agent",
|
|
8454
|
+
input: toolInput.unwrap(),
|
|
8455
|
+
interface: input.interface ?? "agent",
|
|
8228
8456
|
requestedBy: "agent.run"
|
|
8229
8457
|
});
|
|
8230
8458
|
const ok = execution.status === "succeeded";
|
|
@@ -8234,64 +8462,114 @@ var AgentRuntime = class {
|
|
|
8234
8462
|
transcript.push({ content: `Observation from ${tool}: ${summary}`, role: "tool" });
|
|
8235
8463
|
if (execution.status === "approval_required") {
|
|
8236
8464
|
return Result.ok({
|
|
8465
|
+
mode: "task",
|
|
8237
8466
|
reply: `A ferramenta ${tool} requer aprova\xE7\xE3o expl\xEDcita. Reexecute autorizando para continuar.`,
|
|
8238
8467
|
steps
|
|
8239
8468
|
});
|
|
8240
8469
|
}
|
|
8241
8470
|
}
|
|
8242
8471
|
return Result.ok({
|
|
8472
|
+
mode: "task",
|
|
8243
8473
|
reply: "Limite de passos do agente atingido sem uma resposta final.",
|
|
8244
8474
|
steps
|
|
8245
8475
|
});
|
|
8246
8476
|
}
|
|
8247
|
-
#
|
|
8248
|
-
if (
|
|
8249
|
-
return
|
|
8477
|
+
async #knowledgeForTools(moduleIds) {
|
|
8478
|
+
if (this.#knowledge === void 0) {
|
|
8479
|
+
return [];
|
|
8250
8480
|
}
|
|
8251
|
-
|
|
8481
|
+
const present = new Set(moduleIds);
|
|
8482
|
+
const all = await this.#knowledge.all();
|
|
8483
|
+
return all.filter((module) => present.has(module.moduleId));
|
|
8252
8484
|
}
|
|
8253
|
-
#
|
|
8254
|
-
const
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
name: "Agent",
|
|
8269
|
-
tone: "direct",
|
|
8270
|
-
traits: []
|
|
8271
|
-
},
|
|
8272
|
-
context: { knowledge: [] },
|
|
8273
|
-
locale: "pt-BR",
|
|
8274
|
-
messages: transcript,
|
|
8275
|
-
output: { format: "json", language: "pt-BR" },
|
|
8276
|
-
policies: {
|
|
8277
|
-
allowToolCalls: true,
|
|
8278
|
-
approvalRequired: false,
|
|
8279
|
-
maxToolCalls: maxToolCallsFor(tools)
|
|
8280
|
-
},
|
|
8281
|
-
schema: "agent-devkit.prompt/v1",
|
|
8282
|
-
task: { userMessage: instruction },
|
|
8283
|
-
tools: tools.map((tool) => ({
|
|
8284
|
-
description: tool.description,
|
|
8285
|
-
id: tool.id,
|
|
8286
|
-
inputSchema: tool.inputSchema,
|
|
8287
|
-
risk: tool.risk
|
|
8288
|
-
}))
|
|
8289
|
-
});
|
|
8485
|
+
async #resolveToolInput(generateStructured, tool, task, transcript, agent) {
|
|
8486
|
+
const descriptor = this.#tools.getTool(tool);
|
|
8487
|
+
if (descriptor.isErr()) {
|
|
8488
|
+
return Result.fail(descriptor.unwrapError());
|
|
8489
|
+
}
|
|
8490
|
+
const request = {
|
|
8491
|
+
options: { provider: "local", role: "agent" },
|
|
8492
|
+
prompt: buildToolInputPrompt({ agent, task, tool: descriptor.unwrap(), transcript }),
|
|
8493
|
+
schema: "agent-devkit.brain-request/v1"
|
|
8494
|
+
};
|
|
8495
|
+
const produced = await generateStructured(request, descriptor.unwrap().inputSchema);
|
|
8496
|
+
if (produced.isErr()) {
|
|
8497
|
+
return Result.fail(produced.unwrapError());
|
|
8498
|
+
}
|
|
8499
|
+
return Result.ok(produced.unwrap().json ?? {});
|
|
8290
8500
|
}
|
|
8291
8501
|
};
|
|
8292
|
-
|
|
8293
|
-
|
|
8502
|
+
|
|
8503
|
+
// src/agent/agent.runtime.ts
|
|
8504
|
+
function textInput(input) {
|
|
8505
|
+
return (input.message ?? input.task ?? "").trim();
|
|
8506
|
+
}
|
|
8507
|
+
function resolveMode(input) {
|
|
8508
|
+
if (input.mode === "chat" || input.mode === "task") {
|
|
8509
|
+
return input.mode;
|
|
8510
|
+
}
|
|
8511
|
+
if (input.message !== void 0) {
|
|
8512
|
+
return "chat";
|
|
8513
|
+
}
|
|
8514
|
+
return "task";
|
|
8515
|
+
}
|
|
8516
|
+
function chatInput(input, message) {
|
|
8517
|
+
return {
|
|
8518
|
+
characterId: input.characterId,
|
|
8519
|
+
includeHistory: input.includeHistory,
|
|
8520
|
+
interface: input.interface ?? "cli",
|
|
8521
|
+
message,
|
|
8522
|
+
projectId: input.projectId,
|
|
8523
|
+
sessionId: input.sessionId
|
|
8524
|
+
};
|
|
8294
8525
|
}
|
|
8526
|
+
var AgentRuntime = class {
|
|
8527
|
+
#agent;
|
|
8528
|
+
#conversation;
|
|
8529
|
+
#toolLoop;
|
|
8530
|
+
constructor(options) {
|
|
8531
|
+
this.#agent = options.agent;
|
|
8532
|
+
this.#conversation = options.conversation;
|
|
8533
|
+
this.#toolLoop = new AgentToolLoop({
|
|
8534
|
+
agent: options.agent,
|
|
8535
|
+
brainProvider: options.brainProvider,
|
|
8536
|
+
knowledge: options.knowledge,
|
|
8537
|
+
toolRuntime: options.toolRuntime
|
|
8538
|
+
});
|
|
8539
|
+
}
|
|
8540
|
+
async run(input) {
|
|
8541
|
+
const message = textInput(input);
|
|
8542
|
+
if (message.length === 0) {
|
|
8543
|
+
return Result.fail(ErrorCodes.InvalidInput);
|
|
8544
|
+
}
|
|
8545
|
+
const mode = resolveMode(input);
|
|
8546
|
+
if (mode === "chat") {
|
|
8547
|
+
return this.#runChat(input, message);
|
|
8548
|
+
}
|
|
8549
|
+
return this.#toolLoop.run({ ...input, agent: input.agent ?? this.#agent, task: message });
|
|
8550
|
+
}
|
|
8551
|
+
async #runChat(input, message) {
|
|
8552
|
+
if (this.#conversation === void 0) {
|
|
8553
|
+
return Result.fail(ErrorCodes.BrainProviderUnavailable);
|
|
8554
|
+
}
|
|
8555
|
+
const result = await this.#conversation.chat(chatInput(input, message), {
|
|
8556
|
+
approved: input.approved,
|
|
8557
|
+
interface: input.interface ?? "cli",
|
|
8558
|
+
requestedBy: "agent.chat"
|
|
8559
|
+
});
|
|
8560
|
+
if (result.isErr()) {
|
|
8561
|
+
return Result.fail(result.unwrapError());
|
|
8562
|
+
}
|
|
8563
|
+
const conversation = result.unwrap();
|
|
8564
|
+
input.onEvent?.({ reply: conversation.reply, type: "final" });
|
|
8565
|
+
return Result.ok({
|
|
8566
|
+
conversation,
|
|
8567
|
+
mode: "chat",
|
|
8568
|
+
reply: conversation.reply,
|
|
8569
|
+
steps: []
|
|
8570
|
+
});
|
|
8571
|
+
}
|
|
8572
|
+
};
|
|
8295
8573
|
|
|
8296
8574
|
// src/app/mcp/mcp_result_mapper.ts
|
|
8297
8575
|
function inputSchemaWithAgentControl(tool) {
|
|
@@ -8396,6 +8674,11 @@ var agentTaskTool = {
|
|
|
8396
8674
|
annotations: { openWorldHint: true },
|
|
8397
8675
|
_meta: { "agent-devkit/kind": "agent-delegation" }
|
|
8398
8676
|
};
|
|
8677
|
+
var baseInstructions = "Agent DevKit exposes local capabilities as MCP tools, plus an `agent.task` delegation tool. Prefer `agent.task` for bounded, multi-step or routine local tasks to offload orchestration and reduce token usage; use the individual capability tools directly when you need step-by-step control or precise intermediate results. Risky tools require explicit approval through _agent.approved. For agent.task, approval must be scoped with approvedTools.";
|
|
8678
|
+
var surfaceResourceInstructions = " Per-module guidance (purpose, when to use, guardrails) is available as MCP resources under agent-devkit://surface/<moduleId>; read them to route between agent.task and direct capability tools.";
|
|
8679
|
+
function surfaceResourceUri(moduleId) {
|
|
8680
|
+
return `agent-devkit://surface/${moduleId}`;
|
|
8681
|
+
}
|
|
8399
8682
|
function mcpToolFromRuntimeTool(tool) {
|
|
8400
8683
|
const mcpTool = {
|
|
8401
8684
|
name: tool.id,
|
|
@@ -8418,21 +8701,37 @@ function mcpToolFromRuntimeTool(tool) {
|
|
|
8418
8701
|
}
|
|
8419
8702
|
return mcpTool;
|
|
8420
8703
|
}
|
|
8704
|
+
async function currentAgentPersona(personalization) {
|
|
8705
|
+
const profile = await personalization.loadProfile();
|
|
8706
|
+
if (profile.isErr()) {
|
|
8707
|
+
return void 0;
|
|
8708
|
+
}
|
|
8709
|
+
const character = profile.unwrap().currentCharacter;
|
|
8710
|
+
return {
|
|
8711
|
+
behavior: character.profile.behavior,
|
|
8712
|
+
characterId: character.id,
|
|
8713
|
+
detailLevel: character.profile.detailLevel,
|
|
8714
|
+
name: character.name ?? character.id,
|
|
8715
|
+
tone: character.profile.tone,
|
|
8716
|
+
traits: character.profile.traits
|
|
8717
|
+
};
|
|
8718
|
+
}
|
|
8421
8719
|
function createAgentMcpServer(options) {
|
|
8720
|
+
const knowledge = options.knowledge;
|
|
8721
|
+
const personalization = new PersonalizationRepository();
|
|
8422
8722
|
const server = new Server(
|
|
8423
8723
|
{
|
|
8424
8724
|
name: options.packageName,
|
|
8425
8725
|
version: options.version
|
|
8426
8726
|
},
|
|
8427
8727
|
{
|
|
8428
|
-
capabilities: {
|
|
8429
|
-
|
|
8430
|
-
},
|
|
8431
|
-
instructions: "Agent DevKit exposes local capabilities as MCP tools, plus an `agent.task` delegation tool. Prefer `agent.task` for bounded, multi-step or routine local tasks to offload orchestration and reduce token usage; use the individual capability tools directly when you need step-by-step control or precise intermediate results. Risky tools require explicit approval through _agent.approved. For agent.task, approval must be scoped with approvedTools."
|
|
8728
|
+
capabilities: knowledge === void 0 ? { tools: {} } : { resources: {}, tools: {} },
|
|
8729
|
+
instructions: knowledge === void 0 ? baseInstructions : `${baseInstructions}${surfaceResourceInstructions}`
|
|
8432
8730
|
}
|
|
8433
8731
|
);
|
|
8434
8732
|
const agent = new AgentRuntime({
|
|
8435
8733
|
brainProvider: createBrainDockProvider({ stateDirectory: join16(homedir13(), ".agent-devkit") }),
|
|
8734
|
+
knowledge,
|
|
8436
8735
|
toolRuntime: options.runtime
|
|
8437
8736
|
});
|
|
8438
8737
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
@@ -8446,7 +8745,13 @@ function createAgentMcpServer(options) {
|
|
|
8446
8745
|
if (task.length === 0) {
|
|
8447
8746
|
return { content: [{ type: "text", text: "Missing 'task'." }], isError: true };
|
|
8448
8747
|
}
|
|
8449
|
-
const run = await agent.run({
|
|
8748
|
+
const run = await agent.run({
|
|
8749
|
+
agent: await currentAgentPersona(personalization),
|
|
8750
|
+
approvedTools,
|
|
8751
|
+
interface: "mcp",
|
|
8752
|
+
mode: "task",
|
|
8753
|
+
task
|
|
8754
|
+
});
|
|
8450
8755
|
if (run.isErr()) {
|
|
8451
8756
|
return {
|
|
8452
8757
|
content: [{ type: "text", text: `Agent run failed: ${run.unwrapError()}` }],
|
|
@@ -8480,6 +8785,37 @@ ${stepsText}` : payload.reply
|
|
|
8480
8785
|
const tool = options.runtime.getTool(request.params.name);
|
|
8481
8786
|
return runtimeResultToMcpContent(result, tool.isOk() && hasObjectOutputSchema(tool.unwrap()));
|
|
8482
8787
|
});
|
|
8788
|
+
if (knowledge !== void 0) {
|
|
8789
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
8790
|
+
const modules = await knowledge.all();
|
|
8791
|
+
return {
|
|
8792
|
+
resources: modules.map((module) => ({
|
|
8793
|
+
description: module.summary,
|
|
8794
|
+
mimeType: "application/json",
|
|
8795
|
+
name: `${module.moduleId} surface`,
|
|
8796
|
+
uri: surfaceResourceUri(module.moduleId)
|
|
8797
|
+
}))
|
|
8798
|
+
};
|
|
8799
|
+
});
|
|
8800
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
8801
|
+
const modules = await knowledge.all();
|
|
8802
|
+
const module = modules.find(
|
|
8803
|
+
(entry) => surfaceResourceUri(entry.moduleId) === request.params.uri
|
|
8804
|
+
);
|
|
8805
|
+
if (module === void 0) {
|
|
8806
|
+
throw new Error(`Unknown resource: ${request.params.uri}`);
|
|
8807
|
+
}
|
|
8808
|
+
return {
|
|
8809
|
+
contents: [
|
|
8810
|
+
{
|
|
8811
|
+
mimeType: "application/json",
|
|
8812
|
+
text: JSON.stringify(module, null, 2),
|
|
8813
|
+
uri: request.params.uri
|
|
8814
|
+
}
|
|
8815
|
+
]
|
|
8816
|
+
};
|
|
8817
|
+
});
|
|
8818
|
+
}
|
|
8483
8819
|
return server;
|
|
8484
8820
|
}
|
|
8485
8821
|
|
|
@@ -8577,6 +8913,7 @@ function runtime2(options) {
|
|
|
8577
8913
|
}
|
|
8578
8914
|
async function runStdio(options) {
|
|
8579
8915
|
await startMcpStdioServer({
|
|
8916
|
+
knowledge: createModuleSurfaceKnowledge(),
|
|
8580
8917
|
packageName: options.packageName,
|
|
8581
8918
|
runtime: runtime2(options),
|
|
8582
8919
|
version: options.currentVersion
|
|
@@ -8631,6 +8968,7 @@ function registerMcpCommand(program2, options) {
|
|
|
8631
8968
|
const server = await startMcpHttpServer({
|
|
8632
8969
|
allowedOrigins: commandOptions.origin,
|
|
8633
8970
|
host: commandOptions.host,
|
|
8971
|
+
knowledge: createModuleSurfaceKnowledge(),
|
|
8634
8972
|
packageName: options.packageName,
|
|
8635
8973
|
port: parsePositiveInteger(commandOptions.port),
|
|
8636
8974
|
runtime: runtime2(options),
|
|
@@ -9710,6 +10048,16 @@ function registerSecretsCommand(program2, options) {
|
|
|
9710
10048
|
}
|
|
9711
10049
|
|
|
9712
10050
|
// src/app/cli/commands/sessionsCommand.ts
|
|
10051
|
+
function stringOption(options, ...names) {
|
|
10052
|
+
const nested = typeof options.opts === "function" ? options.opts() : {};
|
|
10053
|
+
for (const name of names) {
|
|
10054
|
+
const value = options[name] ?? nested[name];
|
|
10055
|
+
if (typeof value === "string" && value.length > 0) {
|
|
10056
|
+
return value;
|
|
10057
|
+
}
|
|
10058
|
+
}
|
|
10059
|
+
return void 0;
|
|
10060
|
+
}
|
|
9713
10061
|
function parseTags2(value) {
|
|
9714
10062
|
const tags = value?.split(",").map((tag) => tag.trim()).filter((tag) => tag.length > 0);
|
|
9715
10063
|
return tags === void 0 || tags.length === 0 ? void 0 : tags;
|
|
@@ -9742,14 +10090,14 @@ function registerSessionsCommand(program2, options) {
|
|
|
9742
10090
|
await printSessionsResult(commandOptions, {
|
|
9743
10091
|
action: "list",
|
|
9744
10092
|
limit: parseNonNegativeInteger(commandOptions.limit),
|
|
9745
|
-
projectId: commandOptions
|
|
10093
|
+
projectId: stringOption(commandOptions, "project", "projectId"),
|
|
9746
10094
|
query: commandOptions.query,
|
|
9747
10095
|
status: commandOptions.status
|
|
9748
10096
|
});
|
|
9749
10097
|
}
|
|
9750
10098
|
)
|
|
9751
10099
|
);
|
|
9752
|
-
const createCommand = sessionsCommand.command("create").description("create a context session").option("--json", "print session result as JSON").option("--origin <origin>", "cli, tui, mcp or agent", "cli").option("--
|
|
10100
|
+
const createCommand = sessionsCommand.command("create").description("create a context session").option("--json", "print session result as JSON").option("--origin <origin>", "cli, tui, mcp or agent", "cli").option("--tags <tags>", "comma-separated tags").option("--title <title>", "session title");
|
|
9753
10101
|
createCommand.action(
|
|
9754
10102
|
options.usageLogging.track(
|
|
9755
10103
|
{ area: "user", command: "sessions.create", options: () => createCommand.opts() },
|
|
@@ -9757,7 +10105,7 @@ function registerSessionsCommand(program2, options) {
|
|
|
9757
10105
|
await printSessionsResult(commandOptions, {
|
|
9758
10106
|
action: "create",
|
|
9759
10107
|
origin: commandOptions.origin ?? "cli",
|
|
9760
|
-
projectId: commandOptions.project,
|
|
10108
|
+
projectId: stringOption(commandOptions, "project", "projectId") ?? stringOption(sessionsCommand.opts(), "project", "projectId"),
|
|
9761
10109
|
tags: parseTags2(commandOptions.tags),
|
|
9762
10110
|
title: commandOptions.title
|
|
9763
10111
|
});
|
|
@@ -9793,7 +10141,7 @@ function registerSessionsCommand(program2, options) {
|
|
|
9793
10141
|
}
|
|
9794
10142
|
)
|
|
9795
10143
|
);
|
|
9796
|
-
const searchCommand = sessionsCommand.command("search").argument("<query>", "query").description("search context sessions").option("--json", "print session result as JSON").option("--limit <limit>", "maximum number of results")
|
|
10144
|
+
const searchCommand = sessionsCommand.command("search").argument("<query>", "query").description("search context sessions").option("--json", "print session result as JSON").option("--limit <limit>", "maximum number of results");
|
|
9797
10145
|
searchCommand.action(
|
|
9798
10146
|
options.usageLogging.track(
|
|
9799
10147
|
{ area: "user", command: "sessions.search", options: () => searchCommand.opts() },
|
|
@@ -9801,7 +10149,7 @@ function registerSessionsCommand(program2, options) {
|
|
|
9801
10149
|
await printSessionsResult(commandOptions, {
|
|
9802
10150
|
action: "search",
|
|
9803
10151
|
limit: parseNonNegativeInteger(commandOptions.limit),
|
|
9804
|
-
projectId: commandOptions.project,
|
|
10152
|
+
projectId: stringOption(commandOptions, "project", "projectId") ?? stringOption(sessionsCommand.opts(), "project", "projectId"),
|
|
9805
10153
|
query
|
|
9806
10154
|
});
|
|
9807
10155
|
}
|
|
@@ -10073,10 +10421,7 @@ import { homedir as homedir22 } from "os";
|
|
|
10073
10421
|
|
|
10074
10422
|
// src/modules/conversation/capabilities/chat/chat.viewmodel.ts
|
|
10075
10423
|
function formatConversationChatText(result) {
|
|
10076
|
-
const agentName = result.prompt.agent.name.trim();
|
|
10077
10424
|
const reply2 = result.reply.trim();
|
|
10078
|
-
const speakerPrefix = `${agentName}:`;
|
|
10079
|
-
const normalizedReply = reply2.toLowerCase().startsWith(speakerPrefix.toLowerCase()) ? reply2 : `${speakerPrefix} ${reply2}`;
|
|
10080
10425
|
const metadata = [`Session: ${result.sessionId}`];
|
|
10081
10426
|
if (result.projectId !== void 0) {
|
|
10082
10427
|
metadata.push(`Project: ${result.projectId}`);
|
|
@@ -10096,20 +10441,28 @@ function formatConversationChatText(result) {
|
|
|
10096
10441
|
metadata.push(`Tokens: ${tokens.join(", ")}`);
|
|
10097
10442
|
}
|
|
10098
10443
|
}
|
|
10099
|
-
return [
|
|
10444
|
+
return [reply2, "", ...metadata].join("\n");
|
|
10100
10445
|
}
|
|
10101
10446
|
|
|
10102
10447
|
// src/app/cli/rootConversation.ts
|
|
10103
|
-
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10448
|
+
function sanitizeCliScope(scope) {
|
|
10449
|
+
return scope.replaceAll(/[^a-zA-Z0-9_-]+/g, "-").replaceAll(/^-+|-+$/g, "") || "default";
|
|
10450
|
+
}
|
|
10451
|
+
function currentCliSessionScope() {
|
|
10452
|
+
return process.env.AGENT_DEVKIT_CLI_SESSION_SCOPE ?? String(process.ppid);
|
|
10453
|
+
}
|
|
10454
|
+
function cliConversationStatePathForScope(scope) {
|
|
10455
|
+
return {
|
|
10456
|
+
namespace: "conversation",
|
|
10457
|
+
segments: [`cli-state-${sanitizeCliScope(scope)}.json`]
|
|
10458
|
+
};
|
|
10459
|
+
}
|
|
10107
10460
|
function isCliConversationState(value) {
|
|
10108
10461
|
const record = value;
|
|
10109
10462
|
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";
|
|
10110
10463
|
}
|
|
10111
|
-
async function loadActiveCliSessionId(dataStore, sessions) {
|
|
10112
|
-
const state = await dataStore.readJson(
|
|
10464
|
+
async function loadActiveCliSessionId(dataStore, sessions, statePath) {
|
|
10465
|
+
const state = await dataStore.readJson(statePath);
|
|
10113
10466
|
if (state.isErr()) {
|
|
10114
10467
|
return void 0;
|
|
10115
10468
|
}
|
|
@@ -10131,9 +10484,9 @@ async function loadActiveCliSessionId(dataStore, sessions) {
|
|
|
10131
10484
|
}
|
|
10132
10485
|
return result.session.id;
|
|
10133
10486
|
}
|
|
10134
|
-
async function saveActiveCliSessionId(dataStore, sessionId) {
|
|
10487
|
+
async function saveActiveCliSessionId(dataStore, sessionId, statePath) {
|
|
10135
10488
|
await dataStore.writeJson(
|
|
10136
|
-
|
|
10489
|
+
statePath,
|
|
10137
10490
|
{
|
|
10138
10491
|
activeSessionId: sessionId,
|
|
10139
10492
|
schema: "agent-devkit.cli-conversation-state/v1",
|
|
@@ -10142,7 +10495,31 @@ async function saveActiveCliSessionId(dataStore, sessionId) {
|
|
|
10142
10495
|
{ atomic: true }
|
|
10143
10496
|
);
|
|
10144
10497
|
}
|
|
10145
|
-
|
|
10498
|
+
function createConversationPort(chat) {
|
|
10499
|
+
return {
|
|
10500
|
+
chat: async (input, context) => {
|
|
10501
|
+
const result = await chat.invoke(
|
|
10502
|
+
{
|
|
10503
|
+
action: "send",
|
|
10504
|
+
characterId: input.characterId,
|
|
10505
|
+
includeHistory: input.includeHistory,
|
|
10506
|
+
message: input.message,
|
|
10507
|
+
projectId: input.projectId,
|
|
10508
|
+
sessionId: input.sessionId
|
|
10509
|
+
},
|
|
10510
|
+
context
|
|
10511
|
+
);
|
|
10512
|
+
return result.map((payload) => ({
|
|
10513
|
+
brain: payload.brain,
|
|
10514
|
+
projectId: payload.projectId,
|
|
10515
|
+
raw: payload,
|
|
10516
|
+
reply: payload.reply,
|
|
10517
|
+
sessionId: payload.sessionId
|
|
10518
|
+
}));
|
|
10519
|
+
}
|
|
10520
|
+
};
|
|
10521
|
+
}
|
|
10522
|
+
async function runRootConversation(message, options) {
|
|
10146
10523
|
const homeDirectory = homedir22();
|
|
10147
10524
|
const dataStore = new LocalAgentDataStore({
|
|
10148
10525
|
rootDirectory: `${homeDirectory}/.agent-devkit/data`
|
|
@@ -10159,21 +10536,40 @@ async function runRootConversation(message) {
|
|
|
10159
10536
|
if (contextBindings.isErr()) {
|
|
10160
10537
|
throw new Error(contextBindings.unwrapError());
|
|
10161
10538
|
}
|
|
10539
|
+
const cliStatePath = cliConversationStatePathForScope(currentCliSessionScope());
|
|
10162
10540
|
const activeSessionId = await loadActiveCliSessionId(
|
|
10163
10541
|
dataStore,
|
|
10164
|
-
contextBindings.unwrap().capabilities.sessions
|
|
10542
|
+
contextBindings.unwrap().capabilities.sessions,
|
|
10543
|
+
cliStatePath
|
|
10165
10544
|
);
|
|
10166
|
-
const
|
|
10167
|
-
|
|
10545
|
+
const agent = new AgentRuntime({
|
|
10546
|
+
brainProvider: createBrainDockProvider({ stateDirectory: `${homeDirectory}/.agent-devkit` }),
|
|
10547
|
+
conversation: createConversationPort(bindings.unwrap().capabilities.chat),
|
|
10548
|
+
toolRuntime: createCliToolRuntime({
|
|
10549
|
+
currentVersion: options.currentVersion,
|
|
10550
|
+
packageName: options.packageName
|
|
10551
|
+
})
|
|
10552
|
+
});
|
|
10553
|
+
const result = await agent.run({
|
|
10554
|
+
interface: "cli",
|
|
10168
10555
|
message,
|
|
10556
|
+
mode: "chat",
|
|
10169
10557
|
sessionId: activeSessionId
|
|
10170
10558
|
});
|
|
10171
10559
|
if (result.isErr()) {
|
|
10172
10560
|
throw new Error(result.unwrapError());
|
|
10173
10561
|
}
|
|
10174
10562
|
const payload = result.unwrap();
|
|
10175
|
-
|
|
10176
|
-
|
|
10563
|
+
const rawConversation = payload.conversation?.raw;
|
|
10564
|
+
if (payload.conversation === void 0 || !isConversationChatResult(rawConversation)) {
|
|
10565
|
+
throw new Error("Agent did not return a conversation result.");
|
|
10566
|
+
}
|
|
10567
|
+
await saveActiveCliSessionId(dataStore, payload.conversation.sessionId, cliStatePath);
|
|
10568
|
+
console.log(formatConversationChatText(rawConversation));
|
|
10569
|
+
}
|
|
10570
|
+
function isConversationChatResult(value) {
|
|
10571
|
+
const candidate = value;
|
|
10572
|
+
return typeof value === "object" && value !== null && candidate.action === "send" && typeof candidate.reply === "string" && typeof candidate.sessionId === "string";
|
|
10177
10573
|
}
|
|
10178
10574
|
|
|
10179
10575
|
// src/infra/helpers/redaction.ts
|
|
@@ -10514,7 +10910,10 @@ program.name("agent").description(translator.t("cli.root.description")).version(
|
|
|
10514
10910
|
program.error(translator.t("cli.root.removedChatCommand"));
|
|
10515
10911
|
}
|
|
10516
10912
|
if (initialPrompt.length > 0) {
|
|
10517
|
-
await runRootConversation(initialPrompt
|
|
10913
|
+
await runRootConversation(initialPrompt, {
|
|
10914
|
+
currentVersion: package_default.version,
|
|
10915
|
+
packageName: package_default.name
|
|
10916
|
+
});
|
|
10518
10917
|
return;
|
|
10519
10918
|
}
|
|
10520
10919
|
await ensureFirstRunModel(translator);
|