@qadanm/opencode-smart-router 0.0.0-stage → 0.4.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 (65) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/CONTRIBUTING.md +96 -0
  3. package/LICENSE +21 -0
  4. package/README.md +341 -2
  5. package/SECURITY.md +174 -0
  6. package/config.example.json +108 -0
  7. package/dist/allowance.js +487 -0
  8. package/dist/gui-experimental.cjs +1 -0
  9. package/dist/index.js +11111 -0
  10. package/dist/npm/index.js +40 -0
  11. package/dist/tui.js +587 -0
  12. package/docs/ARCHITECTURE.md +104 -0
  13. package/docs/DEBUGGING-GUI.md +70 -0
  14. package/docs/INSTALL.md +120 -0
  15. package/docs/LIMITATIONS.md +213 -0
  16. package/docs/MODELS.md +124 -0
  17. package/docs/OPENDESIGN-INTEGRATION.md +635 -0
  18. package/docs/QA.md +142 -0
  19. package/docs/SHARED-CORE.md +72 -0
  20. package/install +75 -0
  21. package/package.json +92 -4
  22. package/scripts/install.sh +324 -0
  23. package/scripts/uninstall.sh +91 -0
  24. package/src/allowance.ts +135 -0
  25. package/src/core/classify/classifier.ts +305 -0
  26. package/src/core/config-writer.ts +167 -0
  27. package/src/core/config.ts +1030 -0
  28. package/src/core/context/strategy.ts +188 -0
  29. package/src/core/context-health.ts +39 -0
  30. package/src/core/failures.ts +398 -0
  31. package/src/core/history/opencode.ts +173 -0
  32. package/src/core/models/protocol.ts +22 -0
  33. package/src/core/models/registry.ts +203 -0
  34. package/src/core/models/seed.ts +771 -0
  35. package/src/core/offline/mode.ts +321 -0
  36. package/src/core/plan-page.ts +390 -0
  37. package/src/core/plans/catalog.ts +481 -0
  38. package/src/core/policy/calibration.ts +259 -0
  39. package/src/core/policy/eligibility.ts +578 -0
  40. package/src/core/providers/enablement.ts +143 -0
  41. package/src/core/providers/opendesign-credits.ts +206 -0
  42. package/src/core/providers/opendesign-models.ts +628 -0
  43. package/src/core/providers/opendesign.ts +474 -0
  44. package/src/core/quota/calibration.ts +166 -0
  45. package/src/core/quota/commandcode.ts +471 -0
  46. package/src/core/quota/credentials.ts +490 -0
  47. package/src/core/quota/ledger.ts +1273 -0
  48. package/src/core/quota/opencode-go.ts +148 -0
  49. package/src/core/quota/opendesign.ts +1043 -0
  50. package/src/core/quota/reconcile.ts +155 -0
  51. package/src/core/quota/report.ts +261 -0
  52. package/src/core/quota/service.ts +273 -0
  53. package/src/core/reprompt.ts +48 -0
  54. package/src/core/routing/engine.ts +919 -0
  55. package/src/core/types.ts +825 -0
  56. package/src/core/ui.ts +236 -0
  57. package/src/core/util.ts +114 -0
  58. package/src/gui/index.tsx +1670 -0
  59. package/src/gui/viewmodel.ts +456 -0
  60. package/src/index.ts +48 -0
  61. package/src/rpc.ts +204 -0
  62. package/src/server/controller.ts +3281 -0
  63. package/src/server/route-tracker.ts +60 -0
  64. package/src/server/shared-core.ts +671 -0
  65. package/src/tui/index.tsx +168 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Prompt repair for providers whose wire protocol is stricter than the
3
+ * canonical context OpenCode builds.
4
+ *
5
+ * The Anthropic Messages protocol accepts only `user` and `assistant` as
6
+ * message roles. OpenCode turns mid-session notices ("Today's date...",
7
+ * "New instructions...") into `role: "system"` entries inside the message
8
+ * array; OpenAI-compatible gateways tolerate that, the Anthropic path
9
+ * rejects the whole turn with a 400 ("Invalid discriminator value. Expected
10
+ * 'user' | 'assistant'"). The router folds those entries into user messages
11
+ * before the request leaves, so the turn the model actually serves carries
12
+ * the same text with a role the strict path accepts.
13
+ *
14
+ * A leading `system` entry is deliberately never folded: the adapter hoists
15
+ * it into the system parameter, where Anthropic prompt caching is anchored.
16
+ */
17
+
18
+ export interface RepairMessagesInput {
19
+ readonly protocol: "anthropic" | "openai-compat"
20
+ }
21
+
22
+ export interface RepairMessagesResult {
23
+ readonly messages: ReadonlyArray<any>
24
+ readonly folded: number
25
+ }
26
+
27
+ export const repairMessages = (
28
+ messages: ReadonlyArray<any> | undefined,
29
+ input: RepairMessagesInput,
30
+ ): RepairMessagesResult => {
31
+ if (input.protocol !== "anthropic") return { messages: messages ?? [], folded: 0 }
32
+ if (!Array.isArray(messages)) return { messages: messages ?? [], folded: 0 }
33
+
34
+ let folded = 0
35
+ let anyFolded = false
36
+ const next = messages.map((message, index) => {
37
+ if (index === 0 || message === null || typeof message !== "object") {
38
+ return { message, changed: false }
39
+ }
40
+ if (message.role !== "system") return { message, changed: false }
41
+ folded += 1
42
+ anyFolded = true
43
+ return { message: { ...message, role: "user" }, changed: true }
44
+ })
45
+
46
+ if (!anyFolded) return { messages, folded: 0 }
47
+ return { messages: next.map((entry) => entry.message), folded }
48
+ }