mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
Merge pull request #1325 from Enferlain/fix/1284-list-valued-fields
fix(search): preserve compound requested fields
This commit is contained in:
2 files changed
+50
-33
No files matched your search
+27
-30
@@ -3241,6 +3241,27 @@ static int sg_parse_fields(const char *args, const char *out[], int max_out, yyj
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Append a property as one compact-output cell. Compound values stay one
|
||||
* column by using their compact JSON representation; the cell emitter quotes
|
||||
* and escapes that representation as needed. */
|
||||
static void sg_toon_property_cell(cbm_sb_t *sb, yyjson_val *v) {
|
||||
if (v && yyjson_is_str(v)) {
|
||||
cbm_tree_cell_str(sb, yyjson_get_str(v), false);
|
||||
} else if (v && yyjson_is_bool(v)) {
|
||||
cbm_tree_cell_bool(sb, yyjson_get_bool(v), false);
|
||||
} else if (v && yyjson_is_int(v)) {
|
||||
cbm_tree_cell_int(sb, yyjson_get_int(v), false);
|
||||
} else if (v && yyjson_is_real(v)) {
|
||||
cbm_tree_cell_real(sb, yyjson_get_real(v), false);
|
||||
} else if (v && !yyjson_is_null(v)) {
|
||||
char *json = yyjson_val_write(v, 0, NULL);
|
||||
cbm_tree_cell_str(sb, json ? json : "", false);
|
||||
free(json);
|
||||
} else {
|
||||
cbm_tree_cell_str(sb, "", false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Append one row's extra-field cells, pulled from the node's properties. */
|
||||
static void sg_toon_extra_cells(cbm_sb_t *sb, const char *props_json, const char *const *fields,
|
||||
int nfields) {
|
||||
@@ -3249,17 +3270,7 @@ static void sg_toon_extra_cells(cbm_sb_t *sb, const char *props_json, const char
|
||||
yyjson_val *pr = pd ? yyjson_doc_get_root(pd) : NULL;
|
||||
for (int f = 0; f < nfields; f++) {
|
||||
yyjson_val *v = (pr && yyjson_is_obj(pr)) ? yyjson_obj_get(pr, fields[f]) : NULL;
|
||||
if (v && yyjson_is_str(v)) {
|
||||
cbm_tree_cell_str(sb, yyjson_get_str(v), false);
|
||||
} else if (v && yyjson_is_bool(v)) {
|
||||
cbm_tree_cell_bool(sb, yyjson_get_bool(v), false);
|
||||
} else if (v && yyjson_is_int(v)) {
|
||||
cbm_tree_cell_int(sb, yyjson_get_int(v), false);
|
||||
} else if (v && yyjson_is_real(v)) {
|
||||
cbm_tree_cell_real(sb, yyjson_get_real(v), false);
|
||||
} else {
|
||||
cbm_tree_cell_str(sb, "", false);
|
||||
}
|
||||
sg_toon_property_cell(sb, v);
|
||||
}
|
||||
if (pd) {
|
||||
yyjson_doc_free(pd);
|
||||
@@ -3391,17 +3402,7 @@ static void emit_search_results_tree(cbm_sb_t *sb, cbm_search_output_t *out, int
|
||||
yyjson_val *pr = pd ? yyjson_doc_get_root(pd) : NULL;
|
||||
for (int f = 0; f < nfields; f++) {
|
||||
yyjson_val *v = (pr && yyjson_is_obj(pr)) ? yyjson_obj_get(pr, fields[f]) : NULL;
|
||||
if (v && yyjson_is_str(v)) {
|
||||
cbm_tree_cell_str(sb, yyjson_get_str(v), false);
|
||||
} else if (v && yyjson_is_int(v)) {
|
||||
cbm_tree_cell_int(sb, yyjson_get_int(v), false);
|
||||
} else if (v && yyjson_is_real(v)) {
|
||||
cbm_tree_cell_real(sb, yyjson_get_real(v), false);
|
||||
} else if (v && yyjson_is_bool(v)) {
|
||||
cbm_tree_cell_bool(sb, yyjson_get_bool(v), false);
|
||||
} else {
|
||||
cbm_tree_cell_str(sb, "", false); /* emits "-" */
|
||||
}
|
||||
sg_toon_property_cell(sb, v);
|
||||
}
|
||||
if (pd) {
|
||||
yyjson_doc_free(pd);
|
||||
@@ -3483,14 +3484,10 @@ static void emit_search_results_tree_json(yyjson_mut_doc *doc, yyjson_mut_val *r
|
||||
yyjson_val *pr = pd ? yyjson_doc_get_root(pd) : NULL;
|
||||
for (int f = 0; f < nfields; f++) {
|
||||
yyjson_val *v = (pr && yyjson_is_obj(pr)) ? yyjson_obj_get(pr, fields[f]) : NULL;
|
||||
if (v && yyjson_is_str(v)) {
|
||||
yyjson_mut_arr_add_strcpy(doc, row, yyjson_get_str(v));
|
||||
} else if (v && yyjson_is_int(v)) {
|
||||
yyjson_mut_arr_add_int(doc, row, yyjson_get_int(v));
|
||||
} else if (v && yyjson_is_real(v)) {
|
||||
yyjson_mut_arr_add_real(doc, row, yyjson_get_real(v));
|
||||
} else if (v && yyjson_is_bool(v)) {
|
||||
yyjson_mut_arr_add_bool(doc, row, yyjson_get_bool(v));
|
||||
yyjson_mut_val *copy =
|
||||
(v && !yyjson_is_null(v)) ? yyjson_val_mut_copy(doc, v) : NULL;
|
||||
if (copy) {
|
||||
yyjson_mut_arr_add_val(row, copy);
|
||||
} else {
|
||||
yyjson_mut_arr_add_null(doc, row);
|
||||
}
|
||||
|
||||
+23
-3
@@ -2084,15 +2084,32 @@ TEST(tool_search_graph_includes_node_properties) {
|
||||
free(inner);
|
||||
free(resp);
|
||||
|
||||
/* List-valued fields are compact JSON in text output, rather than an
|
||||
* empty placeholder. */
|
||||
resp = cbm_mcp_server_handle(
|
||||
srv, "{\"jsonrpc\":\"2.0\",\"id\":431,\"method\":\"tools/call\","
|
||||
"\"params\":{\"name\":\"search_graph\","
|
||||
"\"arguments\":{\"project\":\"test-project\",\"label\":\"Function\","
|
||||
"\"name_pattern\":\"HandleRequest\",\"fields\":[\"base_classes\"],"
|
||||
"\"limit\":5}}}");
|
||||
ASSERT_NOT_NULL(resp);
|
||||
inner = extract_text_content(resp);
|
||||
ASSERT_NOT_NULL(inner);
|
||||
ASSERT_NOT_NULL(strstr(inner, "base_classes"));
|
||||
ASSERT_NOT_NULL(strstr(inner, "HandlerBase"));
|
||||
ASSERT_NOT_NULL(strstr(inner, "Audited"));
|
||||
free(inner);
|
||||
free(resp);
|
||||
|
||||
/* format:"json" = json-stringified tree: same grouped model, column-
|
||||
* ordered row arrays — never per-row key envelopes or property blobs.
|
||||
* fields adds columns there too. */
|
||||
* fields adds columns there too and preserves compound JSON types. */
|
||||
resp = cbm_mcp_server_handle(
|
||||
srv, "{\"jsonrpc\":\"2.0\",\"id\":44,\"method\":\"tools/call\","
|
||||
"\"params\":{\"name\":\"search_graph\","
|
||||
"\"arguments\":{\"project\":\"test-project\",\"label\":\"Function\","
|
||||
"\"name_pattern\":\"HandleRequest\",\"format\":\"json\","
|
||||
"\"fields\":[\"signature\"],\"limit\":5}}}");
|
||||
"\"fields\":[\"signature\",\"base_classes\"],\"limit\":5}}}");
|
||||
ASSERT_NOT_NULL(resp);
|
||||
inner = extract_text_content(resp);
|
||||
ASSERT_NOT_NULL(inner);
|
||||
@@ -2101,6 +2118,8 @@ TEST(tool_search_graph_includes_node_properties) {
|
||||
ASSERT_NOT_NULL(strstr(inner, "\"rows\""));
|
||||
ASSERT_NOT_NULL(strstr(inner, "\"signature\"")); /* requested column */
|
||||
ASSERT_NOT_NULL(strstr(inner, "func HandleRequest")); /* its value */
|
||||
ASSERT_NOT_NULL(strstr(inner, "\"base_classes\""));
|
||||
ASSERT_NOT_NULL(strstr(inner, "[\"HandlerBase\",\"Audited\"]"));
|
||||
ASSERT_NULL(strstr(inner, "is_exported")); /* blob never spills */
|
||||
free(inner);
|
||||
free(resp);
|
||||
@@ -7411,7 +7430,8 @@ static cbm_mcp_server_t *setup_snippet_server(char *tmp_dir, size_t tmp_sz) {
|
||||
n_hr.end_line = 5;
|
||||
n_hr.properties_json = "{\"signature\":\"func HandleRequest() error\","
|
||||
"\"return_type\":\"error\","
|
||||
"\"is_exported\":true}";
|
||||
"\"is_exported\":true,"
|
||||
"\"base_classes\":[\"HandlerBase\",\"Audited\"]}";
|
||||
int64_t id_hr = cbm_store_upsert_node(st, &n_hr);
|
||||
|
||||
cbm_node_t n_po = {0};
|
||||
|
||||
Reference in new issue
Block a user