feat(T2a): tool-toggle seam + phase-based question principles
Part 1 — tool availability (the settings seam, machinery generic): - core/pending.ts: TOGGLEABLE_TOOLS (today: research, demo, visual — the model-facing tool names), EnabledTools = the JSON-native seam shape Partial<Record<string, boolean>> (absent key = enabled, so old records behave exactly as today), filterEnabledTools shared helper. quiz/ask_user_question are always-on FOR NOW (user-decided); the filtering is generic so future toggleables (question-tool variants, the read tool, …) need no factory change. - createProberTools/createTeacherTools take enabled?: EnabledTools; the composition root (chat-handler, Platform's lane this wave) passes the resolved settings through. probe_done is re-added after the filter — always-on by construction (it ends the phase; a prober that can never conclude is a lockout). - Prompts stay STATIC under toggles this wave (user-decided); standing principle recorded: tools ship self-contained usage guidance in their descriptions; system prompts reference only always-on tools. Part 2 — phase-based question-writing principles (user-locked wording, drafted with the user over three iterations): - NEW teacher/21-question-principles.md (composes after 20-teaching): answerable-by-reasoning-from-the-session (the fairness rule that filters unanswerable questions without forbidding visible answers), never-just-reciting-your-words-back, PREFER problems that apply the knowledge (preference, not hard rule — honest recall is the fallback, not the habit), catch-confusion-early-and-nameable (wrong options as real misconceptions), answer-is-signal-not-verdict. - prober/10-probe-doctrine.md: 'no rush' retired; quick-measurement directive in — every question moves an edge (bracket, narrow, or characterize); a bracketed strand is done. Tests: TOGGLEABLE_TOOLS pin, prober/teacher filtering (absent = full, false drops exactly that tool, probe_done survives), prompt pins (the principles compose verbatim into the teacher prompt, the no-rush framing is gone from the prober). 547/547, typecheck/lint/build green.
This commit is contained in:
+42
-12
@@ -5,6 +5,7 @@ import {
|
||||
quizInputObject,
|
||||
quizInputProblems,
|
||||
} from "../core/question-core.ts";
|
||||
import { filterEnabledTools, type EnabledTools } from "../core/pending.ts";
|
||||
import type { JobRecord } from "../core/contracts.ts";
|
||||
import type { JobStore } from "../core/ports.ts";
|
||||
import { jobTools, type DemoInput, type ResearchInput, type VisualInput } from "./tools/jobs.ts";
|
||||
@@ -62,12 +63,28 @@ export const probeQuizTool: LhTool<any, any> = {
|
||||
schema: probeQuizInputSchema,
|
||||
};
|
||||
|
||||
/** The prober's tool set: probe quiz (no nodeId) + ask + probe_done. */
|
||||
export function createProberTools(ctx: ProbeDoneContext): Record<string, LhTool<any, any>> {
|
||||
/** The prober's tool set: probe quiz (no nodeId) + ask + probe_done.
|
||||
* `enabled` is the resolved settings seam (core/pending.ts): any tool
|
||||
* explicitly false is dropped from the registry. probe_done stays
|
||||
* always-on regardless — it is how the phase ENDS; a prober that can
|
||||
* never conclude is a lockout. */
|
||||
export function createProberTools(
|
||||
ctx: ProbeDoneContext,
|
||||
enabled?: EnabledTools,
|
||||
): Record<string, LhTool<any, any>> {
|
||||
// probe_done is re-added AFTER the filter, always-on by construction — it
|
||||
// is how the phase ENDS; a prober that can never conclude is a lockout.
|
||||
const done = probeDoneTool(ctx);
|
||||
return {
|
||||
quiz: probeQuizTool,
|
||||
ask_user_question: askUserQuestionTool,
|
||||
...probeDoneTool(ctx),
|
||||
...filterEnabledTools(
|
||||
{
|
||||
quiz: probeQuizTool,
|
||||
ask_user_question: askUserQuestionTool,
|
||||
...done,
|
||||
},
|
||||
enabled,
|
||||
),
|
||||
...done,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -131,12 +148,25 @@ export interface TeacherToolContext extends PlanToolContext {
|
||||
/**
|
||||
* Per-request teacher tool registry: teach questions (validated nodeId) +
|
||||
* plan tools + job tools, all closing over the ctx.
|
||||
*
|
||||
* `enabled` is the resolved settings seam (core/pending.ts EnabledTools —
|
||||
* Platform's chat-handler wiring passes it through from settings). Today
|
||||
* only the sub-agent tools (research/demo/visual) are user-toggleable, but
|
||||
* the filtering is GENERIC: any name explicitly false is dropped, so
|
||||
* future toggleables (question-tool variants, …) need no change here.
|
||||
* Absent/undefined = enabled — tests and old records see today's set.
|
||||
*/
|
||||
export function createTeacherTools(ctx: TeacherToolContext): Record<string, LhTool<any, any>> {
|
||||
return {
|
||||
quiz: teachQuizToolFor(ctx),
|
||||
ask_user_question: askUserQuestionTool,
|
||||
...planTools(ctx),
|
||||
...jobTools({ chatId: ctx.chatId, jobStore: ctx.jobStore, spawn: ctx.spawn }),
|
||||
};
|
||||
export function createTeacherTools(
|
||||
ctx: TeacherToolContext,
|
||||
enabled?: EnabledTools,
|
||||
): Record<string, LhTool<any, any>> {
|
||||
return filterEnabledTools(
|
||||
{
|
||||
quiz: teachQuizToolFor(ctx),
|
||||
ask_user_question: askUserQuestionTool,
|
||||
...planTools(ctx),
|
||||
...jobTools({ chatId: ctx.chatId, jobStore: ctx.jobStore, spawn: ctx.spawn }),
|
||||
},
|
||||
enabled,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user