@koda-sl/baker-cli 0.529.0 → 0.531.0
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 +23 -0
- package/dist/{ads-6ESCXPHK.js → ads-7TEPA4KZ.js} +3 -3
- package/dist/{analytics-OUNKG2FW.js → analytics-XDWBEY57.js} +13 -13
- package/dist/{avatars-IJQOWSFC.js → avatars-K7RBSMIJ.js} +1 -1
- package/dist/{brief-ZDHUBPV5.js → brief-SLTB3EPO.js} +15 -15
- package/dist/{canvas-AZ47PNYZ.js → canvas-2VRPGRND.js} +11 -11
- package/dist/{chunk-5G225R4A.js → chunk-3H5MJOG2.js} +2 -2
- package/dist/{chunk-WSYQ6LWB.js → chunk-4ULRDQVD.js} +5 -1
- package/dist/chunk-4ULRDQVD.js.map +1 -0
- package/dist/{chunk-KDNOMRJA.js → chunk-5EF7ZLXA.js} +3 -3
- package/dist/{chunk-4VSD4NSZ.js → chunk-7HH4F2KX.js} +3 -3
- package/dist/{chunk-Z4ZYFIDQ.js → chunk-CKTVRR3D.js} +2 -2
- package/dist/{chunk-3N2KAOVM.js → chunk-CSCHS3JG.js} +7 -7
- package/dist/{chunk-7B73TSKJ.js → chunk-ERRTBCDW.js} +3 -3
- package/dist/{chunk-7ODQ6ZID.js → chunk-EZBZU6N7.js} +3 -3
- package/dist/{chunk-HZ3RXKR4.js → chunk-FVZL2YC5.js} +5 -5
- package/dist/{chunk-FX3MXXYD.js → chunk-GDQJG4BO.js} +2 -2
- package/dist/{chunk-PTK7AFEE.js → chunk-HAJYFRXL.js} +2 -2
- package/dist/{chunk-SXML3LQN.js → chunk-IHZUSAUX.js} +2 -2
- package/dist/{chunk-EIDJCUMM.js → chunk-OYNBUT5X.js} +2 -2
- package/dist/{chunk-OXARC5HH.js → chunk-PGBZ73UZ.js} +2 -2
- package/dist/{chunk-B65WCT6M.js → chunk-PILLZPNC.js} +38 -2
- package/dist/chunk-PILLZPNC.js.map +1 -0
- package/dist/{chunk-ZL5YETKR.js → chunk-TE4ASZSC.js} +2 -2
- package/dist/{chunk-7OVCUTEL.js → chunk-XWO6CXNG.js} +2 -2
- package/dist/{chunk-WQKBEC4I.js → chunk-Y25HSPRJ.js} +2 -2
- package/dist/cli.js +19 -17
- package/dist/cli.js.map +1 -1
- package/dist/{create-UI2YG2KA.js → create-PYP3QWTL.js} +3 -3
- package/dist/{creatives-QFSIIFXB.js → creatives-ANTJUTIE.js} +6 -6
- package/dist/{critique-OK2ENBOA.js → critique-MZUTDK4V.js} +5 -5
- package/dist/{delete-4CUEJZ2Z.js → delete-3H6YH4YK.js} +3 -3
- package/dist/{feedback-ZBEZIIPT.js → feedback-TJRYTOR3.js} +8 -8
- package/dist/{feedback-record-CZVSPZUR.js → feedback-record-7IAJI5IY.js} +11 -11
- package/dist/{flows-CAOMVQYZ.js → flows-LL5SPPIK.js} +1 -1
- package/dist/{funnel-LKF6D7AA.js → funnel-XIZROHV7.js} +3 -3
- package/dist/{get-TB52FVNV.js → get-XPJ4BZGP.js} +3 -3
- package/dist/{google-FZVOB7HW.js → google-5JV7OMOH.js} +2 -2
- package/dist/{history-SJJX6EXI.js → history-RD2YMNNL.js} +3 -3
- package/dist/{images-K7JQ3ORB.js → images-XP4TKE2F.js} +1 -1
- package/dist/{inspiration-KAXPRINY.js → inspiration-D75DO3MD.js} +1 -1
- package/dist/knowledge-PKXPN4RV.js +195 -0
- package/dist/knowledge-PKXPN4RV.js.map +1 -0
- package/dist/{landing-BFMRM3HA.js → landing-O2ZUIUGE.js} +2 -2
- package/dist/lead-routes-WVXWVG62.js +733 -0
- package/dist/lead-routes-WVXWVG62.js.map +1 -0
- package/dist/{list-PT4DVD4U.js → list-OZCU2T22.js} +3 -3
- package/dist/{lookup-IUQWU346.js → lookup-K57ITJWF.js} +4 -4
- package/dist/{make-N5LVJSZD.js → make-T6HLXIYY.js} +21 -21
- package/dist/{performance-6XFKDJGY.js → performance-MHJDRLEK.js} +2 -2
- package/dist/{plan-VHMWZU7F.js → plan-JYSHKPZQ.js} +3 -3
- package/dist/{posts-BDMC644W.js → posts-ILAFADBW.js} +1 -1
- package/dist/{questionnaire-32BQ4ZUX.js → questionnaire-Y37I64FO.js} +3 -3
- package/dist/{rerun-HUFJUOEV.js → rerun-UPDIXTEL.js} +9 -9
- package/dist/{run-MRC4UVHU.js → run-4UIPMCSN.js} +3 -3
- package/dist/{run-7OCCCNJ4.js → run-GACZDI6Q.js} +9 -9
- package/dist/{scaffold-ad-7ADCDQBK.js → scaffold-ad-Z2HSN4PE.js} +6 -6
- package/dist/{scaffold-static-ad-TV5OWISA.js → scaffold-static-ad-ODZGTIM5.js} +11 -11
- package/dist/{scaffold-video-LLBDO546.js → scaffold-video-EHGAMEEP.js} +6 -6
- package/dist/{scheduled-agents-EPPP4SCZ.js → scheduled-agents-4VY4CAA2.js} +11 -11
- package/dist/{schema-5Q6VO5MW.js → schema-EYGPETLF.js} +2 -2
- package/dist/{select-BRH4QLWU.js → select-FCQUYBKV.js} +7 -7
- package/dist/{sends-43FU3SJN.js → sends-MZKHZZGJ.js} +3 -3
- package/dist/{set-prompt-SYWNE4CS.js → set-prompt-IBAG6BDA.js} +5 -5
- package/dist/{sources-CGXHNWJM.js → sources-K2LILGTW.js} +1 -1
- package/dist/{sources-PUZ4WV4Q.js → sources-ZM7LEIMM.js} +4 -4
- package/dist/{stale-QNIJZTGD.js → stale-VR5QAYB6.js} +6 -6
- package/dist/{studio-NRWLXOFZ.js → studio-3D42TUJX.js} +1 -1
- package/dist/{sync-definition-EGHEQ57K.js → sync-definition-MZUJOJYI.js} +6 -6
- package/dist/{targets-3WIBMP4B.js → targets-LQ7HGI73.js} +3 -3
- package/dist/{testimonials-2NQMY23B.js → testimonials-Z2KOOMVH.js} +2 -2
- package/dist/{translate-YGHRSEX6.js → translate-II4JY2XW.js} +8 -8
- package/dist/{triggers-6EXLTW35.js → triggers-Z3LV3KJR.js} +3 -3
- package/dist/{unstage-YSVQ6DLB.js → unstage-AVLORZLW.js} +3 -3
- package/dist/{unstage-KEMVI37X.js → unstage-QXOL5DXZ.js} +3 -3
- package/dist/{update-USKR3UOC.js → update-UE4XVBKL.js} +3 -3
- package/dist/{url-options-6MFRIDNA.js → url-options-DJZV3ADK.js} +2 -2
- package/dist/{validate-JX4FT7PL.js → validate-BCK22BQL.js} +7 -7
- package/dist/{videos-EHDZ46UQ.js → videos-YCQVOOFE.js} +1 -1
- package/dist/{winning-ads-H7ZE5AQW.js → winning-ads-7X5EWSJX.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-B65WCT6M.js.map +0 -1
- package/dist/chunk-WSYQ6LWB.js.map +0 -1
- /package/dist/{ads-6ESCXPHK.js.map → ads-7TEPA4KZ.js.map} +0 -0
- /package/dist/{analytics-OUNKG2FW.js.map → analytics-XDWBEY57.js.map} +0 -0
- /package/dist/{avatars-IJQOWSFC.js.map → avatars-K7RBSMIJ.js.map} +0 -0
- /package/dist/{brief-ZDHUBPV5.js.map → brief-SLTB3EPO.js.map} +0 -0
- /package/dist/{canvas-AZ47PNYZ.js.map → canvas-2VRPGRND.js.map} +0 -0
- /package/dist/{chunk-5G225R4A.js.map → chunk-3H5MJOG2.js.map} +0 -0
- /package/dist/{chunk-KDNOMRJA.js.map → chunk-5EF7ZLXA.js.map} +0 -0
- /package/dist/{chunk-4VSD4NSZ.js.map → chunk-7HH4F2KX.js.map} +0 -0
- /package/dist/{chunk-Z4ZYFIDQ.js.map → chunk-CKTVRR3D.js.map} +0 -0
- /package/dist/{chunk-3N2KAOVM.js.map → chunk-CSCHS3JG.js.map} +0 -0
- /package/dist/{chunk-7B73TSKJ.js.map → chunk-ERRTBCDW.js.map} +0 -0
- /package/dist/{chunk-7ODQ6ZID.js.map → chunk-EZBZU6N7.js.map} +0 -0
- /package/dist/{chunk-HZ3RXKR4.js.map → chunk-FVZL2YC5.js.map} +0 -0
- /package/dist/{chunk-FX3MXXYD.js.map → chunk-GDQJG4BO.js.map} +0 -0
- /package/dist/{chunk-PTK7AFEE.js.map → chunk-HAJYFRXL.js.map} +0 -0
- /package/dist/{chunk-SXML3LQN.js.map → chunk-IHZUSAUX.js.map} +0 -0
- /package/dist/{chunk-EIDJCUMM.js.map → chunk-OYNBUT5X.js.map} +0 -0
- /package/dist/{chunk-OXARC5HH.js.map → chunk-PGBZ73UZ.js.map} +0 -0
- /package/dist/{chunk-ZL5YETKR.js.map → chunk-TE4ASZSC.js.map} +0 -0
- /package/dist/{chunk-7OVCUTEL.js.map → chunk-XWO6CXNG.js.map} +0 -0
- /package/dist/{chunk-WQKBEC4I.js.map → chunk-Y25HSPRJ.js.map} +0 -0
- /package/dist/{create-UI2YG2KA.js.map → create-PYP3QWTL.js.map} +0 -0
- /package/dist/{creatives-QFSIIFXB.js.map → creatives-ANTJUTIE.js.map} +0 -0
- /package/dist/{critique-OK2ENBOA.js.map → critique-MZUTDK4V.js.map} +0 -0
- /package/dist/{delete-4CUEJZ2Z.js.map → delete-3H6YH4YK.js.map} +0 -0
- /package/dist/{feedback-ZBEZIIPT.js.map → feedback-TJRYTOR3.js.map} +0 -0
- /package/dist/{feedback-record-CZVSPZUR.js.map → feedback-record-7IAJI5IY.js.map} +0 -0
- /package/dist/{flows-CAOMVQYZ.js.map → flows-LL5SPPIK.js.map} +0 -0
- /package/dist/{funnel-LKF6D7AA.js.map → funnel-XIZROHV7.js.map} +0 -0
- /package/dist/{get-TB52FVNV.js.map → get-XPJ4BZGP.js.map} +0 -0
- /package/dist/{google-FZVOB7HW.js.map → google-5JV7OMOH.js.map} +0 -0
- /package/dist/{history-SJJX6EXI.js.map → history-RD2YMNNL.js.map} +0 -0
- /package/dist/{images-K7JQ3ORB.js.map → images-XP4TKE2F.js.map} +0 -0
- /package/dist/{inspiration-KAXPRINY.js.map → inspiration-D75DO3MD.js.map} +0 -0
- /package/dist/{landing-BFMRM3HA.js.map → landing-O2ZUIUGE.js.map} +0 -0
- /package/dist/{list-PT4DVD4U.js.map → list-OZCU2T22.js.map} +0 -0
- /package/dist/{lookup-IUQWU346.js.map → lookup-K57ITJWF.js.map} +0 -0
- /package/dist/{make-N5LVJSZD.js.map → make-T6HLXIYY.js.map} +0 -0
- /package/dist/{performance-6XFKDJGY.js.map → performance-MHJDRLEK.js.map} +0 -0
- /package/dist/{plan-VHMWZU7F.js.map → plan-JYSHKPZQ.js.map} +0 -0
- /package/dist/{posts-BDMC644W.js.map → posts-ILAFADBW.js.map} +0 -0
- /package/dist/{questionnaire-32BQ4ZUX.js.map → questionnaire-Y37I64FO.js.map} +0 -0
- /package/dist/{rerun-HUFJUOEV.js.map → rerun-UPDIXTEL.js.map} +0 -0
- /package/dist/{run-MRC4UVHU.js.map → run-4UIPMCSN.js.map} +0 -0
- /package/dist/{run-7OCCCNJ4.js.map → run-GACZDI6Q.js.map} +0 -0
- /package/dist/{scaffold-ad-7ADCDQBK.js.map → scaffold-ad-Z2HSN4PE.js.map} +0 -0
- /package/dist/{scaffold-static-ad-TV5OWISA.js.map → scaffold-static-ad-ODZGTIM5.js.map} +0 -0
- /package/dist/{scaffold-video-LLBDO546.js.map → scaffold-video-EHGAMEEP.js.map} +0 -0
- /package/dist/{scheduled-agents-EPPP4SCZ.js.map → scheduled-agents-4VY4CAA2.js.map} +0 -0
- /package/dist/{schema-5Q6VO5MW.js.map → schema-EYGPETLF.js.map} +0 -0
- /package/dist/{select-BRH4QLWU.js.map → select-FCQUYBKV.js.map} +0 -0
- /package/dist/{sends-43FU3SJN.js.map → sends-MZKHZZGJ.js.map} +0 -0
- /package/dist/{set-prompt-SYWNE4CS.js.map → set-prompt-IBAG6BDA.js.map} +0 -0
- /package/dist/{sources-CGXHNWJM.js.map → sources-K2LILGTW.js.map} +0 -0
- /package/dist/{sources-PUZ4WV4Q.js.map → sources-ZM7LEIMM.js.map} +0 -0
- /package/dist/{stale-QNIJZTGD.js.map → stale-VR5QAYB6.js.map} +0 -0
- /package/dist/{studio-NRWLXOFZ.js.map → studio-3D42TUJX.js.map} +0 -0
- /package/dist/{sync-definition-EGHEQ57K.js.map → sync-definition-MZUJOJYI.js.map} +0 -0
- /package/dist/{targets-3WIBMP4B.js.map → targets-LQ7HGI73.js.map} +0 -0
- /package/dist/{testimonials-2NQMY23B.js.map → testimonials-Z2KOOMVH.js.map} +0 -0
- /package/dist/{translate-YGHRSEX6.js.map → translate-II4JY2XW.js.map} +0 -0
- /package/dist/{triggers-6EXLTW35.js.map → triggers-Z3LV3KJR.js.map} +0 -0
- /package/dist/{unstage-YSVQ6DLB.js.map → unstage-AVLORZLW.js.map} +0 -0
- /package/dist/{unstage-KEMVI37X.js.map → unstage-QXOL5DXZ.js.map} +0 -0
- /package/dist/{update-USKR3UOC.js.map → update-UE4XVBKL.js.map} +0 -0
- /package/dist/{url-options-6MFRIDNA.js.map → url-options-DJZV3ADK.js.map} +0 -0
- /package/dist/{validate-JX4FT7PL.js.map → validate-BCK22BQL.js.map} +0 -0
- /package/dist/{videos-EHDZ46UQ.js.map → videos-YCQVOOFE.js.map} +0 -0
- /package/dist/{winning-ads-H7ZE5AQW.js.map → winning-ads-7X5EWSJX.js.map} +0 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiPost
|
|
3
|
+
} from "./chunk-B4UVJCJ4.js";
|
|
4
|
+
import "./chunk-AFQF6ISC.js";
|
|
5
|
+
import "./chunk-52IYZCRS.js";
|
|
6
|
+
import {
|
|
7
|
+
registerSchema,
|
|
8
|
+
writeJson
|
|
9
|
+
} from "./chunk-FSGJSREN.js";
|
|
10
|
+
import "./chunk-YQSBHWOI.js";
|
|
11
|
+
|
|
12
|
+
// src/commands/knowledge/index.ts
|
|
13
|
+
import { defineCommand as defineCommand2 } from "citty";
|
|
14
|
+
|
|
15
|
+
// src/commands/knowledge/search.ts
|
|
16
|
+
import { execFile } from "child_process";
|
|
17
|
+
import { promisify } from "util";
|
|
18
|
+
|
|
19
|
+
// ../api/src/knowledge.ts
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
var KNOWLEDGE_RANK_MAX_PASSAGES = 40;
|
|
22
|
+
var KNOWLEDGE_RANK_MAX_PASSAGE_CHARS = 4e3;
|
|
23
|
+
var knowledgeRankRequestSchema = z.object({
|
|
24
|
+
query: z.string().trim().min(1, "the question cannot be empty").max(2e3),
|
|
25
|
+
passages: z.array(z.string().max(KNOWLEDGE_RANK_MAX_PASSAGE_CHARS)).min(1).max(KNOWLEDGE_RANK_MAX_PASSAGES)
|
|
26
|
+
});
|
|
27
|
+
var knowledgeRankResponseSchema = z.object({
|
|
28
|
+
model: z.string(),
|
|
29
|
+
/** Every passage sent, best first. `index` points into the request's `passages`. */
|
|
30
|
+
ranking: z.array(z.object({ index: z.number().int().nonnegative(), score: z.number() }))
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// src/commands/knowledge/search.ts
|
|
34
|
+
import { defineCommand } from "citty";
|
|
35
|
+
import { z as z2 } from "zod";
|
|
36
|
+
var execFileAsync = promisify(execFile);
|
|
37
|
+
var QMD_TIMEOUT_MS = 9e4;
|
|
38
|
+
var PASSAGE_LINES = 70;
|
|
39
|
+
var SNIPPET_CHARS = 300;
|
|
40
|
+
var qmdRowSchema = z2.object({
|
|
41
|
+
file: z2.string(),
|
|
42
|
+
title: z2.string().optional(),
|
|
43
|
+
line: z2.number().int().optional(),
|
|
44
|
+
score: z2.number().default(0),
|
|
45
|
+
body: z2.string().default("")
|
|
46
|
+
});
|
|
47
|
+
function passageOf(body, line) {
|
|
48
|
+
const lines = body.split("\n");
|
|
49
|
+
const start = Math.max(0, (line ?? 1) - 1 - 5);
|
|
50
|
+
return lines.slice(start, start + PASSAGE_LINES).join("\n").slice(0, KNOWLEDGE_RANK_MAX_PASSAGE_CHARS);
|
|
51
|
+
}
|
|
52
|
+
function qmdQueryArgs(args) {
|
|
53
|
+
return [
|
|
54
|
+
"query",
|
|
55
|
+
args.question,
|
|
56
|
+
"--no-rerank",
|
|
57
|
+
"--json",
|
|
58
|
+
"--full",
|
|
59
|
+
"-n",
|
|
60
|
+
String(KNOWLEDGE_RANK_MAX_PASSAGES),
|
|
61
|
+
...args.collection ? ["-c", args.collection] : []
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
async function searchKnowledge(args, deps) {
|
|
65
|
+
const stdout = await deps.runQmd(qmdQueryArgs(args));
|
|
66
|
+
const rows = z2.array(qmdRowSchema).parse(JSON.parse(stdout));
|
|
67
|
+
if (rows.length === 0) {
|
|
68
|
+
return {
|
|
69
|
+
data: [],
|
|
70
|
+
meta: { count: 0, rankedBy: "qmd" },
|
|
71
|
+
hints: [
|
|
72
|
+
'Nothing in the vault answers this. Try an exact word with `qmd search "<word>"`, or check the collections with `qmd collection list`.'
|
|
73
|
+
]
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const passages = rows.map((row) => passageOf(row.body, row.line));
|
|
77
|
+
const ranked = await deps.rank({ query: args.question, passages }).catch(() => null);
|
|
78
|
+
const { model, ranking } = ranked ?? {
|
|
79
|
+
model: "qmd",
|
|
80
|
+
ranking: rows.map((row, index) => ({ index, score: row.score }))
|
|
81
|
+
};
|
|
82
|
+
const data = ranking.slice(0, args.limit).flatMap(({ index, score }) => {
|
|
83
|
+
const row = rows[index];
|
|
84
|
+
const passage = passages[index];
|
|
85
|
+
if (!row || passage === void 0) return [];
|
|
86
|
+
return [
|
|
87
|
+
{
|
|
88
|
+
file: row.file,
|
|
89
|
+
...row.title ? { title: row.title } : {},
|
|
90
|
+
...row.line ? { line: row.line } : {},
|
|
91
|
+
score: Math.round(score * 100) / 100,
|
|
92
|
+
snippet: passage.slice(0, SNIPPET_CHARS),
|
|
93
|
+
...args.full ? { passage } : {}
|
|
94
|
+
}
|
|
95
|
+
];
|
|
96
|
+
});
|
|
97
|
+
const hints = ranked ? [] : [
|
|
98
|
+
"Not ranked: the ranking model did not answer, so these are in qmd's own order. Read a few before trusting the first."
|
|
99
|
+
];
|
|
100
|
+
return { data, meta: { count: data.length, rankedBy: model }, hints };
|
|
101
|
+
}
|
|
102
|
+
var ARGS = {
|
|
103
|
+
question: {
|
|
104
|
+
type: "positional",
|
|
105
|
+
description: "The question, in plain words: what you want to know, not keywords",
|
|
106
|
+
required: true
|
|
107
|
+
},
|
|
108
|
+
collection: {
|
|
109
|
+
type: "string",
|
|
110
|
+
alias: "c",
|
|
111
|
+
description: "Only this qmd collection (names: qmd collection list)",
|
|
112
|
+
required: false
|
|
113
|
+
},
|
|
114
|
+
limit: {
|
|
115
|
+
type: "string",
|
|
116
|
+
alias: "n",
|
|
117
|
+
description: "Passages to return, 1-20 (default: 5)",
|
|
118
|
+
required: false
|
|
119
|
+
},
|
|
120
|
+
full: {
|
|
121
|
+
type: "boolean",
|
|
122
|
+
description: "Also return each passage's text (default: a 300-character snippet)",
|
|
123
|
+
required: false,
|
|
124
|
+
default: false
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
registerSchema({
|
|
128
|
+
command: "knowledge.search",
|
|
129
|
+
description: "Start here for a question about the company's Knowledge vault (src/content/): qmd finds the passages, a hosted model ranks them, best first, in about 10 seconds. Returns file (open it with `qmd get <file>`), line, score and a snippet. For an exact word, name or phrase use `qmd search` instead (instant).",
|
|
130
|
+
args: ARGS
|
|
131
|
+
});
|
|
132
|
+
function readLimit(raw) {
|
|
133
|
+
const limit = raw === void 0 ? 5 : Number(raw);
|
|
134
|
+
return Number.isInteger(limit) && limit >= 1 && limit <= 20 ? limit : 5;
|
|
135
|
+
}
|
|
136
|
+
var searchCommand = defineCommand({
|
|
137
|
+
meta: {
|
|
138
|
+
name: "search",
|
|
139
|
+
description: `Answer a question from the Knowledge vault: the best passages, ranked. Read-only, ~10 s.
|
|
140
|
+
|
|
141
|
+
Start here:
|
|
142
|
+
baker knowledge search "what budget did we start Meta prospecting with"
|
|
143
|
+
baker knowledge search "which hooks worked for retargeting" -c audits -n 10
|
|
144
|
+
|
|
145
|
+
Each hit: file (read it whole with \`qmd get <file>\`), line, score (0-1), snippet. --full adds the passage text.
|
|
146
|
+
For an exact word, name or phrase: \`qmd search "<words>"\` (instant).
|
|
147
|
+
Full guide: __tooling__/docs/tools/baker/knowledge.md`
|
|
148
|
+
},
|
|
149
|
+
args: ARGS,
|
|
150
|
+
run: async ({ args }) => {
|
|
151
|
+
try {
|
|
152
|
+
const { data, meta, hints } = await searchKnowledge(
|
|
153
|
+
{
|
|
154
|
+
question: String(args.question),
|
|
155
|
+
...typeof args.collection === "string" ? { collection: args.collection } : {},
|
|
156
|
+
limit: readLimit(args.limit),
|
|
157
|
+
full: args.full === true
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
runQmd: async (qmdArgs) => (await execFileAsync("qmd", qmdArgs, { timeout: QMD_TIMEOUT_MS, maxBuffer: 64 * 1024 * 1024 })).stdout,
|
|
161
|
+
rank: (request) => apiPost("/api/knowledge/rank", request, { timeoutMs: 2e4 })
|
|
162
|
+
}
|
|
163
|
+
);
|
|
164
|
+
writeJson({ ok: true, data, meta, ...hints.length > 0 ? { hints } : {} });
|
|
165
|
+
} catch (err) {
|
|
166
|
+
writeJson({
|
|
167
|
+
ok: false,
|
|
168
|
+
error: {
|
|
169
|
+
code: "UNAVAILABLE",
|
|
170
|
+
message: `The vault search did not run: ${err instanceof Error ? err.message.slice(0, 300) : "unknown error"}`,
|
|
171
|
+
fix: {
|
|
172
|
+
action: "degrade",
|
|
173
|
+
explanation: 'Search for an exact word instead with `qmd search "<word>"` (instant), or read the likely files under src/content/ directly. Do not retry in a loop.'
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// src/commands/knowledge/index.ts
|
|
183
|
+
var knowledgeCommand = defineCommand2({
|
|
184
|
+
meta: {
|
|
185
|
+
name: "knowledge",
|
|
186
|
+
description: "Search the company's Knowledge vault (src/content/): answers to a question, ranked best first."
|
|
187
|
+
},
|
|
188
|
+
subCommands: {
|
|
189
|
+
search: searchCommand
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
export {
|
|
193
|
+
knowledgeCommand
|
|
194
|
+
};
|
|
195
|
+
//# sourceMappingURL=knowledge-PKXPN4RV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/knowledge/index.ts","../src/commands/knowledge/search.ts","../../api/src/knowledge.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { searchCommand } from \"./search.ts\";\n\nexport const knowledgeCommand = defineCommand({\n meta: {\n name: \"knowledge\",\n description: \"Search the company's Knowledge vault (src/content/): answers to a question, ranked best first.\",\n },\n subCommands: {\n search: searchCommand,\n },\n});\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport {\n KNOWLEDGE_RANK_MAX_PASSAGE_CHARS,\n KNOWLEDGE_RANK_MAX_PASSAGES,\n type KnowledgeRankRequest,\n type KnowledgeRankResponse,\n} from \"@baker/api/knowledge\";\nimport { defineCommand } from \"citty\";\nimport { z } from \"zod\";\nimport { apiPost } from \"../../client.ts\";\nimport { writeJson } from \"../../output.ts\";\nimport { registerSchema } from \"../../schemas.ts\";\n\n/**\n * `baker knowledge search`: qmd finds the passages, a hosted model ranks them.\n *\n * qmd's own reranker runs a 0.6B model on the Runtime's CPU — about 200 tokens a\n * second, so two minutes for the ~30 passages of one question, past the 120 s\n * bound a shell command gets. qmd still expands the question and fuses keyword\n * and vector hits here (`--no-rerank`, ~8 s, cached per question); only the\n * ordering is sent to the backend's reranker, which answers in under a second.\n * Measured on 10 marketer questions over the playbooks: NDCG@5 0.47 for qmd's\n * fused order, 0.81 ranked here.\n */\n\nconst execFileAsync = promisify(execFile);\n\n/** qmd expands, embeds and fuses in ~8 s; a query still running at this point is hung, not slow. */\nconst QMD_TIMEOUT_MS = 90_000;\n/** Lines kept from a passage's start, about qmd's own 900-token chunk. */\nconst PASSAGE_LINES = 70;\nconst SNIPPET_CHARS = 300;\n\nconst qmdRowSchema = z.object({\n file: z.string(),\n title: z.string().optional(),\n line: z.number().int().optional(),\n score: z.number().default(0),\n body: z.string().default(\"\"),\n});\n\nexport interface KnowledgeHit {\n file: string;\n title?: string;\n line?: number;\n score: number;\n snippet: string;\n passage?: string;\n}\n\nexport interface SearchKnowledgeDeps {\n /** qmd's stdout for the given arguments. */\n runQmd: (args: string[]) => Promise<string>;\n rank: (request: KnowledgeRankRequest) => Promise<KnowledgeRankResponse>;\n}\n\nexport interface SearchKnowledgeArgs {\n question: string;\n collection?: string;\n limit: number;\n full: boolean;\n}\n\n/** The lines a hit stands for: from just above qmd's best-passage line. Pure. */\nfunction passageOf(body: string, line: number | undefined): string {\n const lines = body.split(\"\\n\");\n const start = Math.max(0, (line ?? 1) - 1 - 5);\n return lines\n .slice(start, start + PASSAGE_LINES)\n .join(\"\\n\")\n .slice(0, KNOWLEDGE_RANK_MAX_PASSAGE_CHARS);\n}\n\nfunction qmdQueryArgs(args: SearchKnowledgeArgs): string[] {\n return [\n \"query\",\n args.question,\n \"--no-rerank\",\n \"--json\",\n \"--full\",\n \"-n\",\n String(KNOWLEDGE_RANK_MAX_PASSAGES),\n ...(args.collection ? [\"-c\", args.collection] : []),\n ];\n}\n\nexport async function searchKnowledge(\n args: SearchKnowledgeArgs,\n deps: SearchKnowledgeDeps,\n): Promise<{ data: KnowledgeHit[]; meta: { count: number; rankedBy: string }; hints: string[] }> {\n const stdout = await deps.runQmd(qmdQueryArgs(args));\n const rows = z.array(qmdRowSchema).parse(JSON.parse(stdout));\n if (rows.length === 0) {\n return {\n data: [],\n meta: { count: 0, rankedBy: \"qmd\" },\n hints: [\n 'Nothing in the vault answers this. Try an exact word with `qmd search \"<word>\"`, or check the collections with `qmd collection list`.',\n ],\n };\n }\n const passages = rows.map((row) => passageOf(row.body, row.line));\n const ranked = await deps.rank({ query: args.question, passages }).catch(() => null);\n const { model, ranking } = ranked ?? {\n model: \"qmd\",\n ranking: rows.map((row, index) => ({ index, score: row.score })),\n };\n const data = ranking.slice(0, args.limit).flatMap(({ index, score }) => {\n const row = rows[index];\n const passage = passages[index];\n if (!row || passage === undefined) return [];\n return [\n {\n file: row.file,\n ...(row.title ? { title: row.title } : {}),\n ...(row.line ? { line: row.line } : {}),\n score: Math.round(score * 100) / 100,\n snippet: passage.slice(0, SNIPPET_CHARS),\n ...(args.full ? { passage } : {}),\n },\n ];\n });\n const hints = ranked\n ? []\n : [\n \"Not ranked: the ranking model did not answer, so these are in qmd's own order. Read a few before trusting the first.\",\n ];\n return { data, meta: { count: data.length, rankedBy: model }, hints };\n}\n\nconst ARGS = {\n question: {\n type: \"positional\",\n description: \"The question, in plain words: what you want to know, not keywords\",\n required: true,\n },\n collection: {\n type: \"string\",\n alias: \"c\",\n description: \"Only this qmd collection (names: qmd collection list)\",\n required: false,\n },\n limit: {\n type: \"string\",\n alias: \"n\",\n description: \"Passages to return, 1-20 (default: 5)\",\n required: false,\n },\n full: {\n type: \"boolean\",\n description: \"Also return each passage's text (default: a 300-character snippet)\",\n required: false,\n default: false,\n },\n} as const;\n\nregisterSchema({\n command: \"knowledge.search\",\n description:\n \"Start here for a question about the company's Knowledge vault (src/content/): qmd finds the passages, a hosted model ranks them, best first, in about 10 seconds. Returns file (open it with `qmd get <file>`), line, score and a snippet. For an exact word, name or phrase use `qmd search` instead (instant).\",\n args: ARGS,\n});\n\nfunction readLimit(raw: unknown): number {\n const limit = raw === undefined ? 5 : Number(raw);\n return Number.isInteger(limit) && limit >= 1 && limit <= 20 ? limit : 5;\n}\n\nexport const searchCommand = defineCommand({\n meta: {\n name: \"search\",\n description: `Answer a question from the Knowledge vault: the best passages, ranked. Read-only, ~10 s.\n\nStart here:\n baker knowledge search \"what budget did we start Meta prospecting with\"\n baker knowledge search \"which hooks worked for retargeting\" -c audits -n 10\n\nEach hit: file (read it whole with \\`qmd get <file>\\`), line, score (0-1), snippet. --full adds the passage text.\nFor an exact word, name or phrase: \\`qmd search \"<words>\"\\` (instant).\nFull guide: __tooling__/docs/tools/baker/knowledge.md`,\n },\n args: ARGS,\n run: async ({ args }) => {\n try {\n const { data, meta, hints } = await searchKnowledge(\n {\n question: String(args.question),\n ...(typeof args.collection === \"string\" ? { collection: args.collection } : {}),\n limit: readLimit(args.limit),\n full: args.full === true,\n },\n {\n runQmd: async (qmdArgs) =>\n (await execFileAsync(\"qmd\", qmdArgs, { timeout: QMD_TIMEOUT_MS, maxBuffer: 64 * 1024 * 1024 })).stdout,\n rank: (request) => apiPost<KnowledgeRankResponse>(\"/api/knowledge/rank\", request, { timeoutMs: 20_000 }),\n },\n );\n writeJson({ ok: true, data, meta, ...(hints.length > 0 ? { hints } : {}) });\n } catch (err) {\n writeJson({\n ok: false,\n error: {\n code: \"UNAVAILABLE\",\n message: `The vault search did not run: ${err instanceof Error ? err.message.slice(0, 300) : \"unknown error\"}`,\n fix: {\n action: \"degrade\",\n explanation:\n 'Search for an exact word instead with `qmd search \"<word>\"` (instant), or read the likely files under src/content/ directly. Do not retry in a loop.',\n },\n },\n });\n process.exit(1);\n }\n },\n});\n","/**\n * `baker knowledge search` — the wire contract for ranking the passages a\n * vault search found.\n *\n * The search itself runs in the Runtime (qmd, over the company's Knowledge);\n * only the ranking leaves it. qmd's own reranker is a CPU model that took two\n * minutes a question in a Runtime, so the passages qmd fused come here and a\n * hosted cross-encoder orders them in well under a second. Read-only.\n */\nimport { z } from \"zod\";\n\n/** qmd's fused candidates per question; more costs ranking time and returns nothing the top 5 would use. */\nexport const KNOWLEDGE_RANK_MAX_PASSAGES = 40;\n/** About 1,000 tokens: qmd's own chunk is 900. */\nexport const KNOWLEDGE_RANK_MAX_PASSAGE_CHARS = 4000;\n\nexport const knowledgeRankRequestSchema = z.object({\n query: z.string().trim().min(1, \"the question cannot be empty\").max(2000),\n passages: z.array(z.string().max(KNOWLEDGE_RANK_MAX_PASSAGE_CHARS)).min(1).max(KNOWLEDGE_RANK_MAX_PASSAGES),\n});\n\nexport type KnowledgeRankRequest = z.infer<typeof knowledgeRankRequestSchema>;\n\nexport const knowledgeRankResponseSchema = z.object({\n model: z.string(),\n /** Every passage sent, best first. `index` points into the request's `passages`. */\n ranking: z.array(z.object({ index: z.number().int().nonnegative(), score: z.number() })),\n});\n\nexport type KnowledgeRankResponse = z.infer<typeof knowledgeRankResponseSchema>;\n"],"mappings":"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","names":["defineCommand","z","z","defineCommand"]}
|
|
@@ -16,7 +16,7 @@ Subcommands:
|
|
|
16
16
|
baker landing export start \u2014 download the PUBLISHED landings as a ZIP of plain HTML ("download my landings", "send me the HTML"); \`baker landing export status <id>\` gives the link.`
|
|
17
17
|
},
|
|
18
18
|
subCommands: {
|
|
19
|
-
inspiration: () => import("./inspiration-
|
|
19
|
+
inspiration: () => import("./inspiration-D75DO3MD.js").then((m) => m.inspirationCommand),
|
|
20
20
|
critique: () => import("./critique-GWRXVXVG.js").then((m) => m.critiqueCommand),
|
|
21
21
|
variant: () => import("./variant-JQVZUUA4.js").then((m) => m.variantCommand),
|
|
22
22
|
export: () => import("./export-6Z6QBU6V.js").then((m) => m.exportCommand)
|
|
@@ -25,4 +25,4 @@ Subcommands:
|
|
|
25
25
|
export {
|
|
26
26
|
landingCommand
|
|
27
27
|
};
|
|
28
|
-
//# sourceMappingURL=landing-
|
|
28
|
+
//# sourceMappingURL=landing-O2ZUIUGE.js.map
|