@circuitwall/jarela 0.14.0 → 1.0.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 (164) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +1 -1
  3. package/.next/standalone/.next/build-manifest.json +2 -2
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  16. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  17. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  18. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  20. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  23. package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js +6 -1
  24. package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js.map +1 -1
  25. package/.next/standalone/.next/server/app/api/v1/agents/route.js +6 -1
  26. package/.next/standalone/.next/server/app/api/v1/agents/route.js.map +1 -1
  27. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +9 -1
  28. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.map +1 -1
  29. package/.next/standalone/.next/server/app/api/v1/bridges/route.js +9 -1
  30. package/.next/standalone/.next/server/app/api/v1/bridges/route.js.map +1 -1
  31. package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js +36 -29
  32. package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js.map +1 -1
  33. package/.next/standalone/.next/server/app/api/v1/events/route.js +7 -1
  34. package/.next/standalone/.next/server/app/api/v1/events/route.js.map +1 -1
  35. package/.next/standalone/.next/server/app/api/v1/extensions/route.js +3 -3
  36. package/.next/standalone/.next/server/app/api/v1/extensions/route.js.map +1 -1
  37. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js +4 -4
  38. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js.map +1 -1
  39. package/.next/standalone/.next/server/app/api/v1/health/route.js +7 -1
  40. package/.next/standalone/.next/server/app/api/v1/health/route.js.map +1 -1
  41. package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js +9 -1
  42. package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js.map +1 -1
  43. package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js +9 -1
  44. package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js.map +1 -1
  45. package/.next/standalone/.next/server/app/api/v1/models/route.js +6 -1
  46. package/.next/standalone/.next/server/app/api/v1/models/route.js.map +1 -1
  47. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js +7 -1
  48. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js.map +1 -1
  49. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js +14 -7
  50. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js.map +1 -1
  51. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +28 -0
  52. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js.map +1 -1
  53. package/.next/standalone/.next/server/app/api/v1/providers/route.js +7 -1
  54. package/.next/standalone/.next/server/app/api/v1/providers/route.js.map +1 -1
  55. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js +16 -2
  56. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js.map +1 -1
  57. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +8 -1
  58. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js.map +1 -1
  59. package/.next/standalone/.next/server/app/api/v1/threads/route.js +6 -1
  60. package/.next/standalone/.next/server/app/api/v1/threads/route.js.map +1 -1
  61. package/.next/standalone/.next/server/app/api/v1/tools/route.js +10 -3
  62. package/.next/standalone/.next/server/app/api/v1/tools/route.js.map +1 -1
  63. package/.next/standalone/.next/server/app/index.html +2 -2
  64. package/.next/standalone/.next/server/app/index.rsc +3 -3
  65. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  66. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  67. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  68. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  69. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  70. package/.next/standalone/.next/server/app/page.js +56 -0
  71. package/.next/standalone/.next/server/app/page.js.map +1 -1
  72. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/setup.html +1 -1
  75. package/.next/standalone/.next/server/app/setup.rsc +2 -2
  76. package/.next/standalone/.next/server/app/setup.segments/_full.segment.rsc +2 -2
  77. package/.next/standalone/.next/server/app/setup.segments/_head.segment.rsc +1 -1
  78. package/.next/standalone/.next/server/app/setup.segments/_index.segment.rsc +2 -2
  79. package/.next/standalone/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
  80. package/.next/standalone/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
  81. package/.next/standalone/.next/server/app/setup.segments/setup.segment.rsc +1 -1
  82. package/.next/standalone/.next/server/app-paths-manifest.json +1 -1
  83. package/.next/standalone/.next/server/chunks/1683.js +2 -2
  84. package/.next/standalone/.next/server/chunks/2082.js +122 -13
  85. package/.next/standalone/.next/server/chunks/2082.js.map +1 -1
  86. package/.next/standalone/.next/server/chunks/210.js +3 -3
  87. package/.next/standalone/.next/server/chunks/210.js.map +1 -1
  88. package/.next/standalone/.next/server/chunks/239.js +1902 -1487
  89. package/.next/standalone/.next/server/chunks/239.js.map +1 -1
  90. package/.next/standalone/.next/server/chunks/2447.js +9 -1
  91. package/.next/standalone/.next/server/chunks/2447.js.map +1 -1
  92. package/.next/standalone/.next/server/chunks/423.js +125 -16
  93. package/.next/standalone/.next/server/chunks/423.js.map +1 -1
  94. package/.next/standalone/.next/server/chunks/4631.js +36 -29
  95. package/.next/standalone/.next/server/chunks/4631.js.map +1 -1
  96. package/.next/standalone/.next/server/chunks/5937.js +3 -2
  97. package/.next/standalone/.next/server/chunks/5937.js.map +1 -1
  98. package/.next/standalone/.next/server/chunks/{947.js → 8866.js} +11321 -10883
  99. package/.next/standalone/.next/server/chunks/8866.js.map +1 -0
  100. package/.next/standalone/.next/server/chunks/9032.js +3 -3
  101. package/.next/standalone/.next/server/chunks/9032.js.map +1 -1
  102. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  103. package/.next/standalone/.next/server/middleware.js +122 -13
  104. package/.next/standalone/.next/server/pages/404.html +2 -2
  105. package/.next/standalone/.next/server/pages/500.html +1 -1
  106. package/.next/standalone/.next/server/proxy.js.map +1 -1
  107. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  108. package/.next/standalone/.next/static/chunks/app/{page-473b39ec30c7f569.js → page-a7cae65f235e2942.js} +57 -1
  109. package/.next/standalone/.next/static/chunks/app/page-a7cae65f235e2942.js.map +1 -0
  110. package/.next/standalone/.next/static/css/{6f8b1a84bcbcd467.css → e57bdbbbb5a05779.css} +2 -2
  111. package/.next/standalone/.next/static/css/e57bdbbbb5a05779.css.map +1 -0
  112. package/.next/standalone/package.json +9 -1
  113. package/CHANGELOG.md +90 -0
  114. package/README.md +30 -2
  115. package/api/types.ts +8 -0
  116. package/app/api/v1/agents/[id]/route.ts +7 -0
  117. package/app/api/v1/agents/route.ts +7 -0
  118. package/app/api/v1/events/route.ts +8 -0
  119. package/app/api/v1/extensions/route.ts +2 -2
  120. package/app/api/v1/extensions/tools/[name]/secrets/route.ts +3 -3
  121. package/app/api/v1/health/route.ts +8 -0
  122. package/app/api/v1/models/route.ts +7 -0
  123. package/app/api/v1/page-capture/route.ts +8 -0
  124. package/app/api/v1/providers/route.ts +8 -0
  125. package/app/api/v1/threads/[thread_id]/route.ts +8 -0
  126. package/app/api/v1/threads/[thread_id]/run/route.ts +9 -0
  127. package/app/api/v1/threads/route.ts +7 -0
  128. package/app/api/v1/tools/route.ts +9 -0
  129. package/components/chat/ContextUsageBar.tsx +44 -0
  130. package/lib/agents/llm.ts +25 -2
  131. package/lib/agents/run-thread.ts +13 -1
  132. package/lib/agents/stream-collector.ts +9 -1
  133. package/lib/api/serializers.test.ts +15 -0
  134. package/lib/api/serializers.ts +8 -0
  135. package/lib/db/migrations.ts +15 -0
  136. package/lib/health/runner.test.ts +24 -2
  137. package/lib/mcp/registry.ts +14 -6
  138. package/lib/providers/anthropic.test.ts +95 -0
  139. package/lib/providers/anthropic.ts +106 -10
  140. package/lib/providers/jarela-chat-model.ts +9 -1
  141. package/lib/providers/known-context-windows.ts +21 -0
  142. package/lib/providers/types.ts +21 -1
  143. package/lib/stores/message-usage.test.ts +34 -0
  144. package/lib/stores/message-usage.ts +15 -3
  145. package/lib/stores/pricing.test.ts +52 -0
  146. package/lib/stores/pricing.ts +26 -1
  147. package/lib/tools/builtins.ts +4 -0
  148. package/lib/tools/extension-surfaces.test.ts +79 -0
  149. package/lib/tools/extension-surfaces.ts +153 -0
  150. package/lib/tools/index.ts +27 -8
  151. package/lib/tools/list-tools.test.ts +76 -0
  152. package/lib/tools/list-tools.ts +84 -0
  153. package/lib/tools/mcp-servers-info.test.ts +73 -0
  154. package/lib/tools/mcp-servers-info.ts +71 -0
  155. package/lib/tools/providers-info.test.ts +73 -0
  156. package/lib/tools/providers-info.ts +106 -0
  157. package/lib/tools/registry.ts +36 -25
  158. package/lib/tools/types.ts +13 -0
  159. package/package.json +9 -1
  160. package/.next/standalone/.next/server/chunks/947.js.map +0 -1
  161. package/.next/standalone/.next/static/chunks/app/page-473b39ec30c7f569.js.map +0 -1
  162. package/.next/standalone/.next/static/css/6f8b1a84bcbcd467.css.map +0 -1
  163. /package/.next/standalone/.next/static/{T0p2VVPsJPj44rwbmjaFb → d_vhp-lJqfdjRFpnLVIqZ}/_buildManifest.js +0 -0
  164. /package/.next/standalone/.next/static/{T0p2VVPsJPj44rwbmjaFb → d_vhp-lJqfdjRFpnLVIqZ}/_ssgManifest.js +0 -0
@@ -0,0 +1,106 @@
1
+ // Read-only introspection for LLM provider adapters. Two paired tools:
2
+ // - list_providers: enumerate every adapter (built-in + external).
3
+ // - describe_provider: capability map + known model context windows for one.
4
+ // Together they let the agent answer "what can we route to" or pick a model
5
+ // by capability without hand-coded knowledge of the provider catalog.
6
+
7
+ import { tool } from "@langchain/core/tools";
8
+ import { z } from "zod";
9
+ import {
10
+ listProviderNames,
11
+ getProvider,
12
+ BUILTIN_PROVIDER_NAMES,
13
+ } from "@/lib/providers";
14
+ import { listKnownModels } from "@/lib/providers/known-context-windows";
15
+ import { registerTools } from "./registry";
16
+
17
+ type ProviderSource = "builtin" | "external";
18
+
19
+ function sourceOf(name: string): ProviderSource {
20
+ return BUILTIN_PROVIDER_NAMES.has(name) ? "builtin" : "external";
21
+ }
22
+
23
+ export const listProvidersTool = tool(
24
+ async () => {
25
+ const names = listProviderNames();
26
+ const providers = names.map((name) => ({
27
+ name,
28
+ source: sourceOf(name),
29
+ }));
30
+ return JSON.stringify({
31
+ providers,
32
+ count: providers.length,
33
+ builtin_count: providers.filter((p) => p.source === "builtin").length,
34
+ external_count: providers.filter((p) => p.source === "external").length,
35
+ });
36
+ },
37
+ {
38
+ name: "list_providers",
39
+ description:
40
+ "List every LLM provider adapter registered in this app (built-in like " +
41
+ "anthropic / openai / gemini / deepseek / github-copilot / langchain, plus " +
42
+ "any external `.cjs` plugins under ~/.jarela/providers/). Read-only. " +
43
+ "Use this before suggesting a model swap, or when answering 'what can " +
44
+ "we route to.' Call describe_provider afterwards for capability details.",
45
+ schema: z.object({}),
46
+ },
47
+ );
48
+
49
+ export const describeProviderTool = tool(
50
+ async ({ name }) => {
51
+ let provider;
52
+ try {
53
+ provider = getProvider(name);
54
+ } catch (err) {
55
+ return JSON.stringify({
56
+ error: err instanceof Error ? err.message : String(err),
57
+ hint: "Call list_providers to see registered names.",
58
+ });
59
+ }
60
+
61
+ // Capability inferred from which methods the adapter implements. We
62
+ // intentionally don't call listModels() here — that would hit the
63
+ // network and require valid credentials, which makes this a "read"-class
64
+ // tool that sometimes fails for credential reasons. Static introspection
65
+ // only.
66
+ const capabilities = {
67
+ chat: typeof provider.chat === "function",
68
+ invoke: typeof provider.invoke === "function",
69
+ stream_invoke: typeof provider.streamInvoke === "function",
70
+ embed: typeof provider.embed === "function",
71
+ list_models: typeof provider.listModels === "function",
72
+ };
73
+
74
+ const models = listKnownModels(name);
75
+
76
+ return JSON.stringify({
77
+ name,
78
+ source: sourceOf(name),
79
+ capabilities,
80
+ known_models: models,
81
+ notes: [
82
+ models.length === 0
83
+ ? "No static model catalog for this provider — call /api/v1/models?provider=" +
84
+ name + " for live discovery if the adapter implements list_models."
85
+ : "Static catalog only. Live `list_models` (when supported) may include " +
86
+ "newer models not listed here.",
87
+ ],
88
+ });
89
+ },
90
+ {
91
+ name: "describe_provider",
92
+ description:
93
+ "Return capability flags (chat / invoke / stream / embed / list_models) " +
94
+ "and the static known-models catalog (with context windows) for one " +
95
+ "registered provider. Read-only. Use this to choose a model by capability, " +
96
+ "or to explain provider differences to the user. Call list_providers first " +
97
+ "if you don't know the provider name.",
98
+ schema: z.object({
99
+ name: z
100
+ .string()
101
+ .describe("Provider name from list_providers, e.g. 'anthropic', 'openai', 'gemini'"),
102
+ }),
103
+ },
104
+ );
105
+
106
+ registerTools("Config", "read", [listProvidersTool, describeProviderTool]);
@@ -1,25 +1,33 @@
1
- // Tool registry.
2
- //
3
- // Each built-in tool module registers its own tools at module load with
4
- // two orthogonal axes:
5
- //
6
- // * category — topical group ("Memory", "Files", "Mail", …) used by
7
- // the Agent editor sidebar to organise tools for users.
8
- // * capability safety class ("read" | "write" | "execute") used by
9
- // the future per-capability approval gate, UI badges,
10
- // and the ADR-0037 output validator. See ADR-0038.
11
- //
12
- // lib/tools/index.ts only needs to side-effect-import the modules
13
- // (see ./builtins.ts) there is no central map listing every tool by
14
- // name. Adding a new built-in tool now requires touching exactly two
15
- // files: the tool file itself, and an `import "./<name>";` line in
16
- // builtins.ts.
17
- //
18
- // External tools (loaded from JARELA_TOOLS_DIR at runtime) use the same
19
- // category vocabulary but are not stored in this registry see
20
- // ./external.ts. MCP tools default to category "MCP". Both default to
21
- // capability "execute" until manifest-level overrides land (ADR-0038
22
- // follow-up).
1
+ /**
2
+ * Tool registry.
3
+ *
4
+ * Each built-in tool module registers its own tools at module load with
5
+ * two orthogonal axes:
6
+ *
7
+ * - category — topical group ("Memory", "Files", "Mail", …) used by
8
+ * the Agent editor sidebar to organise tools for users.
9
+ * - capability safety class ("read" | "write" | "execute") used by
10
+ * the future per-capability approval gate, UI badges,
11
+ * and the ADR-0037 output validator. See ADR-0038.
12
+ *
13
+ * `lib/tools/index.ts` only needs to side-effect-import the modules
14
+ * (see ./builtins.ts) there is no central map listing every tool by
15
+ * name. Adding a new built-in tool now requires touching exactly two
16
+ * files: the tool file itself, and an `import "./<name>";` line in
17
+ * builtins.ts.
18
+ *
19
+ * External tools (loaded from JARELA_TOOLS_DIR at runtime) use the same
20
+ * category vocabulary but are not stored in this registry — see
21
+ * ./external.ts. MCP tools default to category "MCP". Both default to
22
+ * capability "execute" until manifest-level overrides land (ADR-0038
23
+ * follow-up).
24
+ *
25
+ * Public surface (per `package.json#exports`): `ToolCategory`,
26
+ * `Capability`, `ToolGroup`, `BuiltinCategory`, `registerTools`.
27
+ * Everything else (`registeredTools` / `registeredNames` /
28
+ * `registeredCategory` / etc.) is `@internal` — used only by the in-tree
29
+ * runtime, not part of the plugin contract.
30
+ */
23
31
 
24
32
  import type { StructuredToolInterface } from "@langchain/core/tools";
25
33
  import { wrapWithWallclock } from "./wallclock";
@@ -81,29 +89,32 @@ export function registerTools<T extends StructuredToolInterface>(
81
89
  return wrapped;
82
90
  }
83
91
 
84
- /** All registered built-in tools, in registration order. */
92
+ /** @internal — all registered built-in tools, in registration order. */
85
93
  export function registeredTools(): StructuredToolInterface[] {
86
94
  return Array.from(REGISTRY.values(), (e) => e.tool);
87
95
  }
88
96
 
89
- /** Names of all registered built-in tools used for collision checks. */
97
+ /** @internal — names of all registered built-in tools, used for collision checks. */
90
98
  export function registeredNames(): ReadonlySet<string> {
91
99
  return new Set(REGISTRY.keys());
92
100
  }
93
101
 
102
+ /** @internal */
94
103
  export function registeredCategory(name: string): BuiltinCategory | undefined {
95
104
  return REGISTRY.get(name)?.category;
96
105
  }
97
106
 
107
+ /** @internal */
98
108
  export function registeredCapability(name: string): Capability | undefined {
99
109
  return REGISTRY.get(name)?.capability;
100
110
  }
101
111
 
112
+ /** @internal */
102
113
  export function registeredGroup(name: string): ToolGroup | undefined {
103
114
  return REGISTRY.get(name)?.group;
104
115
  }
105
116
 
106
- /** Test-only: clear the registry between cases. */
117
+ /** @internal — test-only: clear the registry between cases. */
107
118
  export function _resetRegistry(): void {
108
119
  REGISTRY.clear();
109
120
  }
@@ -1,3 +1,16 @@
1
+ /**
2
+ * @public
3
+ *
4
+ * Public tool extension contract.
5
+ *
6
+ * Every type and interface in this file is part of the package's
7
+ * stable public surface (per `package.json#exports`). External tool
8
+ * authors — both in-tree built-ins and `~/.jarela/tools/*.cjs` plugins —
9
+ * use these to describe arguments, results, and message shapes. Removing
10
+ * or breaking any export here counts as a breaking change under the
11
+ * deprecation policy in CONTRIBUTING.md.
12
+ */
13
+
1
14
  import type { StructuredToolInterface } from "@langchain/core/tools";
2
15
 
3
16
  // LangGraph/LangChain-compatible tool type. All tools implement this interface.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@circuitwall/jarela",
3
- "version": "0.14.0",
3
+ "version": "1.0.0",
4
4
  "description": "Jarela — local chat interface for LangGraph agents (multi-provider, single-process, SQLite-backed).",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Andrew Ge Wu",
@@ -34,6 +34,14 @@
34
34
  "engines": {
35
35
  "node": ">=22"
36
36
  },
37
+ "exports": {
38
+ ".": null,
39
+ "./package.json": "./package.json",
40
+ "./lib/providers/types": "./lib/providers/types.ts",
41
+ "./lib/tools/types": "./lib/tools/types.ts",
42
+ "./lib/tools/registry": "./lib/tools/registry.ts",
43
+ "./lib/mcp/registry": "./lib/mcp/registry.ts"
44
+ },
37
45
  "files": [
38
46
  ".next/standalone",
39
47
  "!.next/standalone/public/sw.js",