Skip to content

Commit 9f102f9

Browse files
authored
Merge pull request #71 from OpenAF/codex/improve-function-names-and-descriptions
Rename MCP utility tool methods for clarity
2 parents 44409c3 + a2f5239 commit 9f102f9

File tree

6 files changed

+290
-95
lines changed

6 files changed

+290
-95
lines changed

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Automated tests exist for utility modules under `tests/`. Run the mini-a-utils t
1919
For core agent behavior, validate by scripting representative goals (see `USAGE.md`) and capture the agent transcript with `debug=true`. When adding MCP integrations, run the corresponding `mcp-*.yaml` job standalone before wiring it into Mini-A. Document manual verification steps in the PR description, and note any scenarios not exercised.
2020

2121
Current test coverage includes:
22-
- **File Operations**: init, readFile, writeFile, listDirectory, searchContent, getFileInfo, deleteFile, fileOps, fileModify, path security
22+
- **File Operations**: init, readFile, writeFile, listDirectory, searchContent, getFileInfo, deleteFile, filesystemQuery, filesystemModify, path security
2323
- **Mathematical Operations**: calculate (add, subtract, multiply, divide, power, sqrt, abs, round), statistics (mean, median, min, max, sum, count), unit conversions, random generation (integer, sequence, choice, boolean, hex)
2424
- **Time Operations**: current time with timezone/format options, timezone conversions, sleep functionality
2525
- **Advanced Parameters**: UTF-8 encoding, createMissingDirs, contentLength reporting, append flags

USAGE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ If every stage returns an empty list (or errors), Mini-A logs the issue and fall
390390
#### Libraries and Extensions
391391
- **`libs`** (string): Comma-separated list of additional OpenAF libraries to load
392392
- **`useutils`** (boolean, default: false): Auto-register the Mini File Tool utilities as a dummy MCP server for quick file operations
393-
- Exposes three streamlined actions: `init` (configure the working root and permissions), `fileQuery` (read/list/search/info via the `operation` field), and `fileModify` (write/append/delete with `operation` plus required `content` or `confirm` flags)
393+
- Exposes three streamlined actions: `init` (configure the working root and permissions), `filesystemQuery` (read/list/search/info via the `operation` field), and `filesystemModify` (write/append/delete with `operation` plus required `content` or `confirm` flags)
394394

395395
#### Conversation Management
396396
- **`conversation`** (string): Path to file for loading/saving conversation history
@@ -400,7 +400,7 @@ If every stage returns an empty list (or errors), Mini-A logs the issue and fall
400400
- **`mode`** (string): Shortcut for loading a preset argument bundle from [`mini-a-modes.yaml`](mini-a-modes.yaml) or `~/.openaf-mini-a_modes.yaml` (custom modes override built-in ones). Presets are merged before explicit flags, so command-line overrides always win. Bundled configurations include:
401401
- `shell` – Enables read-only shell access.
402402
- `shellrw` – Enables shell access with write permissions (`readwrite=true`).
403-
- `shellutils` – Adds the Mini File Tool helpers as an MCP (`useutils=true usetools=true`) exposing `init`, `fileQuery`, and `fileModify` actions.
403+
- `shellutils` – Adds the Mini File Tool helpers as an MCP (`useutils=true usetools=true`) exposing `init`, `filesystemQuery`, and `filesystemModify` actions.
404404
- `chatbot` – Switches to conversational mode (`chatbotmode=true`).
405405
- `web` – Optimizes for the browser UI with MCP tools registered (`usetools=true`).
406406
- `webfull` – Turns on diagrams, charts, ASCII sketches, attachments, history retention, and planning for the web UI (`usetools=true usediagrams=true usecharts=true useascii=true usehistory=true useattach=true historykeep=true useplanning=true`).

mini-a-con.js

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ try {
6666
var consoleReader = __
6767
var commandHistory = __
6868
var lastConversationStats = __
69-
var slashCommands = ["help", "set", "toggle", "unset", "show", "reset", "last", "clear", "context", "compact", "history", "exit", "quit"]
69+
var slashCommands = ["help", "set", "toggle", "unset", "show", "reset", "last", "clear", "context", "compact", "summarize", "history", "exit", "quit"]
7070
var resumeConversation = parseBoolean(findArgumentValue(args, "resume")) === true
7171
var conversationArgValue = findArgumentValue(args, "conversation")
7272
var initialConversationPath = isString(conversationArgValue) && conversationArgValue.trim().length > 0
@@ -500,6 +500,22 @@ try {
500500
}
501501
}
502502

503+
function summarize(ctx) {
504+
if (!isObject(activeAgent) || typeof activeAgent.summarizeText !== "function") {
505+
return ctx.substring(0, 400)
506+
}
507+
508+
try {
509+
var summaryResponse = activeAgent.summarizeText(ctx, { verbose: false })
510+
if (isString(summaryResponse) && summaryResponse.trim().length > 0) {
511+
return summaryResponse.trim()
512+
}
513+
} catch (summarizeError) {
514+
printErr(ansiColor("ITALIC," + errorColor, "!!") + colorifyText(" Summarization failed: " + summarizeError, errorColor))
515+
}
516+
return ctx.substring(0, 400)
517+
}
518+
503519
function compactConversationContext(preserveCount) {
504520
var stats = refreshConversationStats(activeAgent)
505521
if (!isObject(stats) || !isArray(stats.entries) || stats.entries.length === 0) {
@@ -588,6 +604,68 @@ try {
588604
}
589605
}
590606

607+
function summarizeConversation(preserveCount) {
608+
// First, compact the conversation
609+
compactConversationContext(preserveCount)
610+
611+
// Then generate and display a user-friendly summary of the entire conversation
612+
var stats = refreshConversationStats(activeAgent)
613+
if (!isObject(stats) || !isArray(stats.entries) || stats.entries.length === 0) {
614+
print(colorifyText("No conversation to summarize.", hintColor))
615+
return
616+
}
617+
618+
if (!isObject(activeAgent) || typeof activeAgent.summarizeText !== "function") {
619+
print(colorifyText("No active agent available. Run a goal first to enable summarization.", hintColor))
620+
return
621+
}
622+
623+
var conversationText = []
624+
stats.entries.forEach(function(entry) {
625+
var role = isString(entry.role) ? entry.role.toUpperCase() : "UNKNOWN"
626+
var content = flattenConversationContent(entry.content)
627+
conversationText.push(`${role}: ${content}`)
628+
})
629+
630+
var conversationPayload = conversationText.join("\n")
631+
632+
if (conversationPayload.trim().length === 0) {
633+
print(colorifyText("No conversation content to summarize.", hintColor))
634+
return
635+
}
636+
637+
try {
638+
print(colorifyText("Generating conversation summary...", hintColor))
639+
var instructionText = "You are summarizing a conversation between a user and an AI assistant. Provide a clear, concise summary that:\n1) Identifies the main topics discussed\n2) Highlights key decisions or outcomes\n3) Notes any unresolved questions or next steps\n\nFormat the summary in a readable way with bullet points where appropriate."
640+
641+
var fullSummary = activeAgent.summarizeText(conversationPayload, {
642+
verbose: false,
643+
instructionText: instructionText
644+
})
645+
646+
if (isString(fullSummary) && fullSummary.trim().length > 0) {
647+
print()
648+
print(colorifyText("=".repeat(60), accentColor))
649+
print(colorifyText("Conversation Summary", "BOLD," + accentColor))
650+
print(colorifyText("=".repeat(60), accentColor))
651+
print()
652+
var _m = jsonParse(fullSummary)
653+
if (isMap(_m) && isString(_m.answer)) _m.answer = ow.format.withMD(_m.answer)
654+
print(isObject(_m) ? printTree(_m) : ow.format.withMD(fullSummary.trim()))
655+
print()
656+
print(colorifyText("=".repeat(60), accentColor))
657+
} else {
658+
print(colorifyText("Unable to generate summary. Response was: " + stringify(fullSummary), errorColor))
659+
print(colorifyText("Conversation payload length: " + conversationPayload.length + " characters", hintColor))
660+
}
661+
} catch (summaryError) {
662+
printErr(ansiColor("ITALIC," + errorColor, "!!") + colorifyText(" Failed to generate conversation summary: " + summaryError, errorColor))
663+
if (isDef(summaryError.stack)) {
664+
print(colorifyText("Stack trace: " + summaryError.stack, errorColor))
665+
}
666+
}
667+
}
668+
591669
function resetOptions() {
592670
var opts = {}
593671
Object.keys(parameterDefinitions).forEach(function(key) {
@@ -997,6 +1075,7 @@ try {
9971075
" " + colorifyText("/clear", "BOLD") + colorifyText(" Reset the ongoing conversation", hintColor),
9981076
" " + colorifyText("/context", "BOLD") + colorifyText(" Visualize conversation/context size", hintColor),
9991077
" " + colorifyText("/compact", "BOLD") + colorifyText(" [n] Summarize old context, keep last n messages", hintColor),
1078+
" " + colorifyText("/summarize", "BOLD") + colorifyText(" [n] Compact and display an LLM-generated conversation summary", hintColor),
10001079
" " + colorifyText("/history", "BOLD") + colorifyText(" [n] Show the last n conversation turns", hintColor),
10011080
" " + colorifyText("/exit", "BOLD") + colorifyText(" Leave the console", hintColor)
10021081
]
@@ -1094,6 +1173,20 @@ try {
10941173
}
10951174
continue
10961175
}
1176+
if (command === "summarize") {
1177+
summarizeConversation()
1178+
continue
1179+
}
1180+
if (command.indexOf("summarize ") === 0) {
1181+
var keepValue = command.substring(10).trim()
1182+
var parsedKeep = parseInt(keepValue, 10)
1183+
if (isNaN(parsedKeep)) {
1184+
print(colorifyText("Usage: /summarize [messagesToKeep]", errorColor))
1185+
} else {
1186+
summarizeConversation(parsedKeep)
1187+
}
1188+
continue
1189+
}
10971190
if (command === "history") {
10981191
printConversationHistory()
10991192
continue

mini-a-utils.js

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ MiniUtilsTool.prototype.deleteFile = function(params) {
616616
}
617617
}
618618

619-
MiniUtilsTool.prototype.fileOps = function(params) {
619+
MiniUtilsTool.prototype.filesystemQuery = function(params) {
620620
var payload = isObject(params) ? params : {}
621621
var opValue = payload.operation
622622
var normalized = isString(opValue) && opValue.trim().length > 0 ? opValue.trim().toLowerCase() : "read"
@@ -641,7 +641,7 @@ MiniUtilsTool.prototype.fileOps = function(params) {
641641
var target = map[normalized]
642642
if (!target && isString(opValue) && isFunction(this[opValue])) target = opValue
643643
if (!target) {
644-
return "[ERROR] Unknown file query operation: " + (isString(opValue) ? opValue : normalized)
644+
return "[ERROR] Unknown filesystem query operation: " + (isString(opValue) ? opValue : normalized)
645645
}
646646

647647
var innerParams = {}
@@ -654,15 +654,15 @@ MiniUtilsTool.prototype.fileOps = function(params) {
654654
try {
655655
var handler = this[target]
656656
if (!isFunction(handler)) {
657-
return "[ERROR] Unsupported file query handler: " + target
657+
return "[ERROR] Unsupported filesystem query handler: " + target
658658
}
659659
return handler.call(this, innerParams)
660660
} catch (e) {
661661
return "[ERROR] " + (e && e.message ? e.message : String(e))
662662
}
663663
}
664664

665-
MiniUtilsTool.prototype.fileModify = function(params) {
665+
MiniUtilsTool.prototype.filesystemModify = function(params) {
666666
var payload = isObject(params) ? params : {}
667667
var opValue = payload.operation
668668
if (!isString(opValue) || opValue.trim().length === 0) {
@@ -682,7 +682,7 @@ MiniUtilsTool.prototype.fileModify = function(params) {
682682
var target = map[normalized]
683683
if (!target && isString(opValue) && isFunction(this[opValue])) target = opValue
684684
if (!target) {
685-
return "[ERROR] Unknown file modify operation: " + opValue
685+
return "[ERROR] Unknown filesystem modify operation: " + opValue
686686
}
687687

688688
var innerParams = {}
@@ -698,7 +698,7 @@ MiniUtilsTool.prototype.fileModify = function(params) {
698698
try {
699699
var handler = this[target]
700700
if (!isFunction(handler)) {
701-
return "[ERROR] Unsupported file modify handler: " + target
701+
return "[ERROR] Unsupported filesystem modify handler: " + target
702702
}
703703
return handler.call(this, innerParams)
704704
} catch (e) {
@@ -708,7 +708,7 @@ MiniUtilsTool.prototype.fileModify = function(params) {
708708

709709
/**
710710
* <odoc>
711-
* <key>MiniUtilsTool.mathOps(params) : Object</key>
711+
* <key>MiniUtilsTool.mathematics(params) : Object</key>
712712
* Performs mathematical operations including calculations, statistics, unit conversions, and random number generation.
713713
* The `params` object can have the following properties:
714714
* - `operation` (string, required): The operation to perform (calculate, statistics, convert-unit, random).
@@ -718,7 +718,7 @@ MiniUtilsTool.prototype.fileModify = function(params) {
718718
* - For random: `type` (integer, sequence, choice, boolean, hex), type-specific params (min/max, items, count, seed, etc.)
719719
* </odoc>
720720
*/
721-
MiniUtilsTool.prototype.mathOps = function(params) {
721+
MiniUtilsTool.prototype.mathematics = function(params) {
722722
params = params || {}
723723
var op = (params.operation || "calculate").toLowerCase()
724724

@@ -859,7 +859,7 @@ MiniUtilsTool.prototype.mathOps = function(params) {
859859

860860
/**
861861
* <odoc>
862-
* <key>MiniUtilsTool.timeOps(params) : Object</key>
862+
* <key>MiniUtilsTool.timeUtilities(params) : Object</key>
863863
* Performs time and timezone operations.
864864
* The `params` object can have the following properties:
865865
* - `operation` (string): The operation to perform (current-time, convert, sleep). Defaults to current-time.
@@ -868,7 +868,7 @@ MiniUtilsTool.prototype.mathOps = function(params) {
868868
* - For sleep: `milliseconds` (required)
869869
* </odoc>
870870
*/
871-
MiniUtilsTool.prototype.timeOps = function(params) {
871+
MiniUtilsTool.prototype.timeUtilities = function(params) {
872872
params = params || {}
873873
var op = (params.operation || "current-time").toLowerCase()
874874

@@ -938,8 +938,8 @@ MiniUtilsTool._metadataByFn = (function() {
938938
var modifyDeleteOps = ["delete", "remove", "rm", "deletefile"]
939939
var modifyAllOps = modifyWriteOps.concat(modifyDeleteOps)
940940

941-
var mathOps = ["calculate", "statistics", "convert-unit", "convert", "random"]
942-
var timeOps = ["current-time", "current", "timezone-convert", "sleep"]
941+
var mathOperationTypes = ["calculate", "statistics", "convert-unit", "convert", "random"]
942+
var timeOperationTypes = ["current-time", "current", "timezone-convert", "sleep"]
943943

944944
return {
945945
init: {
@@ -953,9 +953,9 @@ MiniUtilsTool._metadataByFn = (function() {
953953
}
954954
}
955955
},
956-
fileOps: { // Suggested name change for clarity
957-
name : "fileOps",
958-
description: "Perform various operations on files and directories within the configured root, including reading, listing, searching, and retrieving information.",
956+
filesystemQuery: {
957+
name : "filesystemQuery",
958+
description: "Execute read-only filesystem actions such as reading file contents, listing directories, searching text, or retrieving metadata within the configured root.",
959959
inputSchema: {
960960
type : "object",
961961
properties: {
@@ -990,9 +990,9 @@ MiniUtilsTool._metadataByFn = (function() {
990990
]
991991
}
992992
},
993-
fileModify: { // Suggested name change for clarity
994-
name : "fileModify",
995-
description: "Modify files and directories by writing, appending, or deleting them (requires readwrite=true for modifications).",
993+
filesystemModify: {
994+
name : "filesystemModify",
995+
description: "Perform write, append, or delete operations on files and directories within the configured root (requires readwrite=true).",
996996
inputSchema: {
997997
type : "object",
998998
properties: {
@@ -1022,16 +1022,16 @@ MiniUtilsTool._metadataByFn = (function() {
10221022
]
10231023
}
10241024
},
1025-
mathOps: {
1026-
name : "mathOps",
1027-
description: "Perform mathematical operations including calculations, statistics, unit conversions, and random number generation.",
1025+
mathematics: {
1026+
name : "mathematics",
1027+
description: "Run mathematical utilities including arithmetic calculations, descriptive statistics, unit conversions, and random value generation.",
10281028
inputSchema: {
10291029
type : "object",
10301030
properties: {
10311031
operation: {
10321032
type : "string",
10331033
description: "Operation type: calculate, statistics, convert-unit, or random.",
1034-
enum : mathOps,
1034+
enum : mathOperationTypes,
10351035
default : "calculate"
10361036
},
10371037
op : { type: "string", description: "Math operation for calculate: add, subtract, multiply, divide, power, sqrt, abs, round." },
@@ -1057,16 +1057,16 @@ MiniUtilsTool._metadataByFn = (function() {
10571057
required : []
10581058
}
10591059
},
1060-
timeOps: {
1061-
name : "timeOps",
1062-
description: "Perform time and timezone operations including getting current time, timezone conversions, and sleep.",
1060+
timeUtilities: {
1061+
name : "timeUtilities",
1062+
description: "Work with time by returning the current time, converting between time zones, or pausing execution.",
10631063
inputSchema: {
10641064
type : "object",
10651065
properties: {
10661066
operation : {
10671067
type : "string",
10681068
description: "Operation type: current-time, convert, or sleep.",
1069-
enum : timeOps,
1069+
enum : timeOperationTypes,
10701070
default : "current-time"
10711071
},
10721072
timezone : { type: "string", description: "IANA timezone identifier (e.g., 'America/New_York', 'Europe/London')." },

0 commit comments

Comments
 (0)