@sayknow-cli/coding-agent 0.5.26 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/types/config/settings-schema.d.ts +25 -5
  3. package/dist/types/decisions/keyword-learning.d.ts +61 -0
  4. package/dist/types/decisions/llm-backend.d.ts +13 -1
  5. package/dist/types/decisions/prompt-triage.d.ts +42 -0
  6. package/dist/types/decisions/skill-routing.d.ts +41 -6
  7. package/dist/types/hooks/native-prompt-routing.d.ts +21 -0
  8. package/dist/types/hooks/native-skill-hook.d.ts +3 -0
  9. package/dist/types/hooks/skill-keywords.d.ts +9 -0
  10. package/dist/types/hooks/skill-state.d.ts +20 -3
  11. package/dist/types/hooks/ui-skill-keywords.d.ts +15 -0
  12. package/dist/types/sdk/session.d.ts +3 -13
  13. package/dist/types/session/agent-session.d.ts +8 -0
  14. package/dist/types/session/auth-storage-discovery.d.ts +13 -0
  15. package/dist/types/tools/browser.d.ts +2 -2
  16. package/package.json +7 -7
  17. package/scripts/eval-skill-routing.ts +37 -12
  18. package/src/config/settings-schema.ts +27 -5
  19. package/src/decisions/index.ts +8 -2
  20. package/src/decisions/keyword-learning.ts +678 -0
  21. package/src/decisions/llm-backend.ts +213 -67
  22. package/src/decisions/prompt-triage.ts +163 -0
  23. package/src/decisions/skill-routing.ts +39 -56
  24. package/src/decisions/typesafe-backend.ts +3 -0
  25. package/src/hooks/native-prompt-routing.ts +190 -0
  26. package/src/hooks/native-skill-hook.ts +21 -12
  27. package/src/hooks/skill-keywords.ts +9 -0
  28. package/src/hooks/skill-state.ts +41 -10
  29. package/src/hooks/ui-skill-keywords.ts +67 -10
  30. package/src/internal-urls/docs-index.generated.ts +1 -1
  31. package/src/sdk/session.ts +5 -82
  32. package/src/session/agent-session.ts +137 -37
  33. package/src/session/auth-storage-discovery.ts +83 -0
@@ -2008,12 +2008,32 @@ export const SETTINGS_SCHEMA = {
2008
2008
  // Typed decisions
2009
2009
  "decisions.enabled": {
2010
2010
  type: "boolean",
2011
- default: false,
2011
+ default: true,
2012
2012
  ui: {
2013
2013
  tab: "context",
2014
2014
  label: "Typed decisions",
2015
2015
  description:
2016
- "Add a model-backed second stage to workflow routing. The keyword table already runs on every turn and costs nothing; this handles the phrasings it cannot express, which is most wording that is not a literal match. Costs one small model call, and only on turns the keyword table did not already answer. Any failure falls back to keyword-only behaviour, but a successful answer can also select a different workflow than the deep-interview ambiguity detector would have.",
2016
+ "Model-backed second stage for workflow routing. The keyword table runs first on every turn and costs nothing; this handles the phrasings it cannot express, which is most wording that is not a literal match. Costs one small model call, only on turns the keyword table did not already answer, on the cheapest backend available: TypeSafe when a key is stored, else a local runtime that is running, else the small model of the provider you are chatting with. Any failure falls back to keyword-only behaviour, but a successful answer can also select a different workflow than the deep-interview ambiguity detector would have. Turn off to route on the keyword table alone.",
2017
+ },
2018
+ },
2019
+
2020
+ /**
2021
+ * Feed routing answers back into the deterministic keyword table.
2022
+ *
2023
+ * The hand-written table cannot be grown by hand for Korean — measured recall
2024
+ * was 0/9 — so it grows itself instead: a two-stem pattern that produced the
2025
+ * same routing answer on two distinct prompts, and was never contradicted, is
2026
+ * promoted and thereafter fires for free. One contradiction retracts it
2027
+ * permanently. Stems and hashes are stored; prompt text never is.
2028
+ */
2029
+ "decisions.keywordLearning": {
2030
+ type: "boolean",
2031
+ default: true,
2032
+ ui: {
2033
+ tab: "context",
2034
+ label: "Learn routing keywords",
2035
+ description:
2036
+ "Remember the phrasings the routing model resolves, so repeating one stops costing a model call. A pattern must give the same answer on two different prompts before it fires on its own, and a single disagreement removes it for good. Only word stems and hashes are written to disk, never your prompts. Turn off to keep the keyword table frozen at its built-in entries.",
2017
2037
  },
2018
2038
  },
2019
2039
 
@@ -2026,12 +2046,14 @@ export const SETTINGS_SCHEMA = {
2026
2046
  * mid-session invalidates the prompt cache, which on a long context costs
2027
2047
  * more than the cheaper tier saves.
2028
2048
  *
2029
- * Needs `decisions.enabled` and at least two tiers configured. Without both
2030
- * it never fires and the configured role models are used unchanged.
2049
+ * Needs `decisions.enabled` and at least two tiers configured. The tiers are
2050
+ * empty by default, so this is a no-op until the user sets them — which is why
2051
+ * it defaults on: shipping it off meant the routing code existed and never ran
2052
+ * even for users who had configured the tiers it needs.
2031
2053
  */
2032
2054
  "task.modelRouting.enabled": {
2033
2055
  type: "boolean",
2034
- default: false,
2056
+ default: true,
2035
2057
  ui: {
2036
2058
  tab: "tasks",
2037
2059
  label: "Route subagent models per task",
@@ -43,8 +43,9 @@ export function createDecisionService(options: DecisionServiceOptions): Decision
43
43
  * probabilities, and it resolves `null` immediately when no key is stored, so users
44
44
  * who never added one pay nothing for it being in the list.
45
45
  *
46
- * The user's logged-in model is the fallback and the default experience: no extra
47
- * vendor, no extra key, works offline of TypeSafe entirely.
46
+ * The user's logged-in provider is the fallback and the default experience: no extra
47
+ * vendor, no extra key, works offline of TypeSafe entirely. Inside it, a live local
48
+ * runtime is tried before a hosted small model; see `llm-backend.ts`.
48
49
  */
49
50
  const backends = options.backends ?? [createTypeSafeDecisionBackend(options), createLlmDecisionBackend(options)];
50
51
 
@@ -53,6 +54,11 @@ export function createDecisionService(options: DecisionServiceOptions): Decision
53
54
  async decide(request: DecisionRequest): Promise<DecisionResult | null> {
54
55
  if (!enabled || backends.length === 0) return null;
55
56
  for (const backend of backends) {
57
+ // A listener added to a signal that already fired never runs, and the
58
+ // backends only read their own derived signal. Measured: a caller that
59
+ // aborted during the previous backend's await got a full attempt budget of
60
+ // silence from the next one instead of an immediate null.
61
+ if (request.signal?.aborted) return null;
56
62
  const controller = new AbortController();
57
63
  const abortOnCallerSignal = () => controller.abort();
58
64
  request.signal?.addEventListener("abort", abortOnCallerSignal, { once: true });