@stjbrown/agent-knowledge 0.1.0-beta.1 → 0.1.0-beta.10
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/NOTICE +5 -4
- package/OBSERVABILITY.md +163 -0
- package/README.md +74 -8
- package/dist/chunk-JZ3GYPHM.js +3993 -0
- package/dist/chunk-JZ3GYPHM.js.map +1 -0
- package/dist/{chunk-J4MELCGD.js → chunk-X6R3XLAQ.js} +19 -6
- package/dist/chunk-X6R3XLAQ.js.map +1 -0
- package/dist/headless.js +2 -2
- package/dist/index.js +2 -2
- package/dist/main.js +7 -18
- package/dist/main.js.map +1 -1
- package/dist/tui-74FJW5Y4.js +1519 -0
- package/dist/tui-74FJW5Y4.js.map +1 -0
- package/package.json +27 -15
- package/skills/kb/SKILL.md +5 -0
- package/skills/kb/example-bundle/spec/types.md +3 -2
- package/skills/kb-ingest/SKILL.md +27 -6
- package/skills/kb-init/SKILL.md +23 -5
- package/skills/kb-lint/SKILL.md +6 -1
- package/dist/chunk-3XSOMUQQ.js +0 -131
- package/dist/chunk-3XSOMUQQ.js.map +0 -1
- package/dist/chunk-J4MELCGD.js.map +0 -1
- package/dist/chunk-YIAVFL7A.js +0 -1732
- package/dist/chunk-YIAVFL7A.js.map +0 -1
- package/dist/tui-VZVO7UHV.js +0 -521
- package/dist/tui-VZVO7UHV.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tui/index.ts","../src/memory/compact.ts","../src/tui/activity.ts","../src/tui/interrupt.ts","../src/tui/multi-select.ts","../src/tui/thread.ts","../src/tui/traces.ts","../src/tui/theme.ts"],"sourcesContent":["/**\n * Janet's interactive TUI — a minimal pi-tui chat.\n *\n * The transcript renders in strict chronological order: each run of assistant\n * text becomes its own markdown block, and a tool line / question / approval\n * \"closes\" the current block so the next text appears BELOW it (rather than the\n * whole answer streaming at the top while tools pile up underneath).\n *\n * Approvals are governed by the controller's tool-category policy: reads,\n * skills, task bookkeeping, ask_user, and bundle edits never prompt. Execution,\n * MCP, and unknown future tools ask — and the prompt offers \"always allow\" for\n * the session. Questions with options render as an arrow-key SelectList.\n */\nimport {\n Container,\n Editor,\n Loader,\n Markdown,\n ProcessTerminal,\n SelectList,\n Spacer,\n TUI,\n Text,\n matchesKey,\n} from \"@earendil-works/pi-tui\";\nimport type { Component, SelectItem } from \"@earendil-works/pi-tui\";\nimport type { AgentControllerEvent } from \"@mastra/core/agent-controller\";\nimport type { Memory } from \"@mastra/memory\";\nimport { bootJanet, type BootOptions } from \"../agent/controller.js\";\nimport { messageText } from \"../headless/format.js\";\nimport { GREETING } from \"../agent/persona.js\";\nimport { getAuthStorage } from \"../gateways/oauth/claude-max.js\";\nimport {\n completeOnboarding,\n loadSettings,\n rememberModel,\n rememberObservability,\n} from \"../onboarding/settings.js\";\nimport {\n NATIVE_PROVIDER_DEFINITIONS,\n availableModels,\n discoverAvailableModels,\n groupModelsByProvider,\n normalizeModelSelection,\n type ModelChoice,\n type ProviderModelGroup,\n} from \"../onboarding/providers.js\";\nimport { resolveObservabilityConfig } from \"../observability/config.js\";\nimport {\n formatObservabilityStatus,\n safeObservabilityEndpoint,\n} from \"../observability/runtime.js\";\nimport type {\n ObservabilityCaptureMode,\n ObservabilitySettings,\n} from \"../observability/types.js\";\nimport { compactConversation } from \"../memory/compact.js\";\nimport { toolActivityLabel, toolErrorLabel } from \"./activity.js\";\nimport { createInterruptController, type InterruptResult } from \"./interrupt.js\";\nimport { MultiSelectList } from \"./multi-select.js\";\nimport { clearConversation } from \"./thread.js\";\nimport { formatTraceTree, traceStatus } from \"./traces.js\";\nimport { c, editorTheme, markdownTheme } from \"./theme.js\";\n\n/** OAuth providers janet can log in to. */\nconst OAUTH_PROVIDERS = [\"anthropic\", \"openai-codex\"] as const;\n\nconst HELP_TEXT = `Commands:\n /models Pick one or more providers, then a model\n /model [provider/id] Open the picker, or switch directly by id\n /providers Browse provider status and setup\n /login <provider> [mode]\n Log in; OpenAI mode is browser or device\n /logout <provider> Remove stored credentials for a provider\n /auth Show which providers are authenticated\n /observability Configure opt-in tracing\n /traces Browse recent local traces\n /compact Flush this conversation into Observational Memory\n /clear Start a blank conversation (keeps the old thread)\n /cancel Cancel the active run\n /help This help\n /quit Exit (double Ctrl+C also works)\n\nWhile Janet is working, Esc or Ctrl+C cancels the active run.\nAnything else is a message to Janet.`;\n\ninterface PendingApproval {\n toolCallId: string;\n toolName: string;\n}\n\ninterface QuestionOption {\n label: string;\n description?: string;\n}\n\ninterface PendingQuestion {\n toolCallId: string;\n options?: QuestionOption[];\n multi: boolean;\n}\n\n/** The assistant text block currently being streamed (one segment between tools). */\ninterface ActiveMessage {\n id: string;\n committedLen: number;\n comp: Markdown | null;\n lastText: string;\n}\n\ntype OMWindows = Extract<\n AgentControllerEvent,\n { type: \"om_status\" }\n>[\"windows\"];\n\nfunction shortTokens(tokens: number): string {\n if (tokens < 1_000) return String(Math.max(0, Math.round(tokens)));\n const thousands = tokens / 1_000;\n return `${thousands >= 10 ? Math.round(thousands) : thousands.toFixed(1)}k`;\n}\n\n/** Map a typed answer to ask_user resume data (free-text or multi-select). */\nfunction resolveAnswer(q: PendingQuestion, text: string): string | string[] | undefined {\n if (!q.options?.length) return text;\n const opts = q.options;\n const pick = (token: string): string | undefined => {\n const t = token.trim();\n if (!t) return undefined;\n const n = Number(t);\n if (Number.isInteger(n) && n >= 1 && n <= opts.length) return opts[n - 1]!.label;\n const exact = opts.find((o) => o.label.toLowerCase() === t.toLowerCase());\n if (exact) return exact.label;\n return opts.find((o) => o.label.toLowerCase().startsWith(t.toLowerCase()))?.label;\n };\n if (q.multi) {\n const picks = text.split(\",\").map(pick);\n return picks.some((p) => p === undefined) ? undefined : (picks as string[]);\n }\n return pick(text);\n}\n\nexport async function runTui(opts: Omit<BootOptions, \"interactive\">): Promise<number> {\n const { controller, session, paths, herdrDetach, observability } = await bootJanet({\n ...opts,\n interactive: true,\n });\n\n // The interactive approval policy is set deterministically in the controller's\n // initialState (reads/edits/meta never prompt; only execute asks, with an\n // \"always allow\" option) — see INTERACTIVE_RULES in controller.ts.\n\n // Model precedence: an already-persisted per-thread selection, else\n // JANET_MODEL, else the global onboarding default. If none, the first-run\n // wizard runs after the UI is up.\n const persistedModel = process.env[\"JANET_MODEL\"] || loadSettings().defaultModelId;\n const presetModel = persistedModel\n ? normalizeModelSelection(persistedModel, availableModels())\n : undefined;\n if (!session.model.hasSelection() && presetModel) {\n await session.model.switch({ modelId: presetModel });\n }\n\n const terminal = new ProcessTerminal();\n const ui = new TUI(terminal);\n const chat = new Container();\n const status = new Text(\"\", 1, 0);\n const editor = new Editor(ui, editorTheme);\n const loader = new Loader(ui, c.accent, c.dim, \"Janet is thinking…\");\n\n ui.addChild(chat);\n ui.addChild(new Spacer(1));\n ui.addChild(editor);\n ui.addChild(status);\n\n let running = false;\n let loaderMounted = false;\n let pendingApproval: PendingApproval | null = null;\n let pendingQuestion: PendingQuestion | null = null;\n let pendingInput: ((text: string) => void) | null = null;\n let activeSelect: SelectList | MultiSelectList | null = null;\n let active: ActiveMessage | null = null;\n let cancelRequested = false;\n let modelPickerLoading = false;\n let compacting = false;\n let omWindows: OMWindows | null = null;\n let omActivity: \"observing\" | \"reflecting\" | null = null;\n const activeTools = new Map<string, string>();\n\n const updateStatus = (): void => {\n const model = session.model.hasSelection() ? session.model.get() : \"no model — /model <id>\";\n const tracing = observability.status.enabled\n ? c.dim(` · trace:${observability.status.capture}`)\n : \"\";\n const memory = omWindows\n ? c.dim(\n ` · mem:${shortTokens(\n omWindows.active.messages.tokens +\n omWindows.active.observations.tokens,\n )}/${shortTokens(\n omWindows.active.messages.threshold +\n omWindows.active.observations.threshold,\n )}`,\n )\n : \"\";\n const state =\n pendingInput\n ? \"enter the requested value\"\n : compacting\n ? \"compacting memory\"\n : omActivity\n ? `${omActivity} memory`\n : pendingQuestion || activeSelect\n ? \"answer Janet's question\"\n : pendingApproval\n ? \"awaiting approval\"\n : cancelRequested\n ? \"cancelling\"\n : running\n ? \"working · Esc/Ctrl+C cancels\"\n : \"idle\";\n status.setText(\n c.dim(`${paths.projectPath} · `) +\n c.accent(model) +\n c.dim(` · ${state}`) +\n memory +\n tracing,\n );\n ui.requestRender();\n };\n\n // Keep the spinner (and any focused select) visually last by inserting new\n // content before them.\n const appendToChat = (comp: Component): void => {\n if (loaderMounted) chat.removeChild(loader);\n if (activeSelect) chat.removeChild(activeSelect);\n chat.addChild(comp);\n if (activeSelect) chat.addChild(activeSelect);\n if (loaderMounted) chat.addChild(loader);\n ui.requestRender();\n };\n\n const addLine = (text: string): void => appendToChat(new Text(text, 1, 0));\n\n const setLoader = (on: boolean): void => {\n if (on && !loaderMounted) {\n chat.addChild(loader);\n loader.start();\n loaderMounted = true;\n } else if (!on && loaderMounted) {\n loader.stop();\n chat.removeChild(loader);\n loaderMounted = false;\n }\n ui.requestRender();\n };\n\n // Freeze the current text segment so the next assistant text starts a new\n // block below whatever we're about to insert (a tool line, question, etc.).\n const closeSegment = (): void => {\n if (active) {\n active.committedLen = active.lastText.length;\n active.comp = null;\n }\n };\n\n const answerQuestion = (resumeData: string | string[], echo: string): void => {\n if (activeSelect) {\n chat.removeChild(activeSelect);\n activeSelect = null;\n }\n const q = pendingQuestion;\n pendingQuestion = null;\n ui.setFocus(editor);\n addLine(c.user(`❯ ${echo}`));\n setLoader(true);\n updateStatus();\n if (q) void session.respondToToolSuspension({ toolCallId: q.toolCallId, resumeData });\n };\n\n const onEvent = (event: AgentControllerEvent): void => {\n switch (event.type) {\n case \"agent_start\":\n running = true;\n cancelRequested = false;\n active = null;\n activeTools.clear();\n loader.setMessage(\"Janet is thinking…\");\n setLoader(true);\n updateStatus();\n break;\n case \"message_update\":\n case \"message_end\": {\n if (event.message.role !== \"assistant\") break;\n const text = messageText(event.message);\n if (!text) break;\n if (!active || active.id !== event.message.id) {\n active = { id: event.message.id, committedLen: 0, comp: null, lastText: \"\" };\n }\n active.lastText = text;\n const tail = text.slice(active.committedLen);\n if (!tail) break;\n if (!active.comp) {\n active.comp = new Markdown(tail, 1, 0, markdownTheme);\n appendToChat(active.comp);\n } else {\n active.comp.setText(tail);\n ui.requestRender();\n }\n break;\n }\n case \"tool_start\":\n closeSegment();\n if (event.toolName !== \"ask_user\") {\n activeTools.set(event.toolCallId, event.toolName);\n loader.setMessage(toolActivityLabel(event.toolName));\n }\n break;\n case \"tool_end\":\n activeTools.delete(event.toolCallId);\n loader.setMessage(\n activeTools.size\n ? toolActivityLabel(Array.from(activeTools.values()).at(-1)!)\n : \"Janet is thinking…\",\n );\n if (event.isError) {\n closeSegment();\n addLine(c.warn(` ${toolErrorLabel(event.result)}`));\n }\n break;\n case \"tool_suspended\": {\n closeSegment();\n activeTools.delete(event.toolCallId);\n setLoader(false);\n const payload = event.suspendPayload as {\n question?: string;\n options?: QuestionOption[];\n selectionMode?: string;\n };\n const question = payload?.question ?? `Janet needs input for ${event.toolName}.`;\n const options = payload?.options;\n const multi = payload?.selectionMode === \"multi_select\";\n addLine(c.accentBold(` Janet asks: ${question}`));\n\n if (options?.length && !multi) {\n // Arrow-key selection (↑/↓, enter), like a native picker.\n const items: SelectItem[] = options.map((o) => ({\n value: o.label,\n label: o.label,\n ...(o.description ? { description: o.description } : {}),\n }));\n const select = new SelectList(items, Math.min(items.length, 8), editorTheme.selectList);\n select.onSelect = (item: SelectItem) => answerQuestion(item.value, item.label);\n select.onCancel = () => {\n closeActiveSelect(select);\n addLine(c.dim(\" Picker closed. Type your answer instead.\"));\n updateStatus();\n };\n activeSelect = select;\n pendingQuestion = { toolCallId: event.toolCallId, options, multi: false };\n chat.addChild(select);\n addLine(c.dim(\" Use ↑/↓ and Enter · Esc to close.\"));\n ui.setFocus(select);\n } else {\n pendingQuestion = { toolCallId: event.toolCallId, options, multi };\n if (options?.length) {\n options.forEach((o, i) =>\n addLine(c.accent(` ${i + 1}. `) + o.label + (o.description ? c.dim(` — ${o.description}`) : \"\")),\n );\n addLine(c.dim(\" Reply with numbers or labels, then press Enter.\"));\n } else {\n addLine(c.dim(\" Type your answer, then press Enter.\"));\n }\n }\n updateStatus();\n break;\n }\n case \"tool_approval_required\":\n closeSegment();\n activeTools.delete(event.toolCallId);\n pendingApproval = { toolCallId: event.toolCallId, toolName: event.toolName };\n addLine(\n c.warn(` Janet wants to run ${c.bold(event.toolName)}.`) +\n c.dim(\" y = yes · n = no · a = always allow this kind\"),\n );\n updateStatus();\n break;\n case \"error\": {\n closeSegment();\n const err = event.error as Error & { responseBody?: string };\n addLine(\n c.error(` Error: ${err?.message || \"unknown\"}${err?.responseBody ? ` — ${err.responseBody.slice(0, 200)}` : \"\"}`),\n );\n break;\n }\n case \"model_changed\":\n updateStatus();\n break;\n case \"om_status\":\n omWindows = event.windows;\n updateStatus();\n break;\n case \"om_buffering_start\":\n omActivity =\n event.operationType === \"reflection\" ? \"reflecting\" : \"observing\";\n updateStatus();\n break;\n case \"om_observation_start\":\n case \"om_reflection_start\":\n omActivity =\n event.type === \"om_reflection_start\" ||\n event.operationType === \"reflection\"\n ? \"reflecting\"\n : \"observing\";\n updateStatus();\n break;\n case \"om_buffering_end\":\n case \"om_observation_end\":\n case \"om_reflection_end\":\n omActivity = null;\n updateStatus();\n break;\n case \"om_buffering_failed\":\n case \"om_observation_failed\":\n case \"om_reflection_failed\":\n omActivity = null;\n closeSegment();\n addLine(\n c.warn(\n ` Memory ${\n event.type === \"om_buffering_failed\"\n ? `${event.operationType} buffering`\n : event.type === \"om_reflection_failed\"\n ? \"reflection\"\n : \"observation\"\n } failed: ${event.error}`,\n ),\n );\n updateStatus();\n break;\n case \"om_activation\":\n omActivity = null;\n closeSegment();\n addLine(\n c.dim(\n ` Memory compacted ${shortTokens(event.tokensActivated)} into ` +\n `${shortTokens(event.observationTokens)} observation tokens.`,\n ),\n );\n updateStatus();\n break;\n case \"agent_end\":\n running = false;\n cancelRequested = false;\n activeTools.clear();\n loader.setMessage(\"Janet is thinking…\");\n if (event.reason !== \"suspended\") pendingQuestion = null;\n setLoader(false);\n updateStatus();\n break;\n }\n };\n const unsubscribe = session.subscribe(onEvent);\n let removeInputListener = (): void => {};\n let sigintHandler: (() => void) | undefined;\n\n const shutdown = async (code: number): Promise<never> => {\n removeInputListener();\n if (sigintHandler) process.off(\"SIGINT\", sigintHandler);\n unsubscribe();\n herdrDetach();\n ui.stop();\n await observability.flush().catch(() => {});\n await controller.destroy().catch(() => {});\n process.exit(code);\n };\n\n const notifyInterrupt = (result: Exclude<InterruptResult, \"ignored\">): void => {\n switch (result) {\n case \"cancelled\":\n addLine(c.dim(\" Cancelling the active run…\"));\n break;\n case \"cleared\":\n break;\n case \"exit\":\n break;\n case \"exit-hint\":\n addLine(c.dim(\" Press Ctrl+C again to quit.\"));\n break;\n }\n updateStatus();\n };\n\n const abortActiveRun = (): void => {\n if (cancelRequested) return;\n cancelRequested = true;\n pendingApproval = null;\n pendingQuestion = null;\n activeTools.clear();\n if (activeSelect) {\n chat.removeChild(activeSelect);\n activeSelect = null;\n }\n ui.setFocus(editor);\n loader.setMessage(\"Cancelling…\");\n session.abort();\n };\n\n const interrupts = createInterruptController({\n isRunning: () => running,\n hasInput: () => editor.getText().length > 0,\n abortRun: abortActiveRun,\n clearInput: () => {\n editor.setText(\"\");\n ui.requestRender();\n },\n exit: () => {\n void shutdown(0);\n },\n notify: notifyInterrupt,\n });\n\n // Input listeners run before the focused component, so cancellation works\n // during pickers, approvals, questions, and streamed tool activity.\n removeInputListener = ui.addInputListener((data) => {\n if (matchesKey(data, \"ctrl+c\")) {\n interrupts.handleCtrlC();\n return { consume: true };\n }\n // A focused picker owns Escape, even when it represents a suspended\n // in-flight question. Ctrl+C remains the explicit \"cancel the run\" path.\n if (matchesKey(data, \"escape\") && activeSelect) {\n return undefined;\n }\n if (matchesKey(data, \"escape\") && running) {\n interrupts.handleEscape();\n return { consume: true };\n }\n return undefined;\n });\n\n // Raw terminals normally deliver Ctrl+C as input. Keep a SIGINT fallback for\n // terminals and supervisors that preserve normal signal handling.\n sigintHandler = () => {\n interrupts.handleCtrlC();\n };\n process.on(\"SIGINT\", sigintHandler);\n\n // Ask the user for one value; the next editor submit resolves it. Used by the\n // OAuth login flow (paste-code / prompts).\n const promptInput = (message: string, placeholder?: string): Promise<string> => {\n addLine(c.accentBold(` ${message}`));\n if (placeholder) addLine(c.dim(` (${placeholder})`));\n return new Promise((resolve) => {\n pendingInput = resolve;\n updateStatus();\n });\n };\n\n const closeActiveSelect = (\n select: SelectList | MultiSelectList,\n ): void => {\n chat.removeChild(select);\n if (activeSelect === select) activeSelect = null;\n ui.setFocus(editor);\n };\n\n const selectModel = async (modelId: string): Promise<void> => {\n try {\n await session.model.switch({ modelId });\n completeOnboarding(modelId, new Date().toISOString());\n rememberModel(modelId);\n addLine(c.accentBold(` ✓ Using ${modelId}.`) + c.dim(\" (saved as your default)\"));\n } catch (error) {\n addLine(c.error(` Could not select ${modelId}: ${(error as Error).message}`));\n } finally {\n updateStatus();\n }\n };\n\n const showProviderModels = (\n groups: ProviderModelGroup[],\n allChoices: ModelChoice[],\n ): void => {\n const current = session.model.hasSelection() ? session.model.get() : null;\n const available = groups.flatMap((group) =>\n group.models.map((choice) => ({ choice, group })),\n );\n const currentChoice = available.find(({ choice }) => choice.id === current);\n const ordered = currentChoice\n ? [currentChoice, ...available.filter(({ choice }) => choice.id !== current)]\n : available;\n // Large gateways can expose hundreds of models. Keep the arrow list useful\n // and always offer an exact model-id entry path.\n const visible = ordered.slice(0, 29);\n const items: SelectItem[] = visible.map(({ choice, group }) => ({\n value: choice.id,\n label:\n groups.length > 1\n ? `${group.label}: ${choice.label}${choice.id === current ? \" (current)\" : \"\"}`\n : `${choice.label}${choice.id === current ? \" (current)\" : \"\"}`,\n description: choice.id,\n }));\n items.push({\n value: \"__janet_enter_model_id__\",\n label: \"Enter another model ID…\",\n description:\n ordered.length > visible.length\n ? `${ordered.length - visible.length} more catalog models; enter the exact id`\n : groups.length === 1\n ? `Use any ${groups[0]!.id}/model supported by Mastra`\n : \"Use any provider/model supported by Mastra\",\n });\n\n addLine(\n c.accentBold(\n groups.length === 1\n ? ` ${groups[0]!.label} models`\n : ` Models from ${groups.length} providers`,\n ),\n );\n addLine(c.dim(\" ↑/↓ to move · Enter to choose · Esc to go back:\"));\n const select = new SelectList(\n items,\n Math.min(items.length, 10),\n editorTheme.selectList,\n );\n select.onSelect = (item: SelectItem) => {\n closeActiveSelect(select);\n if (item.value === \"__janet_enter_model_id__\") {\n void promptInput(\n groups.length === 1\n ? `Model id for ${groups[0]!.label}:`\n : \"Full model id:\",\n groups.length === 1\n ? `${groups[0]!.id}/model-name`\n : \"provider/model-name\",\n ).then((input) => {\n const modelId =\n groups.length === 1 && !input.includes(\"/\")\n ? `${groups[0]!.id}/${input}`\n : normalizeModelSelection(\n input,\n available.map(({ choice }) => choice),\n );\n void selectModel(modelId);\n });\n return;\n }\n void selectModel(item.value);\n };\n select.onCancel = () => {\n closeActiveSelect(select);\n showProviderPicker(allChoices);\n };\n activeSelect = select;\n chat.addChild(select);\n ui.setFocus(select);\n updateStatus();\n };\n\n const showProviderPicker = (choices: ModelChoice[]): void => {\n const groups = groupModelsByProvider(choices);\n if (!groups.length) {\n addLine(c.dim(\" No providers are configured yet. Set one up, then try again:\"));\n addLine(c.dim(\" • Vertex AI: gcloud auth application-default login (+ GOOGLE_VERTEX_PROJECT)\"));\n addLine(c.dim(\" • Anthropic: set ANTHROPIC_API_KEY, or /login anthropic\"));\n addLine(c.dim(\" • OpenAI: set OPENAI_API_KEY, or /login openai-codex\"));\n addLine(c.dim(\" • Bedrock: configure AWS credentials\"));\n addLine(c.dim(\" • More: /providers lists native Mastra environment variables\"));\n updateStatus();\n return;\n }\n\n addLine(\n c.dim(\n \" ↑/↓ to move · Space to toggle · Enter to view models · Esc to close:\",\n ),\n );\n const select = new MultiSelectList(\n groups.map((group) => ({\n value: group.id,\n label: group.label,\n description: `${group.models.length} model${group.models.length === 1 ? \"\" : \"s\"} · ${group.via}`,\n })),\n Math.min(groups.length, 10),\n editorTheme.selectList,\n groups.map((group) => group.id),\n );\n select.onConfirm = (items: SelectItem[]) => {\n if (!items.length) {\n addLine(c.warn(\" Select at least one provider.\"));\n return;\n }\n closeActiveSelect(select);\n const selectedIds = new Set(items.map((item) => item.value));\n showProviderModels(\n groups.filter((group) => selectedIds.has(group.id)),\n choices,\n );\n };\n select.onCancel = () => closeActiveSelect(select);\n activeSelect = select;\n chat.addChild(select);\n ui.setFocus(select);\n updateStatus();\n };\n\n // Mastra supplies the native provider catalog and auth status. Janet layers\n // its ADC/AWS/OAuth choices over that catalog and retains local fallbacks for\n // offline startup.\n const showModelPicker = (intro?: string): void => {\n if (modelPickerLoading) {\n addLine(c.dim(\" The provider catalog is already loading.\"));\n return;\n }\n if (intro) addLine(c.accentBold(intro));\n addLine(c.dim(\" Loading configured providers…\"));\n modelPickerLoading = true;\n updateStatus();\n void discoverAvailableModels(() => controller.listAvailableModels())\n .then(showProviderPicker)\n .catch((error: Error) => {\n addLine(c.error(` Could not load providers: ${error.message}`));\n showProviderPicker(availableModels());\n })\n .finally(() => {\n modelPickerLoading = false;\n updateStatus();\n });\n };\n\n const showProviders = (): void => {\n if (running) {\n addLine(c.dim(\" Cancel the active run before opening provider setup.\"));\n return;\n }\n addLine(c.accentBold(\" Model providers\"));\n addLine(c.dim(\" Loading provider status…\"));\n void discoverAvailableModels(() => controller.listAvailableModels()).then((choices) => {\n const groups = groupModelsByProvider(choices);\n const groupsById = new Map(groups.map((group) => [group.id, group]));\n const known = [\n {\n id: \"vertex\",\n label: \"Google Vertex AI\",\n setup: \"Run gcloud auth application-default login and set GOOGLE_VERTEX_PROJECT.\",\n },\n {\n id: \"amazon-bedrock\",\n label: \"Amazon Bedrock\",\n setup: \"Configure an AWS credential chain and region.\",\n },\n ...NATIVE_PROVIDER_DEFINITIONS.map((provider) => ({\n id: provider.id,\n label: provider.label,\n setup: `Set ${provider.envVars.join(\" or \")}.`,\n })),\n ];\n const knownIds = new Set(known.map((provider) => provider.id));\n const providers = [\n ...known,\n ...groups\n .filter((group) => !knownIds.has(group.id))\n .map((group) => ({\n id: group.id,\n label: group.label,\n setup: \"This provider was discovered through Mastra.\",\n })),\n ];\n\n addLine(\n c.dim(\n \" ↑/↓ to move · Space to select providers · Enter for details · Esc to close:\",\n ),\n );\n const select = new MultiSelectList(\n providers.map((provider) => {\n const group = groupsById.get(provider.id);\n return {\n value: provider.id,\n label: provider.label,\n description: group ? `Ready · ${group.via}` : provider.setup,\n };\n }),\n Math.min(providers.length, 12),\n editorTheme.selectList,\n );\n select.onConfirm = (items: SelectItem[]) => {\n if (!items.length) {\n addLine(c.warn(\" Select at least one provider, or press Esc to close.\"));\n return;\n }\n closeActiveSelect(select);\n addLine(c.accentBold(\" Provider details\"));\n for (const item of items) {\n const provider = providers.find((candidate) => candidate.id === item.value);\n const group = groupsById.get(item.value);\n if (!provider) continue;\n if (group) {\n addLine(\n c.accent(` ✓ ${provider.label}`) +\n c.dim(` — ready via ${group.via}`),\n );\n continue;\n }\n addLine(c.bold(` ${provider.label}`) + c.dim(` — ${provider.setup}`));\n if (provider.id === \"anthropic\") {\n addLine(c.dim(\" Or use /login anthropic for a Claude subscription.\"));\n } else if (provider.id === \"openai\") {\n addLine(c.dim(\" Or use /login openai-codex for a ChatGPT subscription.\"));\n }\n }\n addLine(c.dim(\" Reopen /providers at any time; /models shows providers ready now.\"));\n updateStatus();\n };\n select.onCancel = () => closeActiveSelect(select);\n activeSelect = select;\n chat.addChild(select);\n ui.setFocus(select);\n updateStatus();\n }).catch((error: Error) => {\n addLine(c.error(` Could not load provider status: ${error.message}`));\n updateStatus();\n });\n };\n\n const savedObservabilitySummary = (): string => {\n const saved = loadSettings().observability;\n const resolved = resolveObservabilityConfig(saved, {});\n return formatObservabilityStatus({\n enabled: resolved.enabled,\n capture: resolved.capture,\n sampleRate: resolved.sampleRate,\n destinations: [\n ...(resolved.local.enabled ? [\"local\"] : []),\n ...(resolved.remote\n ? [\n resolved.remote.kind === \"phoenix\"\n ? `phoenix (${safeObservabilityEndpoint(resolved.remote.endpoint)})`\n : `otlp (${safeObservabilityEndpoint(resolved.remote.endpoint)})`,\n ]\n : []),\n ],\n warnings: resolved.warnings,\n });\n };\n\n const persistObservability = (settings: ObservabilitySettings): void => {\n rememberObservability(settings);\n addLine(c.accentBold(\" ✓ Observability settings saved.\"));\n addLine(c.dim(` Saved: ${savedObservabilitySummary()}`));\n addLine(c.dim(\" Restart Janet to apply the new setting.\"));\n updateStatus();\n };\n\n const confirmFullCapture = (\n base: Omit<ObservabilitySettings, \"capture\">,\n ): void => {\n addLine(\n c.warn(\n \" Full capture includes prompts, responses, and tool payloads. Do not use it with sensitive material.\",\n ),\n );\n addLine(c.dim(\" ↑/↓ to move · Enter to choose · Esc to go back:\"));\n const select = new SelectList(\n [\n {\n value: \"no\",\n label: \"Keep metadata-only capture\",\n description: \"Recommended. Content stays out of traces.\",\n },\n {\n value: \"yes\",\n label: \"Enable full capture\",\n description: \"I understand trace content may contain sensitive data.\",\n },\n ],\n 2,\n editorTheme.selectList,\n );\n select.onSelect = (item: SelectItem) => {\n closeActiveSelect(select);\n persistObservability({\n ...base,\n capture: item.value === \"yes\" ? \"full\" : \"metadata\",\n });\n };\n select.onCancel = () => {\n closeActiveSelect(select);\n chooseCaptureMode(base);\n };\n activeSelect = select;\n chat.addChild(select);\n ui.setFocus(select);\n updateStatus();\n };\n\n const chooseCaptureMode = (\n base: Omit<ObservabilitySettings, \"capture\">,\n ): void => {\n addLine(c.accentBold(\" What may Janet include in traces?\"));\n addLine(c.dim(\" ↑/↓ to move · Enter to choose · Esc to go back:\"));\n const select = new SelectList(\n [\n {\n value: \"metadata\",\n label: \"Metadata only\",\n description: \"Timing, tool names, model, tokens, status, and errors.\",\n },\n {\n value: \"full\",\n label: \"Full content\",\n description: \"Also includes prompts, responses, and tool payloads.\",\n },\n ],\n 2,\n editorTheme.selectList,\n );\n select.onSelect = (item: SelectItem) => {\n closeActiveSelect(select);\n const capture = item.value as ObservabilityCaptureMode;\n if (capture === \"full\") {\n confirmFullCapture(base);\n } else {\n persistObservability({ ...base, capture });\n }\n };\n select.onCancel = () => {\n closeActiveSelect(select);\n showObservabilityPicker();\n };\n activeSelect = select;\n chat.addChild(select);\n ui.setFocus(select);\n updateStatus();\n };\n\n const showObservabilityPicker = (): void => {\n if (running) {\n addLine(c.dim(\" Cancel the active run before changing observability settings.\"));\n return;\n }\n addLine(c.accentBold(\" Configure observability\"));\n addLine(c.dim(` Active now: ${formatObservabilityStatus(observability.status)}`));\n addLine(c.dim(\" Tracing is opt-in and changes apply after restart.\"));\n addLine(c.dim(\" ↑/↓ to move · Enter to choose · Esc to close:\"));\n const select = new SelectList(\n [\n {\n value: \"off\",\n label: \"Off\",\n description: \"No spans, trace database, or network export.\",\n },\n {\n value: \"local\",\n label: \"Local trace history\",\n description: \"Store traces in ~/.agent-knowledge/observability.db.\",\n },\n {\n value: \"phoenix\",\n label: \"Phoenix\",\n description: \"Send OTLP traces to http://localhost:6006.\",\n },\n {\n value: \"otlp\",\n label: \"Custom OTLP\",\n description: \"Send OTLP/HTTP protobuf traces to your endpoint.\",\n },\n ],\n 4,\n editorTheme.selectList,\n );\n select.onSelect = (item: SelectItem) => {\n closeActiveSelect(select);\n if (item.value === \"off\") {\n persistObservability({\n capture: \"off\",\n sampleRate: 1,\n local: { enabled: false, retentionDays: 7 },\n });\n return;\n }\n if (item.value === \"local\") {\n chooseCaptureMode({\n sampleRate: 1,\n local: { enabled: true, retentionDays: 7 },\n });\n return;\n }\n if (item.value === \"phoenix\") {\n chooseCaptureMode({\n sampleRate: 1,\n local: { enabled: false, retentionDays: 7 },\n remote: {\n kind: \"phoenix\",\n endpoint: \"http://localhost:6006\",\n projectName: \"janet\",\n },\n });\n return;\n }\n void promptInput(\n \"OTLP endpoint (for example, http://localhost:4318):\",\n ).then((endpoint) => {\n try {\n const parsed = new URL(endpoint);\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") throw new Error();\n if (parsed.username || parsed.password || parsed.search || parsed.hash) {\n addLine(\n c.error(\n \" Do not put credentials or query parameters in the saved endpoint. Use OTEL_EXPORTER_OTLP_HEADERS.\",\n ),\n );\n return;\n }\n } catch {\n addLine(c.error(\" Endpoint must be a valid HTTP or HTTPS URL.\"));\n return;\n }\n chooseCaptureMode({\n sampleRate: 1,\n local: { enabled: false, retentionDays: 7 },\n remote: {\n kind: \"otlp\",\n endpoint,\n },\n });\n });\n };\n select.onCancel = () => closeActiveSelect(select);\n activeSelect = select;\n chat.addChild(select);\n ui.setFocus(select);\n updateStatus();\n };\n\n const showLocalTraces = async (): Promise<void> => {\n if (running) {\n addLine(c.dim(\" Cancel the active run before browsing traces.\"));\n return;\n }\n if (!observability.config.local.enabled) {\n addLine(c.dim(\" Local trace history is not active. Use /observability to enable it.\"));\n return;\n }\n await observability.flush().catch(() => {});\n const store = await observability.storage.getStore(\"observability\");\n if (!store) {\n addLine(c.error(\" Local trace storage is unavailable.\"));\n return;\n }\n const recent = await store.listTraces({\n pagination: { page: 0, perPage: 10 },\n orderBy: { field: \"startedAt\", direction: \"DESC\" },\n });\n if (!recent.spans.length) {\n addLine(c.dim(\" No local traces yet.\"));\n return;\n }\n\n addLine(c.accentBold(\" Recent local traces\"));\n addLine(c.dim(\" ↑/↓ to move · Enter to open · Esc to close:\"));\n const select = new SelectList(\n recent.spans.map((span) => {\n const state = traceStatus(span);\n const marker = state === \"error\" ? \"✗\" : state === \"running\" ? \"…\" : \"✓\";\n return {\n value: span.traceId,\n label: `${marker} ${span.name}`,\n description: `${span.startedAt.toLocaleString()} · ${span.traceId}`,\n };\n }),\n Math.min(recent.spans.length, 10),\n editorTheme.selectList,\n );\n select.onSelect = (item: SelectItem) => {\n closeActiveSelect(select);\n void store.getTrace({ traceId: item.value }).then((trace) => {\n if (!trace) {\n addLine(c.error(` Trace not found: ${item.value}`));\n return;\n }\n addLine(c.accentBold(` Trace ${trace.traceId}`));\n for (const line of formatTraceTree(trace.spans)) {\n addLine(c.dim(` ${line}`));\n }\n }).catch((error: Error) => {\n addLine(c.error(` Could not read trace: ${error.message}`));\n });\n };\n select.onCancel = () => closeActiveSelect(select);\n activeSelect = select;\n chat.addChild(select);\n ui.setFocus(select);\n updateStatus();\n };\n\n const handleCommand = async (text: string): Promise<void> => {\n const [cmd, ...rest] = text.slice(1).split(/\\s+/);\n switch (cmd) {\n case \"quit\":\n case \"exit\":\n await shutdown(0);\n break;\n case \"help\":\n addLine(c.dim(HELP_TEXT));\n break;\n case \"cancel\":\n if (interrupts.handleEscape() === \"ignored\") {\n addLine(c.dim(\" No active run to cancel.\"));\n }\n break;\n case \"clear\":\n if (running || compacting) {\n addLine(c.dim(\" Wait for the active work to finish before clearing the conversation.\"));\n break;\n }\n try {\n await clearConversation(session.thread);\n active = null;\n activeTools.clear();\n omWindows = null;\n omActivity = null;\n chat.clear();\n addLine(c.accentBold(GREETING));\n addLine(c.accentBold(\" ✓ Conversation cleared.\"));\n addLine(c.dim(` Knowledge bundle: ${paths.bundlePath}`));\n addLine(c.dim(\" The previous conversation is still saved as a separate thread.\"));\n } catch (error) {\n addLine(c.error(` Could not clear the conversation: ${(error as Error).message}`));\n } finally {\n updateStatus();\n }\n break;\n case \"compact\": {\n if (running || compacting) {\n addLine(c.dim(\" Wait for the active work to finish before compacting memory.\"));\n break;\n }\n if (!session.model.hasSelection()) {\n addLine(c.dim(\" Pick a model before compacting memory.\"));\n break;\n }\n const threadId = session.thread.getId();\n if (!threadId) {\n addLine(c.dim(\" There is no active conversation to compact.\"));\n break;\n }\n\n compacting = true;\n loader.setMessage(\"Janet is compacting memory…\");\n setLoader(true);\n updateStatus();\n try {\n const requestContext = await session.machinery.buildRequestContext();\n const agent = controller.getCurrentAgent(session);\n const memory = await agent.getMemory({ requestContext });\n if (!memory) throw new Error(\"Janet memory is unavailable.\");\n const result = await compactConversation({\n memory: memory as Memory,\n agent,\n threadId,\n resourceId: session.identity.getResourceId(),\n requestContext,\n });\n if (!result.buffered && !result.activated && !result.reflected) {\n addLine(c.dim(\" Memory is already compact.\"));\n } else {\n const reflected = result.reflected ? \" and reflected\" : \"\";\n addLine(\n c.accentBold(\n ` ✓ Compacted ~${result.pendingTokensBefore.toLocaleString()} message tokens into ` +\n `~${result.observationTokens.toLocaleString()} memory tokens${reflected}.`,\n ),\n );\n addLine(c.dim(\" Raw messages remain available to Janet through memory recall.\"));\n }\n } catch (error) {\n addLine(c.error(` Could not compact memory: ${(error as Error).message}`));\n } finally {\n compacting = false;\n loader.setMessage(\"Janet is thinking…\");\n setLoader(false);\n updateStatus();\n }\n break;\n }\n case \"observability\": {\n const action = rest[0]?.trim().toLowerCase();\n if (action === \"status\") {\n addLine(c.dim(` Active: ${formatObservabilityStatus(observability.status)}`));\n addLine(c.dim(` Saved: ${savedObservabilitySummary()}`));\n } else if (action === \"off\") {\n persistObservability({\n capture: \"off\",\n sampleRate: 1,\n local: { enabled: false, retentionDays: 7 },\n });\n } else if (!action) {\n showObservabilityPicker();\n } else {\n addLine(c.dim(\"Usage: /observability [status | off]\"));\n }\n break;\n }\n case \"traces\":\n await showLocalTraces();\n break;\n case \"login\": {\n const providerId = (rest[0] || \"anthropic\").trim();\n if (!(OAUTH_PROVIDERS as readonly string[]).includes(providerId)) {\n addLine(c.dim(`Usage: /login <${OAUTH_PROVIDERS.join(\" | \")}>`));\n break;\n }\n const authMode = rest[1]?.trim();\n if (\n authMode &&\n (providerId !== \"openai-codex\" || ![\"browser\", \"device\"].includes(authMode))\n ) {\n addLine(c.dim(\"Usage: /login openai-codex [browser | device]\"));\n break;\n }\n addLine(c.dim(`Starting ${providerId} login…`));\n try {\n await getAuthStorage().login(providerId, {\n onAuth: (info) => {\n addLine(c.accent(\" Open this URL in your browser to authorize:\"));\n addLine(\" \" + info.url);\n if (info.instructions) addLine(c.dim(\" \" + info.instructions));\n },\n onProgress: (m) => addLine(c.dim(\" \" + m)),\n onManualCodeInput: () => promptInput(\"Paste the code shown after you authorize:\"),\n onPrompt: (p) => promptInput(p.message, p.placeholder),\n ...(authMode ? { authMode } : {}),\n });\n addLine(c.accentBold(` ✓ Logged in to ${providerId}.`));\n updateStatus();\n } catch (err) {\n addLine(c.error(` Login failed: ${(err as Error).message}`));\n } finally {\n // A successful browser callback can win the race with the manual-code\n // prompt. Disarm that abandoned prompt so it cannot consume the next\n // chat message after login completes.\n pendingInput = null;\n updateStatus();\n }\n break;\n }\n case \"logout\": {\n const providerId = rest[0]?.trim();\n if (!providerId) {\n addLine(c.dim(`Usage: /logout <${OAUTH_PROVIDERS.join(\" | \")}>`));\n break;\n }\n const storage = getAuthStorage();\n storage.logout(providerId); // OAuth credential\n storage.remove(`apikey:${providerId}`); // stored API key slot, if any\n addLine(c.dim(`Logged out of ${providerId}.`));\n break;\n }\n case \"auth\": {\n const storage = getAuthStorage();\n storage.reload();\n const providers = storage.list();\n if (!providers.length) {\n addLine(c.dim(\"No stored credentials. Use /login <provider>, or set an API key env var\"));\n addLine(c.dim(\"(ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_VERTEX_PROJECT, AWS_*).\"));\n } else {\n for (const p of providers) {\n const cred = storage.get(p);\n addLine(c.dim(` ${p}: `) + (cred?.type === \"oauth\" ? c.accent(\"OAuth (subscription)\") : \"API key\"));\n }\n }\n break;\n }\n case \"model\": {\n const inputId = rest.join(\" \").trim();\n // No id → open the picker; an explicit id still works for power users.\n if (!inputId) {\n showModelPicker();\n break;\n }\n const id = normalizeModelSelection(inputId, availableModels());\n await selectModel(id);\n break;\n }\n case \"models\":\n showModelPicker();\n break;\n case \"providers\":\n showProviders();\n break;\n default:\n addLine(c.dim(`Unknown command /${cmd}. Try /help.`));\n }\n };\n\n editor.onSubmit = (raw: string) => {\n const text = raw.trim();\n editor.setText(\"\");\n if (!text) return;\n\n // Feed normal prompt input (messages + slash commands) into the editor's\n // built-in up/down history. Skip transient responses — approvals, question\n // answers, and paste-codes shouldn't clutter recall.\n if (!pendingInput && !pendingApproval && !pendingQuestion) {\n editor.addToHistory(text);\n }\n\n // A requested value (e.g. an OAuth paste-code) consumes the next submit.\n // Don't echo it verbatim — it may be a credential.\n if (pendingInput) {\n const resolve = pendingInput;\n pendingInput = null;\n addLine(c.dim(\" ❯ (value entered)\"));\n updateStatus();\n resolve(text);\n return;\n }\n\n // A typed question (free-text or multi-select) consumes the next submit.\n if (pendingQuestion && !activeSelect) {\n const resumeData = resolveAnswer(pendingQuestion, text);\n if (resumeData === undefined) {\n addLine(c.dim(\" Didn't match an option — reply with a number or an exact label.\"));\n return;\n }\n answerQuestion(resumeData, Array.isArray(resumeData) ? resumeData.join(\", \") : resumeData);\n return;\n }\n\n // Pending tool approval: y / n / a (always allow this category).\n if (pendingApproval) {\n const approve = /^y(es)?$/i.test(text);\n const decline = /^n(o)?$/i.test(text);\n const always = /^a(lways)?$/i.test(text);\n if (approve || decline || always) {\n const { toolCallId } = pendingApproval;\n pendingApproval = null;\n addLine(c.dim(always ? \" ✓ always allowed\" : approve ? \" ✓ approved\" : \" ✗ declined\"));\n updateStatus();\n void session.respondToToolApproval({\n decision: always ? \"always_allow_category\" : approve ? \"approve\" : \"decline\",\n toolCallId,\n });\n return;\n }\n addLine(c.dim(\" Answer y (yes), n (no), or a (always allow) first.\"));\n return;\n }\n\n if (compacting) {\n addLine(c.dim(\" Janet is still compacting memory; try again in a moment.\"));\n return;\n }\n\n if (text.startsWith(\"/\")) {\n void handleCommand(text);\n return;\n }\n\n addLine(c.user(`❯ ${text}`));\n if (!session.model.hasSelection()) {\n showModelPicker(\" Pick a model first:\");\n return;\n }\n void session.sendMessage({\n content: text,\n tracingOptions: observability.tracingOptionsForTurn({\n interactive: true,\n operation: \"chat\",\n resourceId: paths.resourceId,\n threadId: session.thread.getId() ?? undefined,\n }),\n }).catch((err: Error) => {\n running = false;\n setLoader(false);\n addLine(c.error(` ✗ ${err.message}`));\n updateStatus();\n });\n };\n\n addLine(c.accentBold(GREETING));\n addLine(\n c.dim(\n `Knowledge bundle: ${paths.bundlePath}\\n` +\n `Ask me anything in the bundle, or say what to ingest. /help for commands.`,\n ),\n );\n for (const warning of observability.status.warnings) {\n addLine(c.warn(`Observability: ${warning}`));\n }\n updateStatus();\n ui.start();\n ui.setFocus(editor);\n ui.requestRender();\n\n // First run (no model configured): open the picker to get set up.\n if (!session.model.hasSelection()) showModelPicker(\" Let's pick a model to get you started.\");\n\n // The TUI owns the process from here; exit happens via shutdown().\n return await new Promise<number>(() => {});\n}\n","import type { Agent } from \"@mastra/core/agent\";\nimport type { RequestContext } from \"@mastra/core/di\";\nimport type { Memory } from \"@mastra/memory\";\n\nexport interface CompactConversationOptions {\n memory: Memory;\n agent: Agent;\n threadId: string;\n resourceId: string;\n requestContext: RequestContext;\n}\n\nexport interface CompactConversationResult {\n pendingTokensBefore: number;\n pendingTokensAfter: number;\n observationTokens: number;\n buffered: boolean;\n activated: boolean;\n reflected: boolean;\n}\n\n/**\n * Flush the current thread into the same OM record used by automatic\n * observation. Nothing is deleted: retrieval-mode ranges retain links back to\n * the raw messages, while the next agent step receives observations plus the\n * remaining unobserved tail.\n */\nexport async function compactConversation({\n memory,\n agent,\n threadId,\n resourceId,\n requestContext,\n}: CompactConversationOptions): Promise<CompactConversationResult> {\n const om = await memory.omEngine;\n if (!om) {\n throw new Error(\"Observational Memory is unavailable for this storage.\");\n }\n\n await om.waitForBuffering(threadId, resourceId);\n const before = await om.getStatus({ threadId, resourceId });\n\n let buffered = false;\n if (before.pendingTokens > 0) {\n const result = await om.buffer({\n threadId,\n resourceId,\n requestContext,\n agent,\n pendingTokens: before.pendingTokens,\n record: before.record,\n skipMinimumTokenCheck: true,\n });\n buffered = result.buffered;\n }\n\n await om.waitForBuffering(threadId, resourceId);\n const activation = await om.activate({\n threadId,\n resourceId,\n checkThreshold: false,\n });\n\n const afterActivation = await om.getStatus({ threadId, resourceId });\n let reflected = false;\n let record = activation.record;\n if (afterActivation.shouldReflect) {\n const reflection = await om.reflect(\n threadId,\n resourceId,\n undefined,\n requestContext,\n );\n reflected = reflection.reflected;\n record = reflection.record;\n }\n\n const after = await om.getStatus({ threadId, resourceId });\n return {\n pendingTokensBefore: before.pendingTokens,\n pendingTokensAfter: after.pendingTokens,\n observationTokens: record.observationTokenCount,\n buffered,\n activated: activation.activated,\n reflected,\n };\n}\n","const WORKSPACE_READ = new Set([\n \"mastra_workspace_file_stat\",\n \"mastra_workspace_grep\",\n \"mastra_workspace_lsp_inspect\",\n \"mastra_workspace_list_files\",\n \"mastra_workspace_read_file\",\n \"mastra_workspace_search\",\n]);\n\nconst WORKSPACE_WRITE = new Set([\n \"mastra_workspace_ast_edit\",\n \"mastra_workspace_delete\",\n \"mastra_workspace_edit_file\",\n \"mastra_workspace_index\",\n \"mastra_workspace_mkdir\",\n \"mastra_workspace_write_file\",\n]);\n\nconst WORKSPACE_EXECUTE = new Set([\n \"mastra_workspace_execute_command\",\n \"mastra_workspace_get_process_output\",\n \"mastra_workspace_kill_process\",\n]);\n\nconst PDF_READ = new Set([\"janet_read_pdf\", \"janet_read_pdf_chunk\"]);\nconst WEB_READ = new Set([\"janet_web_fetch\", \"janet_web_fetch_chunk\"]);\n\n/** Friendly transient status for routine tool work. */\nexport function toolActivityLabel(toolName: string): string {\n if (toolName === \"skill\" || toolName === \"skill_read\" || toolName === \"skill_search\") {\n return \"Janet is reading the playbook…\";\n }\n if (PDF_READ.has(toolName)) return \"Janet is reading the document…\";\n if (WEB_READ.has(toolName)) return \"Janet is reading the page…\";\n if (WORKSPACE_READ.has(toolName)) return \"Janet is checking the workspace…\";\n if (WORKSPACE_WRITE.has(toolName)) return \"Janet is updating the bundle…\";\n if (WORKSPACE_EXECUTE.has(toolName) || toolName.includes(\"shell\")) {\n return \"Janet is running a check…\";\n }\n return \"Janet is working…\";\n}\n\n/** Turn recoverable workspace guard failures into useful user-facing status. */\nexport function toolErrorLabel(result: unknown): string {\n const detail = String(result);\n const readRequired = detail.match(\n /File \"([^\"]+)\" (?:has not been read|was modified since last read)/,\n );\n if (readRequired) {\n return `Update paused: Janet needs to re-read \"${readRequired[1]}\" first.`;\n }\n return `Tool error: ${detail.slice(0, 140)}`;\n}\n","export type InterruptResult =\n | \"cancelled\"\n | \"cleared\"\n | \"exit\"\n | \"exit-hint\"\n | \"ignored\";\n\nexport interface InterruptActions {\n isRunning(): boolean;\n hasInput(): boolean;\n abortRun(): void;\n clearInput(): void;\n exit(): void;\n notify(result: Exclude<InterruptResult, \"ignored\">): void;\n}\n\nexport interface InterruptController {\n handleCtrlC(): InterruptResult;\n handleEscape(): InterruptResult;\n}\n\n/**\n * Centralize Janet's interrupt behavior so it works independently of whichever\n * TUI component currently owns keyboard focus.\n */\nexport function createInterruptController(\n actions: InterruptActions,\n options: {\n doublePressMs?: number;\n now?: () => number;\n } = {},\n): InterruptController {\n const doublePressMs = options.doublePressMs ?? 800;\n const now = options.now ?? Date.now;\n let lastCtrlC: number | undefined;\n\n const cancelRun = (): InterruptResult => {\n if (!actions.isRunning()) return \"ignored\";\n actions.abortRun();\n actions.notify(\"cancelled\");\n return \"cancelled\";\n };\n\n return {\n handleCtrlC(): InterruptResult {\n const pressedAt = now();\n if (lastCtrlC !== undefined && pressedAt - lastCtrlC < doublePressMs) {\n actions.notify(\"exit\");\n actions.exit();\n return \"exit\";\n }\n lastCtrlC = pressedAt;\n\n const cancelled = cancelRun();\n if (cancelled !== \"ignored\") return cancelled;\n\n if (actions.hasInput()) {\n actions.clearInput();\n actions.notify(\"cleared\");\n return \"cleared\";\n }\n\n actions.notify(\"exit-hint\");\n return \"exit-hint\";\n },\n\n handleEscape(): InterruptResult {\n return cancelRun();\n },\n };\n}\n","import {\n getKeybindings,\n matchesKey,\n truncateToWidth,\n visibleWidth,\n} from \"@earendil-works/pi-tui\";\nimport type {\n Component,\n SelectItem,\n SelectListTheme,\n} from \"@earendil-works/pi-tui\";\n\n/**\n * Minimal checkbox picker that follows pi-tui's SelectList keybindings and\n * visual language. pi-tui does not currently ship a multi-select component.\n */\nexport class MultiSelectList implements Component {\n private selectedIndex = 0;\n private readonly selectedValues: Set<string>;\n\n onConfirm?: (items: SelectItem[]) => void;\n onCancel?: () => void;\n\n constructor(\n private readonly items: SelectItem[],\n private readonly maxVisible: number,\n private readonly theme: SelectListTheme,\n initiallySelected: ReadonlyArray<string> = [],\n ) {\n this.selectedValues = new Set(initiallySelected);\n }\n\n setSelectedIndex(index: number): void {\n this.selectedIndex = Math.max(0, Math.min(index, this.items.length - 1));\n }\n\n getSelectedItems(): SelectItem[] {\n return this.items.filter((item) => this.selectedValues.has(item.value));\n }\n\n invalidate(): void {\n // No cached rendering state.\n }\n\n render(width: number): string[] {\n if (!this.items.length) {\n return [this.theme.noMatch(\" No options\")];\n }\n\n const startIndex = Math.max(\n 0,\n Math.min(\n this.selectedIndex - Math.floor(this.maxVisible / 2),\n this.items.length - this.maxVisible,\n ),\n );\n const endIndex = Math.min(\n startIndex + Math.max(1, this.maxVisible),\n this.items.length,\n );\n const lines = this.items\n .slice(startIndex, endIndex)\n .map((item, offset) =>\n this.renderItem(item, startIndex + offset === this.selectedIndex, width),\n );\n\n if (startIndex > 0 || endIndex < this.items.length) {\n lines.push(\n this.theme.scrollInfo(\n truncateToWidth(\n ` (${this.selectedIndex + 1}/${this.items.length})`,\n Math.max(1, width - 2),\n \"\",\n ),\n ),\n );\n }\n return lines;\n }\n\n handleInput(keyData: string): void {\n const keybindings = getKeybindings();\n if (!this.items.length) {\n if (keybindings.matches(keyData, \"tui.select.cancel\")) this.onCancel?.();\n return;\n }\n\n if (keybindings.matches(keyData, \"tui.select.up\")) {\n this.selectedIndex =\n this.selectedIndex === 0 ? this.items.length - 1 : this.selectedIndex - 1;\n } else if (keybindings.matches(keyData, \"tui.select.down\")) {\n this.selectedIndex =\n this.selectedIndex === this.items.length - 1 ? 0 : this.selectedIndex + 1;\n } else if (keybindings.matches(keyData, \"tui.select.pageUp\")) {\n this.selectedIndex = Math.max(0, this.selectedIndex - this.maxVisible);\n } else if (keybindings.matches(keyData, \"tui.select.pageDown\")) {\n this.selectedIndex = Math.min(\n this.items.length - 1,\n this.selectedIndex + this.maxVisible,\n );\n } else if (matchesKey(keyData, \"space\")) {\n const item = this.items[this.selectedIndex]!;\n if (this.selectedValues.has(item.value)) {\n this.selectedValues.delete(item.value);\n } else {\n this.selectedValues.add(item.value);\n }\n } else if (keybindings.matches(keyData, \"tui.select.confirm\")) {\n this.onConfirm?.(this.getSelectedItems());\n } else if (keybindings.matches(keyData, \"tui.select.cancel\")) {\n this.onCancel?.();\n }\n }\n\n private renderItem(item: SelectItem, isActive: boolean, width: number): string {\n const checked = this.selectedValues.has(item.value);\n const prefix = isActive ? \"→ \" : \" \";\n const checkbox = checked ? \"[x]\" : \"[ ]\";\n const maxWidth = Math.max(1, width - 2);\n const primary = truncateToWidth(\n `${prefix}${checkbox} ${item.label || item.value}`,\n maxWidth,\n \"\",\n );\n\n let plain = primary;\n if (item.description && width > 40) {\n const remaining = maxWidth - visibleWidth(primary) - 2;\n if (remaining > 10) {\n plain += ` ${truncateToWidth(\n item.description.replace(/[\\r\\n]+/g, \" \").trim(),\n remaining,\n \"\",\n )}`;\n }\n }\n\n if (isActive) return this.theme.selectedText(plain);\n if (!checked) return plain;\n\n const markStart = prefix.length;\n return (\n plain.slice(0, markStart) +\n this.theme.selectedPrefix(checkbox) +\n plain.slice(markStart + checkbox.length)\n );\n }\n}\n","export interface JanetThreadBinding {\n getId(): string | null;\n create(args?: { title?: string }): Promise<{ id: string }>;\n}\n\nexport interface ClearedConversation {\n previousThreadId: string | null;\n threadId: string;\n}\n\n/**\n * Start a blank conversation without deleting the previous thread.\n *\n * Mastra's thread lifecycle carries the selected model into the new thread,\n * releases the previous lock, resets usage, and rebinds the agent stream.\n */\nexport async function clearConversation(\n thread: JanetThreadBinding,\n): Promise<ClearedConversation> {\n const previousThreadId = thread.getId();\n const created = await thread.create({ title: \"Janet conversation\" });\n return { previousThreadId, threadId: created.id };\n}\n","export interface TraceSpanSummary {\n spanId: string;\n parentSpanId?: string | null;\n name: string;\n spanType: string;\n startedAt: Date;\n endedAt?: Date | null;\n error?: unknown;\n}\n\nfunction duration(span: TraceSpanSummary): string {\n if (!span.endedAt) return \"running\";\n const elapsed = Math.max(0, span.endedAt.getTime() - span.startedAt.getTime());\n return elapsed >= 1_000 ? `${(elapsed / 1_000).toFixed(1)}s` : `${elapsed}ms`;\n}\n\nexport function traceStatus(span: TraceSpanSummary): \"error\" | \"running\" | \"ok\" {\n if (span.error) return \"error\";\n return span.endedAt ? \"ok\" : \"running\";\n}\n\n/** Render Mastra's flat span records as a compact, content-free tree. */\nexport function formatTraceTree(spans: TraceSpanSummary[]): string[] {\n const byParent = new Map<string | null, TraceSpanSummary[]>();\n const ids = new Set(spans.map((span) => span.spanId));\n for (const span of spans) {\n const parent =\n span.parentSpanId && ids.has(span.parentSpanId) ? span.parentSpanId : null;\n const children = byParent.get(parent) ?? [];\n children.push(span);\n byParent.set(parent, children);\n }\n for (const children of byParent.values()) {\n children.sort((a, b) => a.startedAt.getTime() - b.startedAt.getTime());\n }\n\n const lines: string[] = [];\n const visited = new Set<string>();\n const visit = (span: TraceSpanSummary, depth: number): void => {\n if (visited.has(span.spanId)) return;\n visited.add(span.spanId);\n const status = traceStatus(span);\n const marker = status === \"error\" ? \"✗\" : status === \"running\" ? \"…\" : \"✓\";\n lines.push(\n `${\" \".repeat(depth)}${marker} ${span.name} · ${span.spanType} · ${duration(span)}`,\n );\n for (const child of byParent.get(span.spanId) ?? []) visit(child, depth + 1);\n };\n\n for (const root of byParent.get(null) ?? []) visit(root, 0);\n return lines;\n}\n","import chalk from \"chalk\";\nimport type { EditorTheme } from \"@earendil-works/pi-tui\";\n\n/**\n * Janet's minimal terminal theme. Good Place warm: cyan accents, soft dims.\n * Kept tiny on purpose — no gradients, no branding machinery.\n */\nexport const c = {\n accent: chalk.cyan,\n accentBold: chalk.cyan.bold,\n dim: chalk.dim,\n user: chalk.green,\n error: chalk.red,\n warn: chalk.yellow,\n bold: chalk.bold,\n italic: chalk.italic,\n};\n\nexport const editorTheme: EditorTheme = {\n borderColor: (s: string) => chalk.cyan(s),\n selectList: {\n selectedPrefix: (s: string) => chalk.cyan(s),\n selectedText: (s: string) => chalk.cyan.bold(s),\n description: (s: string) => chalk.dim(s),\n scrollInfo: (s: string) => chalk.dim(s),\n noMatch: (s: string) => chalk.dim(s),\n },\n};\n\nexport const markdownTheme = {\n heading: (s: string) => chalk.cyan.bold(s),\n link: (s: string) => chalk.cyan.underline(s),\n linkUrl: (s: string) => chalk.dim(s),\n code: (s: string) => chalk.yellow(s),\n codeBlock: (s: string) => chalk.yellow(s),\n codeBlockBorder: (s: string) => chalk.dim(s),\n quote: (s: string) => chalk.italic(s),\n quoteBorder: (s: string) => chalk.dim(s),\n hr: (s: string) => chalk.dim(s),\n listBullet: (s: string) => chalk.cyan(s),\n bold: (s: string) => chalk.bold(s),\n italic: (s: string) => chalk.italic(s),\n strikethrough: (s: string) => chalk.strikethrough(s),\n underline: (s: string) => chalk.underline(s),\n};\n"],"mappings":"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","names":["matchesKey","matchesKey"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stjbrown/agent-knowledge",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.10",
|
|
4
4
|
"description": "Janet builds and maintains portable LLM wikis in plain Markdown using OKF.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -32,11 +32,12 @@
|
|
|
32
32
|
"dist",
|
|
33
33
|
"skills",
|
|
34
34
|
"README.md",
|
|
35
|
+
"OBSERVABILITY.md",
|
|
35
36
|
"LICENSE",
|
|
36
37
|
"NOTICE"
|
|
37
38
|
],
|
|
38
39
|
"engines": {
|
|
39
|
-
"node": ">=22"
|
|
40
|
+
"node": ">=22.13.0"
|
|
40
41
|
},
|
|
41
42
|
"scripts": {
|
|
42
43
|
"build": "tsup",
|
|
@@ -45,25 +46,36 @@
|
|
|
45
46
|
"test": "vitest run"
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|
|
48
|
-
"@ai-sdk/amazon-bedrock": "
|
|
49
|
-
"@ai-sdk/anthropic": "
|
|
50
|
-
"@ai-sdk/google-vertex": "
|
|
51
|
-
"@ai-sdk/openai": "
|
|
52
|
-
"@ai-sdk/openai-compatible": "
|
|
53
|
-
"@aws-sdk/credential-providers": "
|
|
49
|
+
"@ai-sdk/amazon-bedrock": "4.0.143",
|
|
50
|
+
"@ai-sdk/anthropic": "3.0.103",
|
|
51
|
+
"@ai-sdk/google-vertex": "4.0.173",
|
|
52
|
+
"@ai-sdk/openai": "3.0.85",
|
|
53
|
+
"@ai-sdk/openai-compatible": "2.0.61",
|
|
54
|
+
"@aws-sdk/credential-providers": "3.1088.0",
|
|
54
55
|
"@earendil-works/pi-tui": "0.80.6",
|
|
55
|
-
"@mastra/core": "
|
|
56
|
-
"@mastra/libsql": "
|
|
57
|
-
"@mastra/memory": "
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
56
|
+
"@mastra/core": "1.51.0",
|
|
57
|
+
"@mastra/libsql": "1.16.0",
|
|
58
|
+
"@mastra/memory": "1.23.0",
|
|
59
|
+
"@mastra/observability": "1.16.2",
|
|
60
|
+
"@mastra/otel-exporter": "1.3.5",
|
|
61
|
+
"@mozilla/readability": "0.6.0",
|
|
62
|
+
"@opentelemetry/exporter-trace-otlp-proto": "0.218.0",
|
|
63
|
+
"ai": "6.0.228",
|
|
64
|
+
"chalk": "5.6.2",
|
|
65
|
+
"ipaddr.js": "2.4.0",
|
|
66
|
+
"jsdom": "29.1.1",
|
|
67
|
+
"pdf-parse": "2.4.5",
|
|
68
|
+
"strip-ansi": "7.2.0",
|
|
69
|
+
"turndown": "7.2.4",
|
|
70
|
+
"undici": "7.29.0",
|
|
61
71
|
"yaml": "2.9.0",
|
|
62
|
-
"zod": "
|
|
72
|
+
"zod": "4.4.3"
|
|
63
73
|
},
|
|
64
74
|
"devDependencies": {
|
|
65
75
|
"@agent-knowledge/kb-tools": "workspace:*",
|
|
76
|
+
"@types/jsdom": "28.0.3",
|
|
66
77
|
"@types/node": "^22.20.1",
|
|
78
|
+
"@types/turndown": "5.0.6",
|
|
67
79
|
"tsup": "^8.3.0",
|
|
68
80
|
"tsx": "^4.19.0",
|
|
69
81
|
"typescript": "^5.6.0",
|
package/skills/kb/SKILL.md
CHANGED
|
@@ -28,6 +28,11 @@ non-empty `type`. Everything else is soft guidance — consumers MUST tolerate m
|
|
|
28
28
|
unknown types, and broken links. Never reject a bundle over them. Full rules:
|
|
29
29
|
[references/SPEC.md](references/SPEC.md) §9.
|
|
30
30
|
|
|
31
|
+
The domain portion of `spec/types.md` is a living, producer-chosen vocabulary, not a validation
|
|
32
|
+
enum. Keep the workflow conventions `Reference` and `Spec Section`; start the domain types small
|
|
33
|
+
and evolve them through [`kb-ingest`](../kb-ingest/SKILL.md) when the domain reveals a durable new
|
|
34
|
+
kind of entity. Use [`kb-lint`](../kb-lint/SKILL.md) to detect schema drift.
|
|
35
|
+
|
|
31
36
|
## Route to the right skill
|
|
32
37
|
|
|
33
38
|
| The user wants to… | Use |
|
|
@@ -19,5 +19,6 @@ grows.
|
|
|
19
19
|
| `order` | A purchase made by a customer. | `concepts/` |
|
|
20
20
|
| `Reference` | A mirror of external source material (points at it via `resource`). | `references/` |
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
`chapter`)
|
|
22
|
+
Keep the workflow types `Spec Section` and `Reference`. Replace `customer` and `order` with a small,
|
|
23
|
+
provisional set of domain entities (e.g. `person`, `deal`, `metric`, `character`, `chapter`) and
|
|
24
|
+
extend that set as the domain becomes clearer.
|
|
@@ -40,9 +40,12 @@ thing will be routed.
|
|
|
40
40
|
## 2. Read and classify the source
|
|
41
41
|
|
|
42
42
|
Identify what to ingest (an argument, a path, or content the user dropped). Read it in full —
|
|
43
|
-
markdown, text,
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
markdown, text, image (view it), transcript, web page. In Janet, load and follow the `janet-pdf`
|
|
44
|
+
skill for a PDF; never use Janet's generic workspace file reader on the PDF or its cached
|
|
45
|
+
extraction. In another host, use its supported native PDF-reading workflow. Classify the source
|
|
46
|
+
(e.g. transcript, email, note, document, media) since that shapes extraction. **Ground everything
|
|
47
|
+
in what the source actually says** — never invent entities, claims, or attribution not present in
|
|
48
|
+
it (trust model §2).
|
|
46
49
|
|
|
47
50
|
**Completion criterion:** the source is read in full and classified; you can summarize its key
|
|
48
51
|
signal.
|
|
@@ -63,8 +66,26 @@ Before writing anything, draft a plan — the discovery-before-synthesis guard.
|
|
|
63
66
|
Keep the plan in scratch (or a temporary `_ingest_plan.md` you delete before finishing). A rich
|
|
64
67
|
source may touch 10–15 concepts.
|
|
65
68
|
|
|
69
|
+
### Schema-fit check
|
|
70
|
+
|
|
71
|
+
Treat `spec/types.md` as a living vocabulary, not a closed enum. Before routing, check whether the
|
|
72
|
+
source reveals a recurring, materially distinct kind of entity that the current types cannot
|
|
73
|
+
describe cleanly. Do not force-fit it or create an undocumented type.
|
|
74
|
+
|
|
75
|
+
- **Safe additive change:** when the new type and its route are unambiguous and do not reclassify
|
|
76
|
+
existing concepts, add it to `spec/types.md`, update `spec/conventions.md` if routing changes, and
|
|
77
|
+
include the schema change in this ingest's log entry.
|
|
78
|
+
- **Judgment or migration change:** ask the user once before renaming, splitting, merging, or
|
|
79
|
+
deprecating types; changing a type's meaning; moving existing concepts; or choosing among
|
|
80
|
+
plausible schemas. Present the proposed change and affected concepts together.
|
|
81
|
+
- Prefer a useful broader type for a one-off signal. Add a type when it is likely to recur or its
|
|
82
|
+
distinction materially improves routing and retrieval.
|
|
83
|
+
- Preserve old type values as deprecated until any approved migration is complete. Update affected
|
|
84
|
+
concepts and indexes together; never leave two undocumented vocabularies in parallel.
|
|
85
|
+
|
|
66
86
|
**Completion criterion:** a written plan exists listing every entity, its route (create/update), the
|
|
67
|
-
Reference for the source,
|
|
87
|
+
Reference for the source, any supersede/conflict flags, and any schema addition or proposed
|
|
88
|
+
migration.
|
|
68
89
|
|
|
69
90
|
## 4. Store the source as a Reference (provenance)
|
|
70
91
|
|
|
@@ -84,8 +105,8 @@ mechanics of create / **supersede** / **conflict** / additive-event. Write new c
|
|
|
84
105
|
both directions** (a person named in a deal links to their concept and back), with relative links.
|
|
85
106
|
|
|
86
107
|
**Completion criterion:** every entity in the plan has its concept created or updated with a
|
|
87
|
-
non-empty `type`, citing the Reference; planned supersede/conflict actions
|
|
88
|
-
model — no meaning rewritten in place.
|
|
108
|
+
non-empty, documented `type`, citing the Reference; planned schema and supersede/conflict actions
|
|
109
|
+
are applied per the schema layer and trust model — no meaning rewritten in place.
|
|
89
110
|
|
|
90
111
|
## 6. Re-synthesize overviews
|
|
91
112
|
|
package/skills/kb-init/SKILL.md
CHANGED
|
@@ -39,21 +39,39 @@ user only what you still can't infer:
|
|
|
39
39
|
`type` vocabulary (e.g. `person`, `deal`, `metric`; or `character`, `chapter`, `theme`).
|
|
40
40
|
- What raw **sources** will be ingested, and how should they route to those entities?
|
|
41
41
|
|
|
42
|
-
Keep it short — a few types and a one-line routing rule is enough to start
|
|
43
|
-
co-evolves
|
|
42
|
+
Keep it short — a few **provisional** types and a one-line routing rule is enough to start. This is
|
|
43
|
+
an initial vocabulary, not a closed enum; the schema layer co-evolves as ingest reveals the domain.
|
|
44
|
+
`Reference` (captured source material) and `Spec Section` (the bundle's own schema documents) are
|
|
45
|
+
workflow types supplied by the seed, not domain choices the user needs to design.
|
|
46
|
+
|
|
47
|
+
Interaction contract:
|
|
48
|
+
|
|
49
|
+
- Inspect the workspace once, batching related reads where practical.
|
|
50
|
+
- Ask one concise, free-text question for everything that remains unknown.
|
|
51
|
+
- Do not use canned multiple-choice options for this domain-specific input.
|
|
52
|
+
- After the user answers, continue from this loaded procedure. Do not load `kb-init` again.
|
|
53
|
+
- If you propose a schema for confirmation, accept the user's answer once. After approval, scaffold
|
|
54
|
+
without restating or replanning it.
|
|
44
55
|
|
|
45
56
|
**Completion criterion:** you can name the bundle's initial `type` values, its raw sources, and a
|
|
46
57
|
one-line ingest routing rule.
|
|
47
58
|
|
|
48
|
-
## 3.
|
|
59
|
+
## 3. Write the adapted seed and schema layer
|
|
60
|
+
|
|
61
|
+
Read [../kb/example-bundle/](../kb/example-bundle/) as the source scaffold, then write its adapted
|
|
62
|
+
artifacts into the target. Do not first write an unmodified copy and then overwrite it: create the
|
|
63
|
+
directories and write each target file once with its final, domain-specific content. Work quietly
|
|
64
|
+
after the user's approval; do not narrate each read or write.
|
|
49
65
|
|
|
50
|
-
|
|
66
|
+
If a prior attempt already created a target file, it is no longer new: read that file immediately
|
|
67
|
+
before editing it, preserve valid work, and resume from the incomplete step. Never retry a
|
|
68
|
+
read-before-write failure blindly or dismiss it as a false alarm.
|
|
51
69
|
|
|
52
70
|
| Artifact | Action |
|
|
53
71
|
|---|---|
|
|
54
72
|
| `index.md` | Keep `okf_version: "0.1"` frontmatter; replace the body with this bundle's title and section list. |
|
|
55
73
|
| `log.md` | Start fresh with a single dated `**Creation**` entry. |
|
|
56
|
-
| `spec/types.md` |
|
|
74
|
+
| `spec/types.md` | Keep `Spec Section` and `Reference`; replace only the example domain types with the provisional vocabulary from step 2. |
|
|
57
75
|
| `spec/conventions.md` | Replace with folder taxonomy, naming, ingest routing rule, and a trust-model pointer. |
|
|
58
76
|
| `concepts/*` | Remove example entities (`customers`, `orders`); leave `concepts/` empty or create domain starter folders. |
|
|
59
77
|
| `knowledge/index.md` | If multi-bundle (step 1): create or update the catalog entry for this bundle. |
|
package/skills/kb-lint/SKILL.md
CHANGED
|
@@ -44,6 +44,9 @@ the legwork that makes lint worth running. Cover every check:
|
|
|
44
44
|
- **Coverage gaps** — entities named repeatedly across concepts but lacking their own concept; data
|
|
45
45
|
gaps a source or web search could fill.
|
|
46
46
|
- **Provenance gaps** — concepts making external claims with no `# Citations` / Reference.
|
|
47
|
+
- **Schema drift** — types used but absent from `spec/types.md`; documented types that no longer
|
|
48
|
+
describe their concepts; spelling/case variants; or one overloaded type hiding several recurring,
|
|
49
|
+
materially distinct entity kinds. Treat unused documented types as Info, not an error.
|
|
47
50
|
|
|
48
51
|
**Completion criterion:** every check above has been run across the whole bundle and its findings
|
|
49
52
|
recorded — not a sample.
|
|
@@ -71,7 +74,9 @@ vs. what needs a human:
|
|
|
71
74
|
log dates, broken links with an obvious target, index entries out of sync with files.
|
|
72
75
|
- **Never auto-fix:** anything that changes a claim's meaning. A contradiction or a stale *claim* is
|
|
73
76
|
resolved by [ingest](../kb-ingest/SKILL.md) under the [trust model](../kb/references/trust-model.md)
|
|
74
|
-
(**supersede**/**conflict**) — never by editing meaning in place here.
|
|
77
|
+
(**supersede**/**conflict**) — never by editing meaning in place here. Type renames, merges,
|
|
78
|
+
splits, deprecations, and migrations also require user confirmation; report the proposed schema
|
|
79
|
+
change and affected concepts together.
|
|
75
80
|
|
|
76
81
|
**Completion criterion:** every safe issue is fixed and every meaning-level issue is flagged (not
|
|
77
82
|
touched); the re-report distinguishes the two.
|
package/dist/chunk-3XSOMUQQ.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { createRequire as __janetCreateRequire } from "node:module";
|
|
3
|
-
const require = __janetCreateRequire(import.meta.url);
|
|
4
|
-
import {
|
|
5
|
-
appDataDir,
|
|
6
|
-
getAuthStorage,
|
|
7
|
-
hasAwsCredentials,
|
|
8
|
-
hasGoogleCredentials
|
|
9
|
-
} from "./chunk-YIAVFL7A.js";
|
|
10
|
-
|
|
11
|
-
// src/onboarding/settings.ts
|
|
12
|
-
import { mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
13
|
-
import { dirname, join } from "path";
|
|
14
|
-
var ONBOARDING_VERSION = 1;
|
|
15
|
-
function settingsPath() {
|
|
16
|
-
return join(appDataDir(), "settings.json");
|
|
17
|
-
}
|
|
18
|
-
function loadSettings() {
|
|
19
|
-
try {
|
|
20
|
-
return JSON.parse(readFileSync(settingsPath(), "utf-8"));
|
|
21
|
-
} catch {
|
|
22
|
-
return {};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function saveSettings(settings) {
|
|
26
|
-
const p = settingsPath();
|
|
27
|
-
mkdirSync(dirname(p), { recursive: true });
|
|
28
|
-
writeFileSync(p, JSON.stringify(settings, null, 2) + "\n", "utf-8");
|
|
29
|
-
}
|
|
30
|
-
function completeOnboarding(modelId, stampedAt) {
|
|
31
|
-
const settings = loadSettings();
|
|
32
|
-
settings.defaultModelId = modelId;
|
|
33
|
-
settings.onboarding = { completedAt: stampedAt, version: ONBOARDING_VERSION };
|
|
34
|
-
saveSettings(settings);
|
|
35
|
-
}
|
|
36
|
-
function rememberModel(modelId) {
|
|
37
|
-
const id = modelId.trim();
|
|
38
|
-
if (!id) return;
|
|
39
|
-
const settings = loadSettings();
|
|
40
|
-
const rest = (settings.customModels ?? []).filter((m) => m !== id);
|
|
41
|
-
settings.customModels = [id, ...rest].slice(0, 20);
|
|
42
|
-
saveSettings(settings);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// src/onboarding/providers.ts
|
|
46
|
-
var CODEX_MODELS = [
|
|
47
|
-
{ id: "gpt-5.6-sol", label: "GPT-5.6 Sol" },
|
|
48
|
-
{ id: "gpt-5.6-terra", label: "GPT-5.6 Terra" },
|
|
49
|
-
{ id: "gpt-5.6-luna", label: "GPT-5.6 Luna" },
|
|
50
|
-
{ id: "gpt-5.5", label: "GPT-5.5" },
|
|
51
|
-
{ id: "gpt-5.4", label: "GPT-5.4" },
|
|
52
|
-
{ id: "gpt-5.4-mini", label: "GPT-5.4 Mini" }
|
|
53
|
-
];
|
|
54
|
-
var LEGACY_CODEX_MODEL_IDS = {
|
|
55
|
-
"gpt-5.6-codex": "openai/gpt-5.6-sol",
|
|
56
|
-
"openai/gpt-5.6-codex": "openai/gpt-5.6-sol",
|
|
57
|
-
"gpt-5.5-codex": "openai/gpt-5.5",
|
|
58
|
-
"openai/gpt-5.5-codex": "openai/gpt-5.5"
|
|
59
|
-
};
|
|
60
|
-
function normalizeModelSelection(modelId, choices) {
|
|
61
|
-
const id = modelId.trim();
|
|
62
|
-
const legacy = LEGACY_CODEX_MODEL_IDS[id];
|
|
63
|
-
if (legacy) return legacy;
|
|
64
|
-
if (!id || id.includes("/")) return id;
|
|
65
|
-
const matches = choices.filter((choice) => choice.id.endsWith(`/${id}`));
|
|
66
|
-
return matches.length === 1 ? matches[0].id : id;
|
|
67
|
-
}
|
|
68
|
-
function hasOAuth(provider) {
|
|
69
|
-
try {
|
|
70
|
-
const s = getAuthStorage();
|
|
71
|
-
s.reload();
|
|
72
|
-
return s.get(provider)?.type === "oauth";
|
|
73
|
-
} catch {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
function hasEnv(...vars) {
|
|
78
|
-
return vars.some((v) => !!process.env[v]);
|
|
79
|
-
}
|
|
80
|
-
function availableModels() {
|
|
81
|
-
const out = [];
|
|
82
|
-
if (hasGoogleCredentials()) {
|
|
83
|
-
const via = "Vertex AI (ADC)";
|
|
84
|
-
out.push(
|
|
85
|
-
{ id: "vertex/claude-opus-4-8", label: "Claude Opus 4.8", via },
|
|
86
|
-
{ id: "vertex/claude-sonnet-4-5", label: "Claude Sonnet 4.5", via },
|
|
87
|
-
{ id: "vertex/gemini-2.5-pro", label: "Gemini 2.5 Pro", via }
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
if (hasEnv("ANTHROPIC_API_KEY") || hasOAuth("anthropic")) {
|
|
91
|
-
const via = hasOAuth("anthropic") ? "Anthropic (Claude Max)" : "Anthropic (API key)";
|
|
92
|
-
out.push(
|
|
93
|
-
{ id: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6", via },
|
|
94
|
-
{ id: "anthropic/claude-sonnet-4-5", label: "Claude Sonnet 4.5", via }
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
if (hasOAuth("openai-codex")) {
|
|
98
|
-
const via = "OpenAI (ChatGPT/Codex)";
|
|
99
|
-
for (const m of CODEX_MODELS) out.push({ id: `openai/${m.id}`, label: m.label, via });
|
|
100
|
-
} else if (hasEnv("OPENAI_API_KEY")) {
|
|
101
|
-
out.push({ id: "openai/gpt-5.5", label: "GPT-5.5", via: "OpenAI (API key)" });
|
|
102
|
-
}
|
|
103
|
-
if (hasAwsCredentials()) {
|
|
104
|
-
const via = "Amazon Bedrock (AWS)";
|
|
105
|
-
out.push(
|
|
106
|
-
{ id: "amazon-bedrock/anthropic.claude-opus-4-1-20250805-v1:0", label: "Claude Opus 4.1", via },
|
|
107
|
-
{ id: "amazon-bedrock/anthropic.claude-sonnet-4-20250514-v1:0", label: "Claude Sonnet 4", via }
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
if (hasEnv("GOOGLE_GENERATIVE_AI_API_KEY")) {
|
|
111
|
-
out.push({ id: "google/gemini-2.5-pro", label: "Gemini 2.5 Pro", via: "Google (API key)" });
|
|
112
|
-
}
|
|
113
|
-
const known = new Set(out.map((m) => m.id));
|
|
114
|
-
for (const savedId of loadSettings().customModels ?? []) {
|
|
115
|
-
const id = normalizeModelSelection(savedId, out);
|
|
116
|
-
if (!known.has(id)) {
|
|
117
|
-
out.push({ id, label: id.split("/").pop() ?? id, via: "saved" });
|
|
118
|
-
known.add(id);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return out;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export {
|
|
125
|
-
loadSettings,
|
|
126
|
-
completeOnboarding,
|
|
127
|
-
rememberModel,
|
|
128
|
-
normalizeModelSelection,
|
|
129
|
-
availableModels
|
|
130
|
-
};
|
|
131
|
-
//# sourceMappingURL=chunk-3XSOMUQQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/onboarding/settings.ts","../src/onboarding/providers.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { appDataDir } from \"../agent/paths.js\";\n\n/** Global, machine-wide settings (model default + onboarding marker). */\nexport interface JanetSettings {\n onboarding?: { completedAt: string; version: number };\n /** The persisted default model id, applied when no --model / JANET_MODEL is given. */\n defaultModelId?: string;\n /** Model ids the user has used directly — surfaced in the picker afterward. */\n customModels?: string[];\n}\n\nexport const ONBOARDING_VERSION = 1;\n\nfunction settingsPath(): string {\n return join(appDataDir(), \"settings.json\");\n}\n\nexport function loadSettings(): JanetSettings {\n try {\n return JSON.parse(readFileSync(settingsPath(), \"utf-8\")) as JanetSettings;\n } catch {\n return {};\n }\n}\n\nexport function saveSettings(settings: JanetSettings): void {\n const p = settingsPath();\n mkdirSync(dirname(p), { recursive: true });\n writeFileSync(p, JSON.stringify(settings, null, 2) + \"\\n\", \"utf-8\");\n}\n\n/** Persist the chosen model and mark onboarding complete. */\nexport function completeOnboarding(modelId: string, stampedAt: string): void {\n const settings = loadSettings();\n settings.defaultModelId = modelId;\n settings.onboarding = { completedAt: stampedAt, version: ONBOARDING_VERSION };\n saveSettings(settings);\n}\n\nexport function hasOnboarded(): boolean {\n return loadSettings().onboarding !== undefined;\n}\n\n/**\n * Remember a model id the user selected directly so it appears in the picker on\n * later runs. Keeps the picker current without code changes as providers ship\n * new models. Most-recent-first, capped.\n */\nexport function rememberModel(modelId: string): void {\n const id = modelId.trim();\n if (!id) return;\n const settings = loadSettings();\n const rest = (settings.customModels ?? []).filter((m) => m !== id);\n settings.customModels = [id, ...rest].slice(0, 20);\n saveSettings(settings);\n}\n","import { hasGoogleCredentials } from \"../gateways/vertex.js\";\nimport { hasAwsCredentials } from \"../gateways/bedrock.js\";\nimport { getAuthStorage } from \"../gateways/oauth/claude-max.js\";\nimport { loadSettings } from \"./settings.js\";\n\nexport interface ModelChoice {\n /** Full model id, e.g. \"vertex/claude-opus-4-8\". */\n id: string;\n /** Short human label, e.g. \"Claude Opus 4.8\". */\n label: string;\n /** How this provider is reached, e.g. \"Vertex AI (ADC)\". */\n via: string;\n}\n\n/**\n * Models offered when signed in to a ChatGPT/Codex subscription (OAuth). The\n * Codex `responses` backend accepts the model id verbatim, so this is a\n * convenience lineup — ANY id also works via `/model openai/<id>`. Edit here as\n * OpenAI's Codex catalog changes.\n */\nexport const CODEX_MODELS: ReadonlyArray<{ id: string; label: string }> = [\n { id: \"gpt-5.6-sol\", label: \"GPT-5.6 Sol\" },\n { id: \"gpt-5.6-terra\", label: \"GPT-5.6 Terra\" },\n { id: \"gpt-5.6-luna\", label: \"GPT-5.6 Luna\" },\n { id: \"gpt-5.5\", label: \"GPT-5.5\" },\n { id: \"gpt-5.4\", label: \"GPT-5.4\" },\n { id: \"gpt-5.4-mini\", label: \"GPT-5.4 Mini\" },\n];\n\nconst LEGACY_CODEX_MODEL_IDS: Readonly<Record<string, string>> = {\n \"gpt-5.6-codex\": \"openai/gpt-5.6-sol\",\n \"openai/gpt-5.6-codex\": \"openai/gpt-5.6-sol\",\n \"gpt-5.5-codex\": \"openai/gpt-5.5\",\n \"openai/gpt-5.5-codex\": \"openai/gpt-5.5\",\n};\n\n/**\n * Resolve a hand-typed or previously persisted model name to Mastra's required\n * `provider/model` form when the active provider catalog makes it unambiguous.\n * Also migrates the invalid Codex aliases Janet advertised before v0.1.0.\n */\nexport function normalizeModelSelection(\n modelId: string,\n choices: ReadonlyArray<ModelChoice>,\n): string {\n const id = modelId.trim();\n const legacy = LEGACY_CODEX_MODEL_IDS[id];\n if (legacy) return legacy;\n if (!id || id.includes(\"/\")) return id;\n\n const matches = choices.filter((choice) => choice.id.endsWith(`/${id}`));\n return matches.length === 1 ? matches[0]!.id : id;\n}\n\nfunction hasOAuth(provider: string): boolean {\n try {\n const s = getAuthStorage();\n s.reload();\n return s.get(provider)?.type === \"oauth\";\n } catch {\n return false;\n }\n}\n\nfunction hasEnv(...vars: string[]): boolean {\n return vars.some((v) => !!process.env[v]);\n}\n\n/**\n * Enumerate concrete model choices from the providers that are actually\n * reachable on this machine right now (env keys, ADC, AWS chain, stored OAuth).\n * Ordered best-first. Empty when nothing is configured.\n */\nexport function availableModels(): ModelChoice[] {\n const out: ModelChoice[] = [];\n\n if (hasGoogleCredentials()) {\n const via = \"Vertex AI (ADC)\";\n out.push(\n { id: \"vertex/claude-opus-4-8\", label: \"Claude Opus 4.8\", via },\n { id: \"vertex/claude-sonnet-4-5\", label: \"Claude Sonnet 4.5\", via },\n { id: \"vertex/gemini-2.5-pro\", label: \"Gemini 2.5 Pro\", via },\n );\n }\n if (hasEnv(\"ANTHROPIC_API_KEY\") || hasOAuth(\"anthropic\")) {\n const via = hasOAuth(\"anthropic\") ? \"Anthropic (Claude Max)\" : \"Anthropic (API key)\";\n out.push(\n { id: \"anthropic/claude-opus-4-6\", label: \"Claude Opus 4.6\", via },\n { id: \"anthropic/claude-sonnet-4-5\", label: \"Claude Sonnet 4.5\", via },\n );\n }\n if (hasOAuth(\"openai-codex\")) {\n // Signed in to a ChatGPT/Codex subscription — offer the full Codex lineup.\n const via = \"OpenAI (ChatGPT/Codex)\";\n for (const m of CODEX_MODELS) out.push({ id: `openai/${m.id}`, label: m.label, via });\n } else if (hasEnv(\"OPENAI_API_KEY\")) {\n out.push({ id: \"openai/gpt-5.5\", label: \"GPT-5.5\", via: \"OpenAI (API key)\" });\n }\n if (hasAwsCredentials()) {\n const via = \"Amazon Bedrock (AWS)\";\n out.push(\n { id: \"amazon-bedrock/anthropic.claude-opus-4-1-20250805-v1:0\", label: \"Claude Opus 4.1\", via },\n { id: \"amazon-bedrock/anthropic.claude-sonnet-4-20250514-v1:0\", label: \"Claude Sonnet 4\", via },\n );\n }\n if (hasEnv(\"GOOGLE_GENERATIVE_AI_API_KEY\")) {\n out.push({ id: \"google/gemini-2.5-pro\", label: \"Gemini 2.5 Pro\", via: \"Google (API key)\" });\n }\n\n // Models the user has used directly (via /model or --model) that aren't\n // already listed — keeps the picker current as providers ship new models.\n const known = new Set(out.map((m) => m.id));\n for (const savedId of loadSettings().customModels ?? []) {\n const id = normalizeModelSelection(savedId, out);\n if (!known.has(id)) {\n out.push({ id, label: id.split(\"/\").pop() ?? id, via: \"saved\" });\n known.add(id);\n }\n }\n\n return out;\n}\n"],"mappings":"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","names":[]}
|