π Planning: llm-ports v0.1.0-alpha.29 β Capability factory ergonomics #65
baabakk
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Status: Planning discussion. Target ship 2026-08-19 (two weeks after alpha.28). Extendable to 2026-09-02 if design questions surface.
Theme: Capability factory ergonomics. Eleven items adding hooks, schemas, and configuration flexibility to the five capability factories in
@llm-ports/capabilities, plus one Registry-level diagnostic and one adapter policy adjustment.Prior release: alpha.28 (planned 2026-08-05; reliability + observability polish; see planning discussion filed alongside this one).
What ships in alpha.29
Eleven items across three sub-themes.
Capability factory hooks + schemas (BEPA-heavy asks)
createSummarizer(BEPA 2). Addschema?: z.ZodType<T>toCreateSummarizerConfig. When present, factory returnsz.infer<T>(structured summary); when absent, returns string (current behavior). Kills BEPA's misuse ofcreateExtractorfor structured summaries. ~40 LoC.groundingValidatorhook oncreateExtractor(BEPA 3). New optional config field:groundingValidator?: (output: T, input: ExtractInput) => string[] | null. Runs after schema validation succeeds; failures returned by the validator become the correction prompt for retry-with-feedback. Kills BEPA's 40-line outer retry loop. ~60 LoC.createAnalyzer(BEPA 4). Symmetric with Item 1; returns string when schema absent,z.infer<T>when present. Kills BEPA's text-returningllmAnalyzeescape hatch. ~40 LoC.postValidationHookoncreatePlanner(BEPA 5). New optional config field:postValidationHook?: (plan: T) => { valid: boolean; errors?: string[] }. Runs after schema validation; failures feed the model as retry prompts. Lets BEPA plug DAG cycle detection + activity-name membership + scope validation into the factory's retry loop. ~50 LoC.generateStructured(SalesCoach D + Plan 30 A.4). Schema-level defaults fill omitted fields instead of throwing. Consumer suppliespartialAccept: { defaults: Partial<T> }on the call. Deletes SalesCoach's 52-lineassembleCallPlan. ~100 LoC.Diagnostic + type ergonomics
Registry.validateWithEnv()diagnostic (SalesCoach G). Returns structured report per alias: adapter registered? route has live links? alias references model in bundled catalog? Pricing entry present? Replaces SalesCoach's hand-rolled Phase 4.0 dry-run script. Related to Item 13 (tolerantKeylessAliases, alpha.28) but broader. ~150 LoC.PartialResultLLMPort/CompatibleLLMPorttype export (BEPA 1). Publishes a branded compat type where result-metadata fields (cost,providerAlias,latencyMs,validationAttempts,stepsTaken,terminationReason) arePartial. Removes BEPA's 5as unknown as PublishedLLMPortcasts. ~20 LoC (type-level).Sessions + vision
openNamedSession/getSession/sessions()/session.snapshot()(Dramma 3). ReplacesopenCostSessionwith a self-managing named session that supports TTL, snapshot, and cross-worker lookup by id. Kills Dramma's 168-linesession-store.ts. ~200 LoC + tests.port.classifytriage helper (Dramma 6). New capability factorycreateVisionTriagerin@llm-ports/capabilities. Takes an image + a list of yes/no triage questions; internally uses the "low-detail" cost knob on vision models. Consumer's downstreamgenerateStructured(high-detail) is gated by the triager'strue/falsereturn. ~100 LoC + provider verification for OpenAI vision + Gemini vision.Adapter policy
responseAdapterhook onadapter-openai(Dramma 2b). Configuration oncreateOpenAIAdapter({ responseAdapter?: (raw: unknown) => LLMPortResponse })for consumers who point adapter-openai at a compat provider whose response includes extra fields (confidence,content_type,language) or a non-standard payload shape. Kills Dramma's 130-linehandleSelfhostedRecognizeproxy. ~80 LoC.NonContiguousSystemErrordemoted to warning per-adapter (SalesCoach H). Partially undoes the alpha.27 introduction (per Blocker 1 of alpha.27). Some adapters (Anthropic native multi-system content blocks; some OpenAI-compat providers) tolerate mid-conversation system messages. New adapter option:nonContiguousSystemPolicy?: "throw" | "warn-and-collapse"default"throw". ~40 LoC per adapter.Open design questions
postValidationHookvsgroundingValidatorunification. Both are "run a validator after schema validation succeeds; feed errors back as retry prompts." Ship as ONE hook name shared across factories, or KEEP as two named hooks with subtly different semantics (planner-specific vs extractor-specific)? Recommendation: ship as one hook name (postValidateHook<T>) shared across all five capability factories; consumers implement whatever validation logic they need.@llm-ports/budget-redis.createVisionTriagerfallback shape. If no vision-capable provider is configured, throw at construction OR return a stub that always returnstrue(skip triage; go straight to expensive read)? Recommendation: throw at construction with a clear error naming which providers support the low-detail path.responseAdapterscope. Adapter-openai only (Dramma's specific use case) OR shared across all adapters (any provider might need custom response parsing)? Recommendation: shared surfaceAdapterRegistration.responseAdapter?: (raw: unknown) => LLMPortResponseso it applies uniformly across adapter types.nonContiguousSystemPolicy: "warn-and-collapse"collapse strategy. Concatenate all system-role content and prepend to the array (matches alpha.27 leading-contiguous behavior) OR drop non-leading system messages entirely? Recommendation: concatenate + prepend (preserves intent).Consumer credit
Cross-references
Post design-question answers below by 2026-08-12 for baseline scope.
All reactions