@dikolab/kbdb 0.6.4 → 0.6.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/dist/cli.cjs +452 -144
- package/dist/cli.cjs.map +4 -4
- package/dist/cli.mjs +452 -144
- package/dist/cli.mjs.map +4 -4
- package/dist/kbdb-worker.cjs +49 -7
- package/dist/kbdb-worker.cjs.map +4 -4
- package/dist/mod.cjs +1 -1
- package/dist/mod.cjs.map +1 -1
- package/dist/mod.mjs +1 -1
- package/dist/mod.mjs.map +1 -1
- package/dist/src/shared/cli/constants/defaults.constant.d.ts +1 -1
- package/dist/src/shared/cli/functions/learn-structured-document.function.d.ts +10 -0
- package/dist/src/shared/cli/functions/learn-target-content.function.d.ts +5 -17
- package/dist/src/shared/cli/functions/split-markdown-sections.function.d.ts +4 -0
- package/dist/src/shared/cli/typings/learn-client.interface.d.ts +2 -0
- package/dist/src/shared/cli/typings/learn-result.model.d.ts +2 -0
- package/dist/src/shared/content-splitter/classes/heading-parent-tracker.class.d.ts +20 -0
- package/dist/src/shared/content-splitter/constants/content-type-maps.constant.d.ts +5 -0
- package/dist/src/shared/content-splitter/constants/split-strategy-map.constant.d.ts +4 -0
- package/dist/src/shared/content-splitter/functions/detect-content-type.function.d.ts +13 -0
- package/dist/src/shared/content-splitter/functions/flush-markdown-draft.function.d.ts +14 -0
- package/dist/src/shared/content-splitter/functions/flush-toml-draft.function.d.ts +15 -0
- package/dist/src/shared/content-splitter/functions/push-content-section.function.d.ts +16 -0
- package/dist/src/shared/content-splitter/functions/resolve-parent-ids.function.d.ts +14 -0
- package/dist/src/shared/content-splitter/functions/split-content.function.d.ts +11 -0
- package/dist/src/shared/content-splitter/functions/split-html.function.d.ts +12 -0
- package/dist/src/shared/content-splitter/functions/split-markdown.function.d.ts +13 -0
- package/dist/src/shared/content-splitter/functions/split-plain-text.function.d.ts +8 -0
- package/dist/src/shared/content-splitter/functions/split-toml.function.d.ts +12 -0
- package/dist/src/shared/content-splitter/index.d.ts +11 -0
- package/dist/src/shared/content-splitter/typings/content-format.type.d.ts +2 -0
- package/dist/src/shared/content-splitter/typings/content-section.interface.d.ts +17 -0
- package/dist/src/shared/content-splitter/typings/markdown-draft.interface.d.ts +12 -0
- package/dist/src/shared/content-splitter/typings/split-result.interface.d.ts +8 -0
- package/dist/src/shared/content-splitter/typings/split-strategy.interface.d.ts +3 -0
- package/dist/src/shared/content-splitter/typings/toml-draft.interface.d.ts +15 -0
- package/dist/src/shared/mcp/functions/build-learn-payload.function.d.ts +24 -0
- package/dist/src/shared/mcp/functions/determine-learn-split.function.d.ts +18 -0
- package/dist/src/shared/mcp/functions/handle-tool-learn.function.d.ts +3 -1
- package/dist/src/shared/mcp/functions/learn-with-splitting.function.d.ts +22 -0
- package/dist/src/shared/mcp/functions/parse-learn-args.function.d.ts +24 -0
- package/dist/src/shared/mcp/functions/store-split-learn-sections.function.d.ts +16 -0
- package/dist/src/shared/mcp/functions/unwrap-json-content.function.d.ts +9 -0
- package/dist/src/shared/mcp/typings/learn-section-params.interface.d.ts +20 -0
- package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +4 -0
- package/dist/src/shared/mcp/typings/mcp-worker-client.interface.d.ts +4 -0
- package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
- package/dist/src/shared/wasm-codec/functions/decode-one-recall-result.function.d.ts +2 -1
- package/dist/src/shared/wasm-codec/functions/decode-recall-document.function.d.ts +2 -1
- package/dist/src/shared/wasm-codec/functions/decode-recall-result.function.d.ts +2 -0
- package/dist/src/shared/wasm-codec/functions/decode-recall-sibling.function.d.ts +2 -1
- package/dist/src/shared/wasm-codec/functions/decode-scored-results.function.d.ts +6 -0
- package/dist/src/shared/wasm-codec/functions/decode-section-match.function.d.ts +2 -1
- package/dist/src/shared/wasm-codec/functions/decode-section-records.function.d.ts +4 -0
- package/dist/src/shared/wasm-codec/functions/encode-add-section-params.function.d.ts +1 -0
- package/dist/src/shared/wasm-codec/typings/add-section-input.model.d.ts +2 -0
- package/dist/src/shared/wasm-codec/typings/section-match.model.d.ts +4 -0
- package/dist/src/shared/wasm-codec/typings/section-record-trailing.model.d.ts +2 -0
- package/dist/src/shared/wasm-codec/typings/section-record.model.d.ts +2 -0
- package/dist/src/shared/worker-client/typings/recall-result.model.d.ts +12 -0
- package/dist/src/shared/worker-client/typings/search-result.model.d.ts +4 -0
- package/dist/src/shared/worker-client/typings/section.model.d.ts +2 -0
- package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
- package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
- package/dist/worker.mjs +49 -7
- package/dist/worker.mjs.map +4 -4
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -31,7 +31,10 @@ var SUPPORTED_EXTENSIONS = [
|
|
|
31
31
|
".md",
|
|
32
32
|
".txt",
|
|
33
33
|
".rst",
|
|
34
|
-
".adoc"
|
|
34
|
+
".adoc",
|
|
35
|
+
".html",
|
|
36
|
+
".htm",
|
|
37
|
+
".toml"
|
|
35
38
|
];
|
|
36
39
|
|
|
37
40
|
// src/shared/log/typings/log-level.type.ts
|
|
@@ -745,13 +748,102 @@ function computeDirectoryLevel(filePath, basePath) {
|
|
|
745
748
|
return Math.min(depth + 1, MAX_LEVEL);
|
|
746
749
|
}
|
|
747
750
|
|
|
748
|
-
// src/shared/
|
|
749
|
-
var
|
|
751
|
+
// src/shared/content-splitter/constants/content-type-maps.constant.ts
|
|
752
|
+
var HINT_FORMAT_MAP = {
|
|
753
|
+
markdown: "markdown",
|
|
754
|
+
"text/markdown": "markdown",
|
|
755
|
+
md: "markdown",
|
|
756
|
+
html: "html",
|
|
757
|
+
"text/html": "html",
|
|
758
|
+
toml: "toml",
|
|
759
|
+
"application/toml": "toml",
|
|
760
|
+
"text/toml": "toml",
|
|
761
|
+
"text/x-toml": "toml"
|
|
762
|
+
};
|
|
763
|
+
var EXTENSION_FORMAT_MAP = {
|
|
764
|
+
md: "markdown",
|
|
765
|
+
markdown: "markdown",
|
|
766
|
+
html: "html",
|
|
767
|
+
htm: "html",
|
|
768
|
+
toml: "toml"
|
|
769
|
+
};
|
|
750
770
|
|
|
751
|
-
// src/shared/
|
|
771
|
+
// src/shared/content-splitter/functions/detect-content-type.function.ts
|
|
772
|
+
function detectContentType(content, typeHint, filePath) {
|
|
773
|
+
const hinted = typeHint && HINT_FORMAT_MAP[typeHint.toLowerCase()];
|
|
774
|
+
if (hinted) return hinted;
|
|
775
|
+
const extension = filePath?.split(".").pop()?.toLowerCase();
|
|
776
|
+
const extMatch = extension && EXTENSION_FORMAT_MAP[extension];
|
|
777
|
+
if (extMatch) return extMatch;
|
|
778
|
+
return sniffContentType(content);
|
|
779
|
+
}
|
|
780
|
+
function sniffContentType(content) {
|
|
781
|
+
const trimmed = content.trimStart();
|
|
782
|
+
if (/^<!DOCTYPE/i.test(trimmed) || /^<html/i.test(trimmed)) {
|
|
783
|
+
return "html";
|
|
784
|
+
}
|
|
785
|
+
if (trimmed.startsWith("[") && trimmed.includes("=")) {
|
|
786
|
+
return "toml";
|
|
787
|
+
}
|
|
788
|
+
return "plain-text";
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// src/shared/content-splitter/classes/heading-parent-tracker.class.ts
|
|
792
|
+
var HeadingParentTracker = class {
|
|
793
|
+
stack = [];
|
|
794
|
+
/**
|
|
795
|
+
* Resolves the parent index for a heading at `level`
|
|
796
|
+
* appearing at output position `index`, then records the
|
|
797
|
+
* heading so subsequent, deeper headings can nest under it.
|
|
798
|
+
*
|
|
799
|
+
* @param level - heading depth, shallower is smaller
|
|
800
|
+
* @param index - position of this heading in the output
|
|
801
|
+
* sections array
|
|
802
|
+
* @returns the parent's output index, or `null` when the
|
|
803
|
+
* heading is at the root
|
|
804
|
+
*/
|
|
805
|
+
resolve(level, index) {
|
|
806
|
+
while (this.stack.length > 0 && this.stack[this.stack.length - 1].level >= level) {
|
|
807
|
+
this.stack.pop();
|
|
808
|
+
}
|
|
809
|
+
const parentIndex = this.stack.length > 0 ? this.stack[this.stack.length - 1].index : null;
|
|
810
|
+
this.stack.push({ level, index });
|
|
811
|
+
return parentIndex;
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
// src/shared/content-splitter/functions/push-content-section.function.ts
|
|
816
|
+
function pushContentSection(sections, tracker, content, title, level) {
|
|
817
|
+
if (level === void 0) {
|
|
818
|
+
sections.push({ content, parentIndex: null });
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
sections.push({
|
|
822
|
+
title,
|
|
823
|
+
level,
|
|
824
|
+
content,
|
|
825
|
+
parentIndex: tracker.resolve(level, sections.length)
|
|
826
|
+
});
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// src/shared/content-splitter/functions/flush-markdown-draft.function.ts
|
|
830
|
+
function flushMarkdownDraft(draft, sections, tracker) {
|
|
831
|
+
const body = draft.lines.join("\n").trimEnd();
|
|
832
|
+
if (draft.title === void 0 && body.length === 0) return;
|
|
833
|
+
pushContentSection(
|
|
834
|
+
sections,
|
|
835
|
+
tracker,
|
|
836
|
+
body,
|
|
837
|
+
draft.title,
|
|
838
|
+
draft.level
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
// src/shared/content-splitter/functions/split-markdown.function.ts
|
|
752
843
|
var HEADING_PATTERN = /^(#{1,6})\s+(.+)$/;
|
|
753
|
-
function
|
|
844
|
+
function splitMarkdown(content) {
|
|
754
845
|
const sections = [];
|
|
846
|
+
const tracker = new HeadingParentTracker();
|
|
755
847
|
let draft = { lines: [] };
|
|
756
848
|
let inCodeBlock = false;
|
|
757
849
|
for (const line of content.split("\n")) {
|
|
@@ -762,7 +854,7 @@ function splitMarkdownSections(content) {
|
|
|
762
854
|
}
|
|
763
855
|
const heading = inCodeBlock ? null : HEADING_PATTERN.exec(line);
|
|
764
856
|
if (heading) {
|
|
765
|
-
|
|
857
|
+
flushMarkdownDraft(draft, sections, tracker);
|
|
766
858
|
draft = {
|
|
767
859
|
title: heading[2].trim(),
|
|
768
860
|
level: heading[1].length,
|
|
@@ -772,14 +864,113 @@ function splitMarkdownSections(content) {
|
|
|
772
864
|
}
|
|
773
865
|
draft.lines.push(line);
|
|
774
866
|
}
|
|
775
|
-
|
|
776
|
-
return sections.length > 0 ? sections : [{ content: content.trimEnd() }];
|
|
867
|
+
flushMarkdownDraft(draft, sections, tracker);
|
|
868
|
+
return sections.length > 0 ? sections : [{ content: content.trimEnd(), parentIndex: null }];
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// src/shared/content-splitter/functions/split-html.function.ts
|
|
872
|
+
var HEADING_PATTERN2 = /<h([1-6])[^>]*>(.*?)<\/h\1>/gi;
|
|
873
|
+
function splitHtml(content) {
|
|
874
|
+
const matches = [...content.matchAll(HEADING_PATTERN2)];
|
|
875
|
+
if (matches.length === 0) {
|
|
876
|
+
return [{ content: content.trimEnd(), parentIndex: null }];
|
|
877
|
+
}
|
|
878
|
+
const sections = [];
|
|
879
|
+
const tracker = new HeadingParentTracker();
|
|
880
|
+
const firstIndex = matches[0].index;
|
|
881
|
+
const preamble = content.slice(0, firstIndex).trimEnd();
|
|
882
|
+
if (preamble.length > 0) {
|
|
883
|
+
pushContentSection(sections, tracker, preamble);
|
|
884
|
+
}
|
|
885
|
+
matches.forEach((match, i) => {
|
|
886
|
+
const start = match.index + match[0].length;
|
|
887
|
+
const end = matches[i + 1]?.index ?? content.length;
|
|
888
|
+
pushContentSection(
|
|
889
|
+
sections,
|
|
890
|
+
tracker,
|
|
891
|
+
content.slice(start, end).trimEnd(),
|
|
892
|
+
match[2].trim(),
|
|
893
|
+
Number(match[1])
|
|
894
|
+
);
|
|
895
|
+
});
|
|
896
|
+
return sections;
|
|
777
897
|
}
|
|
778
|
-
|
|
898
|
+
|
|
899
|
+
// src/shared/content-splitter/functions/flush-toml-draft.function.ts
|
|
900
|
+
function flushTomlDraft(draft, sections, pathIndex) {
|
|
779
901
|
const body = draft.lines.join("\n").trimEnd();
|
|
780
902
|
if (draft.title === void 0 && body.length === 0) return;
|
|
781
|
-
|
|
782
|
-
|
|
903
|
+
if (draft.title === void 0) {
|
|
904
|
+
sections.push({ content: body, parentIndex: null });
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
const path = draft.path ?? draft.title;
|
|
908
|
+
sections.push({
|
|
909
|
+
title: draft.title,
|
|
910
|
+
content: body,
|
|
911
|
+
parentIndex: resolveParentIndex(path, pathIndex)
|
|
912
|
+
});
|
|
913
|
+
pathIndex.set(path, sections.length - 1);
|
|
914
|
+
}
|
|
915
|
+
function resolveParentIndex(path, pathIndex) {
|
|
916
|
+
if (/^["']/.test(path)) return null;
|
|
917
|
+
const segments = path.split(".");
|
|
918
|
+
segments.pop();
|
|
919
|
+
if (segments.length === 0) return null;
|
|
920
|
+
return pathIndex.get(segments.join(".")) ?? null;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
// src/shared/content-splitter/functions/split-toml.function.ts
|
|
924
|
+
var HEADER_PATTERN = /^\[([^\]]+)\]\s*$/;
|
|
925
|
+
var QUOTED_PATTERN = /^(["'])(.*)\1$/;
|
|
926
|
+
function splitToml(content) {
|
|
927
|
+
const sections = [];
|
|
928
|
+
const pathIndex = /* @__PURE__ */ new Map();
|
|
929
|
+
let draft = { lines: [] };
|
|
930
|
+
for (const line of content.split("\n")) {
|
|
931
|
+
const header = HEADER_PATTERN.exec(line);
|
|
932
|
+
if (header) {
|
|
933
|
+
flushTomlDraft(draft, sections, pathIndex);
|
|
934
|
+
draft = { ...parseHeader(header[1]), lines: [] };
|
|
935
|
+
continue;
|
|
936
|
+
}
|
|
937
|
+
draft.lines.push(line);
|
|
938
|
+
}
|
|
939
|
+
flushTomlDraft(draft, sections, pathIndex);
|
|
940
|
+
return sections.length > 0 ? sections : [{ content: content.trimEnd(), parentIndex: null }];
|
|
941
|
+
}
|
|
942
|
+
function parseHeader(inner) {
|
|
943
|
+
const trimmed = inner.trim();
|
|
944
|
+
const quoted = QUOTED_PATTERN.exec(trimmed);
|
|
945
|
+
return quoted ? { title: quoted[2], path: trimmed } : { title: trimmed, path: trimmed };
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// src/shared/content-splitter/functions/split-plain-text.function.ts
|
|
949
|
+
function splitPlainText(content) {
|
|
950
|
+
return [{ content, parentIndex: null }];
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// src/shared/content-splitter/constants/split-strategy-map.constant.ts
|
|
954
|
+
var SPLIT_STRATEGY_MAP = {
|
|
955
|
+
markdown: splitMarkdown,
|
|
956
|
+
html: splitHtml,
|
|
957
|
+
toml: splitToml,
|
|
958
|
+
"plain-text": splitPlainText
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
// src/shared/content-splitter/functions/split-content.function.ts
|
|
962
|
+
function splitContent(content, typeHint, filePath) {
|
|
963
|
+
const format = detectContentType(content, typeHint, filePath);
|
|
964
|
+
return {
|
|
965
|
+
format,
|
|
966
|
+
sections: SPLIT_STRATEGY_MAP[format](content)
|
|
967
|
+
};
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
// src/shared/content-splitter/functions/resolve-parent-ids.function.ts
|
|
971
|
+
function resolveParentIds(sections, kbids) {
|
|
972
|
+
return sections.map(
|
|
973
|
+
(section) => section.parentIndex === null ? null : kbids[section.parentIndex]
|
|
783
974
|
);
|
|
784
975
|
}
|
|
785
976
|
|
|
@@ -798,15 +989,16 @@ function mapAddSectionResult(result, path, size, sectionType) {
|
|
|
798
989
|
};
|
|
799
990
|
}
|
|
800
991
|
|
|
801
|
-
// src/shared/cli/functions/learn-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
const
|
|
805
|
-
|
|
806
|
-
const docTitle =
|
|
992
|
+
// src/shared/cli/functions/learn-structured-document.function.ts
|
|
993
|
+
var import_node_path3 = require("node:path");
|
|
994
|
+
async function learnStructuredDocument(client, options, path, splitResult, sourcePath) {
|
|
995
|
+
const { sections } = splitResult;
|
|
996
|
+
const firstTitled = sections.find((s) => s.title !== void 0);
|
|
997
|
+
const docTitle = firstTitled?.title ?? (0, import_node_path3.basename)(path);
|
|
807
998
|
const kbids = [];
|
|
808
999
|
const results = [];
|
|
809
1000
|
for (const section of sections) {
|
|
1001
|
+
const [parent] = resolveParentIds([section], kbids);
|
|
810
1002
|
const added = await client.addSection({
|
|
811
1003
|
sectionType: "text",
|
|
812
1004
|
content: section.content,
|
|
@@ -816,7 +1008,8 @@ async function learnMarkdownDocument(client, options, path, content, sourcePath)
|
|
|
816
1008
|
tags: options.tags,
|
|
817
1009
|
replace: options.replace,
|
|
818
1010
|
sourcePath,
|
|
819
|
-
level: section.level
|
|
1011
|
+
level: section.level,
|
|
1012
|
+
parent: parent ?? void 0
|
|
820
1013
|
});
|
|
821
1014
|
kbids.push(added.items[0] ?? "");
|
|
822
1015
|
results.push(
|
|
@@ -834,16 +1027,25 @@ async function learnMarkdownDocument(client, options, path, content, sourcePath)
|
|
|
834
1027
|
|
|
835
1028
|
// src/shared/cli/functions/learn-target-content.function.ts
|
|
836
1029
|
async function learnTargetContent(client, options, path, content, sourcePath, level) {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
const split =
|
|
840
|
-
client,
|
|
841
|
-
options,
|
|
842
|
-
path,
|
|
1030
|
+
if (!options.title) {
|
|
1031
|
+
const isStdin = path === "-";
|
|
1032
|
+
const split = splitContent(
|
|
843
1033
|
content,
|
|
844
|
-
|
|
1034
|
+
isStdin ? "markdown" : void 0,
|
|
1035
|
+
isStdin ? void 0 : path
|
|
1036
|
+
);
|
|
1037
|
+
const hasTitled = split.sections.some(
|
|
1038
|
+
(s) => s.title !== void 0
|
|
845
1039
|
);
|
|
846
|
-
if (split)
|
|
1040
|
+
if (split.sections.length >= 2 && hasTitled) {
|
|
1041
|
+
return learnStructuredDocument(
|
|
1042
|
+
client,
|
|
1043
|
+
options,
|
|
1044
|
+
path,
|
|
1045
|
+
split,
|
|
1046
|
+
sourcePath
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
847
1049
|
}
|
|
848
1050
|
const result = await client.addSection({
|
|
849
1051
|
sectionType: "text",
|
|
@@ -1918,7 +2120,7 @@ async function handleTypedSearch(client, options, type) {
|
|
|
1918
2120
|
}
|
|
1919
2121
|
|
|
1920
2122
|
// src/shared/version/constants/version.constant.ts
|
|
1921
|
-
var VERSION = "0.6.
|
|
2123
|
+
var VERSION = "0.6.5";
|
|
1922
2124
|
|
|
1923
2125
|
// src/shared/cli/functions/generate-help.function.ts
|
|
1924
2126
|
var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
|
|
@@ -1997,7 +2199,7 @@ Usage: kbdb [options]
|
|
|
1997
2199
|
kbdb <command> <subcommand> [options] ...[params]
|
|
1998
2200
|
|
|
1999
2201
|
Knowledge Base:
|
|
2000
|
-
learn Import content (splits
|
|
2202
|
+
learn Import content (auto-splits structured formats)
|
|
2001
2203
|
unlearn Remove sections by kbid
|
|
2002
2204
|
search Query the knowledge base (sibling boost)
|
|
2003
2205
|
recall Retrieve section context by kbid
|
|
@@ -2021,25 +2223,31 @@ Skills:
|
|
|
2021
2223
|
skill list List skills (filter by keyword)
|
|
2022
2224
|
skill get Retrieve a skill by name or kbid
|
|
2023
2225
|
skill delete Remove a skill
|
|
2226
|
+
skill search Search skills by keyword
|
|
2024
2227
|
|
|
2025
2228
|
Agents:
|
|
2026
2229
|
agent create Create an agent with skill refs
|
|
2027
2230
|
agent list List agents (filter by keyword)
|
|
2028
2231
|
agent get Retrieve an agent by docid
|
|
2029
2232
|
agent delete Remove an agent
|
|
2030
|
-
|
|
2031
|
-
Worker:
|
|
2032
|
-
worker stop Stop the worker daemon
|
|
2033
|
-
worker restart Restart the worker daemon
|
|
2233
|
+
agent search Search agents by keyword
|
|
2034
2234
|
|
|
2035
2235
|
Server:
|
|
2036
2236
|
mcp Start MCP server mode (stdio)
|
|
2037
2237
|
|
|
2038
2238
|
Global Options:
|
|
2039
2239
|
-h, --help Show this help message
|
|
2040
|
-
|
|
2240
|
+
--version Show version information
|
|
2241
|
+
-v, --verbose Log warnings (-vv info, -vvv debug)
|
|
2041
2242
|
--db <path> Path to .kbdb directory
|
|
2042
|
-
--format <fmt> Output format (json|text|mcp)
|
|
2243
|
+
--format <fmt> Output format (rec|json|text|mcp)
|
|
2244
|
+
--timeout-ms <ms> Request timeout (default 30000)
|
|
2245
|
+
--retry <n> Retries on timeout (default 1)
|
|
2246
|
+
--non-interactive Suppress prompts
|
|
2247
|
+
|
|
2248
|
+
Worker:
|
|
2249
|
+
worker stop Stop background daemon
|
|
2250
|
+
worker restart Restart background daemon
|
|
2043
2251
|
|
|
2044
2252
|
Run "kbdb <command> --help" for detailed information.
|
|
2045
2253
|
`;
|
|
@@ -2096,14 +2304,19 @@ Options:
|
|
|
2096
2304
|
--replace Supersede existing section by source key
|
|
2097
2305
|
--db <path> Path to .kbdb directory
|
|
2098
2306
|
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2307
|
+
Content splitting:
|
|
2308
|
+
Structured formats are automatically split
|
|
2309
|
+
into independent sections that share a docid.
|
|
2310
|
+
Each section carries a level (heading depth)
|
|
2311
|
+
and parent (kbid of enclosing section).
|
|
2312
|
+
Providing --title imports as a single section
|
|
2313
|
+
(skips splitting).
|
|
2314
|
+
|
|
2315
|
+
Supported formats:
|
|
2316
|
+
Markdown .md, text/markdown ATX headings
|
|
2317
|
+
HTML .html, text/html <h1>-<h6> tags
|
|
2318
|
+
TOML .toml, application/toml [section]
|
|
2319
|
+
Plain .txt, text/plain no splitting
|
|
2107
2320
|
|
|
2108
2321
|
Output:
|
|
2109
2322
|
{ items, total, offset } envelope
|
|
@@ -2141,7 +2354,7 @@ Arguments:
|
|
|
2141
2354
|
Options:
|
|
2142
2355
|
--mode <mode> Result granularity (sections|documents|stats)
|
|
2143
2356
|
--limit <n> Max results (default: 20)
|
|
2144
|
-
--format <fmt> Output format (json|text|mcp)
|
|
2357
|
+
--format <fmt> Output format (rec|json|text|mcp)
|
|
2145
2358
|
--content, -c Hydrate results with section content
|
|
2146
2359
|
--db <path> Path to .kbdb directory
|
|
2147
2360
|
|
|
@@ -2151,6 +2364,11 @@ Scoring:
|
|
|
2151
2364
|
sibling score boost when multiple sections
|
|
2152
2365
|
match the query.
|
|
2153
2366
|
|
|
2367
|
+
Fields:
|
|
2368
|
+
Each result includes level (heading depth,
|
|
2369
|
+
1-6 or null) and parent (kbid of enclosing
|
|
2370
|
+
section or null).
|
|
2371
|
+
|
|
2154
2372
|
Output:
|
|
2155
2373
|
{ items, total, offset } envelope
|
|
2156
2374
|
|
|
@@ -2172,7 +2390,8 @@ Options:
|
|
|
2172
2390
|
--db <path> Path to .kbdb directory
|
|
2173
2391
|
|
|
2174
2392
|
Output:
|
|
2175
|
-
JSON RecallResult or RecallResult[]
|
|
2393
|
+
JSON RecallResult or RecallResult[] with
|
|
2394
|
+
level, parent, siblings, and references
|
|
2176
2395
|
|
|
2177
2396
|
Examples:
|
|
2178
2397
|
kbdb recall abcdef1234567890abcdef1234
|
|
@@ -2181,11 +2400,14 @@ Examples:
|
|
|
2181
2400
|
content: `kbdb content - Compose rendered content from ids
|
|
2182
2401
|
|
|
2183
2402
|
Usage: kbdb content [options] <id>...
|
|
2403
|
+
kbdb content --search <query>...
|
|
2184
2404
|
|
|
2185
2405
|
Arguments:
|
|
2186
2406
|
<id> kbid or docid identifier
|
|
2407
|
+
<query> Search terms (with --search)
|
|
2187
2408
|
|
|
2188
2409
|
Options:
|
|
2410
|
+
--search, -s Search for ids by keyword
|
|
2189
2411
|
--db <path> Path to .kbdb directory
|
|
2190
2412
|
|
|
2191
2413
|
Output:
|
|
@@ -2194,6 +2416,7 @@ Output:
|
|
|
2194
2416
|
Examples:
|
|
2195
2417
|
kbdb content abcdef1234567890abcdef1234
|
|
2196
2418
|
kbdb content id1 id2
|
|
2419
|
+
kbdb content --search machine learning
|
|
2197
2420
|
`,
|
|
2198
2421
|
check: `kbdb check - Verify knowledge base integrity
|
|
2199
2422
|
|
|
@@ -3784,7 +4007,7 @@ function createToolDefinitions() {
|
|
|
3784
4007
|
return [
|
|
3785
4008
|
{
|
|
3786
4009
|
name: "search",
|
|
3787
|
-
description: "Query the knowledge base by keywords. Returns ranked results with heading, snippet,
|
|
4010
|
+
description: "Query the knowledge base by keywords. Returns ranked results with heading, snippet, matched terms, level, and parent. Sections from the same document receive a sibling score boost when multiple sections match. Use multiple short keyword queries for best coverage. Use recall for full content.",
|
|
3788
4011
|
inputSchema: {
|
|
3789
4012
|
type: "object",
|
|
3790
4013
|
properties: {
|
|
@@ -3827,7 +4050,7 @@ function createToolDefinitions() {
|
|
|
3827
4050
|
},
|
|
3828
4051
|
{
|
|
3829
4052
|
name: "learn",
|
|
3830
|
-
description: "Import content into the knowledge base.
|
|
4053
|
+
description: "Import content into the knowledge base. Structured content (Markdown, HTML, TOML) is automatically split into sections that share a docid. Each section carries a level (heading depth) and parent reference. Providing title imports as a single section (skips splitting). Use replace when updating existing knowledge. Attach tags for scoping.",
|
|
3831
4054
|
inputSchema: {
|
|
3832
4055
|
type: "object",
|
|
3833
4056
|
properties: {
|
|
@@ -3837,11 +4060,11 @@ function createToolDefinitions() {
|
|
|
3837
4060
|
},
|
|
3838
4061
|
type: {
|
|
3839
4062
|
type: "string",
|
|
3840
|
-
description: "MIME type
|
|
4063
|
+
description: "MIME type or format hint. Supported: text/markdown, text/html, application/toml (also text/toml, text/x-toml), text/plain, image/*. Default: text/markdown."
|
|
3841
4064
|
},
|
|
3842
4065
|
title: {
|
|
3843
4066
|
type: "string",
|
|
3844
|
-
description: "Section title. Skips
|
|
4067
|
+
description: "Section title. Skips content splitting when set. Required for image/* types."
|
|
3845
4068
|
},
|
|
3846
4069
|
description: {
|
|
3847
4070
|
type: "string",
|
|
@@ -3849,7 +4072,7 @@ function createToolDefinitions() {
|
|
|
3849
4072
|
},
|
|
3850
4073
|
docid: {
|
|
3851
4074
|
type: "string",
|
|
3852
|
-
description: "Document ID to group sections under. Set automatically when
|
|
4075
|
+
description: "Document ID to group sections under. Set automatically when content splitting is active."
|
|
3853
4076
|
},
|
|
3854
4077
|
tags: {
|
|
3855
4078
|
type: "array",
|
|
@@ -3918,7 +4141,7 @@ function createToolDefinitions() {
|
|
|
3918
4141
|
},
|
|
3919
4142
|
{
|
|
3920
4143
|
name: "recall",
|
|
3921
|
-
description: "Retrieve full content and context for sections by identifier. Use after search to read relevant results. Returns section text, metadata, references, and back-references.",
|
|
4144
|
+
description: "Retrieve full content and context for sections by identifier. Use after search to read relevant results. Returns section text, level, parent, metadata, references, and back-references.",
|
|
3922
4145
|
inputSchema: {
|
|
3923
4146
|
type: "object",
|
|
3924
4147
|
properties: {
|
|
@@ -4049,7 +4272,7 @@ function createToolDefinitions() {
|
|
|
4049
4272
|
},
|
|
4050
4273
|
{
|
|
4051
4274
|
name: "skill-learn",
|
|
4052
|
-
description: "Create or update a skill definition. Skills are reusable AI agent capabilities with template placeholders.",
|
|
4275
|
+
description: "Create or update a skill definition. Skills are reusable AI agent capabilities with template placeholders. Stored as atomic JSON (not split into sections).",
|
|
4053
4276
|
inputSchema: {
|
|
4054
4277
|
type: "object",
|
|
4055
4278
|
properties: {
|
|
@@ -4143,7 +4366,7 @@ function createToolDefinitions() {
|
|
|
4143
4366
|
},
|
|
4144
4367
|
{
|
|
4145
4368
|
name: "agent-create",
|
|
4146
|
-
description: "Create an AI agent with a persona and optional skill references.",
|
|
4369
|
+
description: "Create an AI agent with a persona and optional skill references. Stored as atomic JSON (not split into sections).",
|
|
4147
4370
|
inputSchema: {
|
|
4148
4371
|
type: "object",
|
|
4149
4372
|
properties: {
|
|
@@ -4304,7 +4527,7 @@ function createToolDefinitions() {
|
|
|
4304
4527
|
title: "Auto-Capture Review",
|
|
4305
4528
|
readOnlyHint: false,
|
|
4306
4529
|
destructiveHint: false,
|
|
4307
|
-
idempotentHint:
|
|
4530
|
+
idempotentHint: false,
|
|
4308
4531
|
openWorldHint: false
|
|
4309
4532
|
}
|
|
4310
4533
|
}
|
|
@@ -4693,25 +4916,38 @@ async function handleAgentSearch(client, args) {
|
|
|
4693
4916
|
return { content: [{ type: "text", text }] };
|
|
4694
4917
|
}
|
|
4695
4918
|
|
|
4696
|
-
// src/shared/mcp/functions/
|
|
4919
|
+
// src/shared/mcp/functions/as-string.function.ts
|
|
4697
4920
|
function asString2(value, fallback) {
|
|
4698
4921
|
return typeof value === "string" ? value : fallback;
|
|
4699
4922
|
}
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
}
|
|
4923
|
+
|
|
4924
|
+
// src/shared/mcp/functions/as-string-array-or-undefined.function.ts
|
|
4703
4925
|
function asStringArrayOrUndefined(value) {
|
|
4704
4926
|
if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
|
|
4705
4927
|
return value;
|
|
4706
4928
|
}
|
|
4707
4929
|
return void 0;
|
|
4708
4930
|
}
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4931
|
+
|
|
4932
|
+
// src/shared/mcp/functions/as-boolean-or-undefined.function.ts
|
|
4933
|
+
function asBooleanOrUndefined(value) {
|
|
4934
|
+
return typeof value === "boolean" ? value : void 0;
|
|
4935
|
+
}
|
|
4936
|
+
|
|
4937
|
+
// src/shared/mcp/functions/parse-learn-args.function.ts
|
|
4938
|
+
function parseLearnArgs(args) {
|
|
4939
|
+
return {
|
|
4940
|
+
sectionType: asString2(args["type"], "text/markdown"),
|
|
4941
|
+
title: typeof args["title"] === "string" ? args["title"] : void 0,
|
|
4942
|
+
description: typeof args["description"] === "string" ? args["description"] : void 0,
|
|
4943
|
+
docid: typeof args["docid"] === "string" ? args["docid"] : void 0,
|
|
4944
|
+
tags: asStringArrayOrUndefined(args["tags"]),
|
|
4945
|
+
replace: asBooleanOrUndefined(args["replace"]),
|
|
4946
|
+
level: typeof args["level"] === "number" ? args["level"] : void 0
|
|
4947
|
+
};
|
|
4714
4948
|
}
|
|
4949
|
+
|
|
4950
|
+
// src/shared/mcp/functions/unwrap-json-content.function.ts
|
|
4715
4951
|
function unwrapJsonContent(raw) {
|
|
4716
4952
|
const trimmed = raw.trim();
|
|
4717
4953
|
if (!trimmed.startsWith("{")) return raw;
|
|
@@ -4724,6 +4960,158 @@ function unwrapJsonContent(raw) {
|
|
|
4724
4960
|
}
|
|
4725
4961
|
return raw;
|
|
4726
4962
|
}
|
|
4963
|
+
|
|
4964
|
+
// src/shared/mcp/functions/determine-learn-split.function.ts
|
|
4965
|
+
function determineLearnSplit(content, sectionType, title) {
|
|
4966
|
+
const splittable = sectionType.startsWith("text/") || sectionType === "markdown" || sectionType === "application/toml";
|
|
4967
|
+
if (title !== void 0 || !splittable) return void 0;
|
|
4968
|
+
const result = splitContent(content, sectionType);
|
|
4969
|
+
const hasTitledSection = result.sections.some(
|
|
4970
|
+
(section) => section.title !== void 0
|
|
4971
|
+
);
|
|
4972
|
+
return result.sections.length >= 2 && hasTitledSection ? result : void 0;
|
|
4973
|
+
}
|
|
4974
|
+
|
|
4975
|
+
// src/shared/mcp/functions/learn-with-splitting.function.ts
|
|
4976
|
+
async function learnWithSplitting(client, splitResult, params) {
|
|
4977
|
+
const { sections } = splitResult;
|
|
4978
|
+
const firstTitled = sections.find((s) => s.title !== void 0);
|
|
4979
|
+
const docTitle = firstTitled?.title ?? params.docid ?? "Untitled";
|
|
4980
|
+
const docid = params.docid ?? firstTitled?.title;
|
|
4981
|
+
const kbids = [];
|
|
4982
|
+
for (const section of sections) {
|
|
4983
|
+
const [parent] = resolveParentIds([section], kbids);
|
|
4984
|
+
const result = await client.addSection({
|
|
4985
|
+
sectionType: params.sectionType,
|
|
4986
|
+
content: section.content,
|
|
4987
|
+
title: section.title,
|
|
4988
|
+
description: params.description,
|
|
4989
|
+
docid,
|
|
4990
|
+
tags: params.tags,
|
|
4991
|
+
replace: params.replace,
|
|
4992
|
+
level: section.level,
|
|
4993
|
+
parent: parent ?? void 0
|
|
4994
|
+
});
|
|
4995
|
+
kbids.push(result.items[0] ?? "");
|
|
4996
|
+
}
|
|
4997
|
+
return { kbids, docTitle };
|
|
4998
|
+
}
|
|
4999
|
+
|
|
5000
|
+
// src/shared/mcp/functions/store-split-learn-sections.function.ts
|
|
5001
|
+
async function storeSplitLearnSections(client, splitResult, params) {
|
|
5002
|
+
const { kbids, docTitle } = await learnWithSplitting(
|
|
5003
|
+
client,
|
|
5004
|
+
splitResult,
|
|
5005
|
+
params
|
|
5006
|
+
);
|
|
5007
|
+
await client.groupSections(docTitle, kbids);
|
|
5008
|
+
return {
|
|
5009
|
+
items: kbids,
|
|
5010
|
+
total: kbids.length,
|
|
5011
|
+
offset: 0,
|
|
5012
|
+
superseded: null,
|
|
5013
|
+
warnings: [],
|
|
5014
|
+
near_duplicates: []
|
|
5015
|
+
};
|
|
5016
|
+
}
|
|
5017
|
+
|
|
5018
|
+
// src/shared/mcp/functions/build-learn-payload.function.ts
|
|
5019
|
+
function buildLearnPayload(result) {
|
|
5020
|
+
return {
|
|
5021
|
+
items: result.items,
|
|
5022
|
+
total: result.total,
|
|
5023
|
+
offset: result.offset,
|
|
5024
|
+
superseded: result.superseded ?? null,
|
|
5025
|
+
warnings: result.warnings ?? [],
|
|
5026
|
+
near_duplicates: result.near_duplicates ?? []
|
|
5027
|
+
};
|
|
5028
|
+
}
|
|
5029
|
+
|
|
5030
|
+
// src/shared/mcp/functions/handle-tool-learn.function.ts
|
|
5031
|
+
async function handleToolLearn(client, args) {
|
|
5032
|
+
const learnArgs = parseLearnArgs(args);
|
|
5033
|
+
const { sectionType, title, level, ...shared } = learnArgs;
|
|
5034
|
+
if (sectionType.startsWith("image/") && !title) {
|
|
5035
|
+
return {
|
|
5036
|
+
content: [
|
|
5037
|
+
{
|
|
5038
|
+
type: "text",
|
|
5039
|
+
text: "title is required for image/* types"
|
|
5040
|
+
}
|
|
5041
|
+
],
|
|
5042
|
+
isError: true
|
|
5043
|
+
};
|
|
5044
|
+
}
|
|
5045
|
+
const content = unwrapJsonContent(asString2(args["content"], ""));
|
|
5046
|
+
const splitResult = determineLearnSplit(content, sectionType, title);
|
|
5047
|
+
const result = splitResult ? await storeSplitLearnSections(client, splitResult, {
|
|
5048
|
+
sectionType,
|
|
5049
|
+
...shared
|
|
5050
|
+
}) : await client.addSection({
|
|
5051
|
+
sectionType,
|
|
5052
|
+
content,
|
|
5053
|
+
title,
|
|
5054
|
+
level,
|
|
5055
|
+
...shared
|
|
5056
|
+
});
|
|
5057
|
+
return {
|
|
5058
|
+
content: [
|
|
5059
|
+
{
|
|
5060
|
+
type: "text",
|
|
5061
|
+
text: JSON.stringify(buildLearnPayload(result))
|
|
5062
|
+
}
|
|
5063
|
+
]
|
|
5064
|
+
};
|
|
5065
|
+
}
|
|
5066
|
+
|
|
5067
|
+
// src/shared/mcp/functions/handle-tool-skill-learn.function.ts
|
|
5068
|
+
async function handleToolSkillLearn(client, args) {
|
|
5069
|
+
const name = asString2(args["name"], "");
|
|
5070
|
+
if (!name) {
|
|
5071
|
+
return {
|
|
5072
|
+
content: [{ type: "text", text: "name is required" }],
|
|
5073
|
+
isError: true
|
|
5074
|
+
};
|
|
5075
|
+
}
|
|
5076
|
+
const body = asString2(args["body"], "");
|
|
5077
|
+
if (!body) {
|
|
5078
|
+
return {
|
|
5079
|
+
content: [{ type: "text", text: "body is required" }],
|
|
5080
|
+
isError: true
|
|
5081
|
+
};
|
|
5082
|
+
}
|
|
5083
|
+
const description = typeof args["description"] === "string" ? args["description"] : void 0;
|
|
5084
|
+
const skillArgs = extractSkillArguments(body);
|
|
5085
|
+
const skill = {
|
|
5086
|
+
name,
|
|
5087
|
+
description,
|
|
5088
|
+
arguments: skillArgs.length > 0 ? skillArgs : void 0,
|
|
5089
|
+
body
|
|
5090
|
+
};
|
|
5091
|
+
const json = serializeSkillContent(skill);
|
|
5092
|
+
const result = await client.addSection({
|
|
5093
|
+
sectionType: "skill",
|
|
5094
|
+
content: json,
|
|
5095
|
+
title: name,
|
|
5096
|
+
description
|
|
5097
|
+
});
|
|
5098
|
+
return {
|
|
5099
|
+
content: [
|
|
5100
|
+
{
|
|
5101
|
+
type: "text",
|
|
5102
|
+
text: `Created skill "${name}" (kbid: ${result.items[0]})`
|
|
5103
|
+
}
|
|
5104
|
+
]
|
|
5105
|
+
};
|
|
5106
|
+
}
|
|
5107
|
+
|
|
5108
|
+
// src/shared/mcp/functions/handle-tool-call.function.ts
|
|
5109
|
+
function asStringArray2(value) {
|
|
5110
|
+
if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
|
|
5111
|
+
return value;
|
|
5112
|
+
}
|
|
5113
|
+
return [];
|
|
5114
|
+
}
|
|
4727
5115
|
async function handleToolCall(client, name, args) {
|
|
4728
5116
|
log("tool call: " + name, 0 /* DEBUG */);
|
|
4729
5117
|
try {
|
|
@@ -4731,7 +5119,7 @@ async function handleToolCall(client, name, args) {
|
|
|
4731
5119
|
case "search":
|
|
4732
5120
|
return await handleSearch2(client, args);
|
|
4733
5121
|
case "learn":
|
|
4734
|
-
return await
|
|
5122
|
+
return await handleToolLearn(client, args);
|
|
4735
5123
|
case "unlearn":
|
|
4736
5124
|
return await handleUnlearn2(client, args);
|
|
4737
5125
|
case "retrieve":
|
|
@@ -4751,7 +5139,7 @@ async function handleToolCall(client, name, args) {
|
|
|
4751
5139
|
case "export":
|
|
4752
5140
|
return await handleExport2(client, args);
|
|
4753
5141
|
case "skill-learn":
|
|
4754
|
-
return await
|
|
5142
|
+
return await handleToolSkillLearn(client, args);
|
|
4755
5143
|
case "skill-list":
|
|
4756
5144
|
return await handleSkillList(client, args);
|
|
4757
5145
|
case "skill-get":
|
|
@@ -4816,47 +5204,6 @@ async function handleSearch2(client, args) {
|
|
|
4816
5204
|
]
|
|
4817
5205
|
};
|
|
4818
5206
|
}
|
|
4819
|
-
async function handleLearn2(client, args) {
|
|
4820
|
-
const sectionType = asString2(args["type"], "text/markdown");
|
|
4821
|
-
const title = typeof args["title"] === "string" ? args["title"] : void 0;
|
|
4822
|
-
const description = typeof args["description"] === "string" ? args["description"] : void 0;
|
|
4823
|
-
const docid = typeof args["docid"] === "string" ? args["docid"] : void 0;
|
|
4824
|
-
const tags = asStringArrayOrUndefined(args["tags"]);
|
|
4825
|
-
const replace = asBooleanOrUndefined(args["replace"]);
|
|
4826
|
-
if (sectionType.startsWith("image/") && !title) {
|
|
4827
|
-
return {
|
|
4828
|
-
content: [
|
|
4829
|
-
{
|
|
4830
|
-
type: "text",
|
|
4831
|
-
text: "title is required for image/* types"
|
|
4832
|
-
}
|
|
4833
|
-
],
|
|
4834
|
-
isError: true
|
|
4835
|
-
};
|
|
4836
|
-
}
|
|
4837
|
-
const rawContent = asString2(args["content"], "");
|
|
4838
|
-
const content = unwrapJsonContent(rawContent);
|
|
4839
|
-
const result = await client.addSection({
|
|
4840
|
-
sectionType,
|
|
4841
|
-
content,
|
|
4842
|
-
title,
|
|
4843
|
-
description,
|
|
4844
|
-
docid,
|
|
4845
|
-
tags,
|
|
4846
|
-
replace
|
|
4847
|
-
});
|
|
4848
|
-
const payload = {
|
|
4849
|
-
items: result.items,
|
|
4850
|
-
total: result.total,
|
|
4851
|
-
offset: result.offset,
|
|
4852
|
-
superseded: result.superseded ?? null,
|
|
4853
|
-
warnings: result.warnings ?? [],
|
|
4854
|
-
near_duplicates: result.near_duplicates ?? []
|
|
4855
|
-
};
|
|
4856
|
-
return {
|
|
4857
|
-
content: [{ type: "text", text: JSON.stringify(payload) }]
|
|
4858
|
-
};
|
|
4859
|
-
}
|
|
4860
5207
|
async function handleUnlearn2(client, args) {
|
|
4861
5208
|
const kbid = asString2(args["kbid"], "");
|
|
4862
5209
|
await client.removeSection(kbid);
|
|
@@ -4963,45 +5310,6 @@ async function handleRebuild2(client) {
|
|
|
4963
5310
|
const text = `Rebuild complete: ${String(report.sections_reindexed)} sections reindexed, ${String(report.terms_indexed)} terms indexed.`;
|
|
4964
5311
|
return { content: [{ type: "text", text }] };
|
|
4965
5312
|
}
|
|
4966
|
-
async function handleSkillLearn(client, args) {
|
|
4967
|
-
const name = asString2(args["name"], "");
|
|
4968
|
-
if (!name) {
|
|
4969
|
-
return {
|
|
4970
|
-
content: [{ type: "text", text: "name is required" }],
|
|
4971
|
-
isError: true
|
|
4972
|
-
};
|
|
4973
|
-
}
|
|
4974
|
-
const body = asString2(args["body"], "");
|
|
4975
|
-
if (!body) {
|
|
4976
|
-
return {
|
|
4977
|
-
content: [{ type: "text", text: "body is required" }],
|
|
4978
|
-
isError: true
|
|
4979
|
-
};
|
|
4980
|
-
}
|
|
4981
|
-
const description = typeof args["description"] === "string" ? args["description"] : void 0;
|
|
4982
|
-
const skillArgs = extractSkillArguments(body);
|
|
4983
|
-
const skill = {
|
|
4984
|
-
name,
|
|
4985
|
-
description,
|
|
4986
|
-
arguments: skillArgs.length > 0 ? skillArgs : void 0,
|
|
4987
|
-
body
|
|
4988
|
-
};
|
|
4989
|
-
const json = serializeSkillContent(skill);
|
|
4990
|
-
const result = await client.addSection({
|
|
4991
|
-
sectionType: "skill",
|
|
4992
|
-
content: json,
|
|
4993
|
-
title: name,
|
|
4994
|
-
description
|
|
4995
|
-
});
|
|
4996
|
-
return {
|
|
4997
|
-
content: [
|
|
4998
|
-
{
|
|
4999
|
-
type: "text",
|
|
5000
|
-
text: `Created skill "${name}" (kbid: ${result.items[0]})`
|
|
5001
|
-
}
|
|
5002
|
-
]
|
|
5003
|
-
};
|
|
5004
|
-
}
|
|
5005
5313
|
async function handleSkillList(client, args) {
|
|
5006
5314
|
const records = await client.listByType("skill");
|
|
5007
5315
|
const query = typeof args["query"] === "string" ? args["query"].toLowerCase() : "";
|