clanka 0.8.0 → 0.8.1

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 (185) hide show
  1. package/dist/Acp.d.ts +4 -4
  2. package/dist/Acp.d.ts.map +1 -1
  3. package/dist/Acp.js +6 -6
  4. package/dist/Acp.js.map +1 -1
  5. package/dist/Acp.test.js +4 -4
  6. package/dist/Acp.test.js.map +1 -1
  7. package/dist/AcpImage.test.js +7 -7
  8. package/dist/AcpImage.test.js.map +1 -1
  9. package/dist/Agent.d.ts +8 -8
  10. package/dist/Agent.d.ts.map +1 -1
  11. package/dist/Agent.js +7 -7
  12. package/dist/Agent.js.map +1 -1
  13. package/dist/Agent.test.js +6 -6
  14. package/dist/Agent.test.js.map +1 -1
  15. package/dist/AgentExecutor.d.ts +9 -9
  16. package/dist/AgentExecutor.d.ts.map +1 -1
  17. package/dist/AgentExecutor.js +5 -5
  18. package/dist/AgentExecutor.js.map +1 -1
  19. package/dist/AgentExecutorImage.test.js +6 -6
  20. package/dist/AgentExecutorImage.test.js.map +1 -1
  21. package/dist/AgentImage.test.js +3 -3
  22. package/dist/AgentImage.test.js.map +1 -1
  23. package/dist/AgentOutput.d.ts +2 -2
  24. package/dist/AgentOutput.d.ts.map +1 -1
  25. package/dist/AgentOutput.js +2 -2
  26. package/dist/AgentOutput.js.map +1 -1
  27. package/dist/AgentSkills.d.ts.map +1 -1
  28. package/dist/AgentSkills.js +6 -1
  29. package/dist/AgentSkills.js.map +1 -1
  30. package/dist/AgentSkills.test.js +21 -4
  31. package/dist/AgentSkills.test.js.map +1 -1
  32. package/dist/AgentTools.d.ts +4 -4
  33. package/dist/AgentTools.d.ts.map +1 -1
  34. package/dist/AgentTools.js +4 -4
  35. package/dist/AgentTools.js.map +1 -1
  36. package/dist/AgentToolsImage.test.js +2 -2
  37. package/dist/AgentToolsImage.test.js.map +1 -1
  38. package/dist/ChunkRepo.d.ts +10 -10
  39. package/dist/ChunkRepo.d.ts.map +1 -1
  40. package/dist/ChunkRepo.js +7 -7
  41. package/dist/ChunkRepo.js.map +1 -1
  42. package/dist/ChunkRepo.test.js +2 -2
  43. package/dist/ChunkRepo.test.js.map +1 -1
  44. package/dist/CodeChunker.d.ts +1 -1
  45. package/dist/CodeChunker.d.ts.map +1 -1
  46. package/dist/CodeChunker.js +2 -2
  47. package/dist/CodeChunker.js.map +1 -1
  48. package/dist/Codex.d.ts +5 -5
  49. package/dist/Codex.d.ts.map +1 -1
  50. package/dist/Codex.js +1 -1
  51. package/dist/Codex.js.map +1 -1
  52. package/dist/CodexAuth.d.ts +2 -2
  53. package/dist/CodexAuth.d.ts.map +1 -1
  54. package/dist/CodexAuth.js +6 -6
  55. package/dist/CodexAuth.js.map +1 -1
  56. package/dist/CodexAuth.test.js +3 -3
  57. package/dist/CodexAuth.test.js.map +1 -1
  58. package/dist/Compaction.d.ts +3 -3
  59. package/dist/Compaction.d.ts.map +1 -1
  60. package/dist/Compaction.js +3 -3
  61. package/dist/Compaction.js.map +1 -1
  62. package/dist/Compaction.test.js +3 -3
  63. package/dist/Compaction.test.js.map +1 -1
  64. package/dist/CompactionImage.test.js +4 -4
  65. package/dist/CompactionImage.test.js.map +1 -1
  66. package/dist/CompactionTokens.test.js +3 -3
  67. package/dist/CompactionTokens.test.js.map +1 -1
  68. package/dist/CompactionTransport.test.js +5 -5
  69. package/dist/CompactionTransport.test.js.map +1 -1
  70. package/dist/Copilot.d.ts +3 -3
  71. package/dist/Copilot.d.ts.map +1 -1
  72. package/dist/Copilot.js +1 -1
  73. package/dist/Copilot.js.map +1 -1
  74. package/dist/CopilotAuth.d.ts +2 -2
  75. package/dist/CopilotAuth.d.ts.map +1 -1
  76. package/dist/CopilotAuth.js +4 -4
  77. package/dist/CopilotAuth.js.map +1 -1
  78. package/dist/CopilotAuth.test.js +2 -2
  79. package/dist/CopilotAuth.test.js.map +1 -1
  80. package/dist/GlobalWebSocket.d.ts +1 -1
  81. package/dist/GlobalWebSocket.d.ts.map +1 -1
  82. package/dist/GlobalWebSocket.js +1 -1
  83. package/dist/GlobalWebSocket.js.map +1 -1
  84. package/dist/Image.d.ts +2 -2
  85. package/dist/Image.d.ts.map +1 -1
  86. package/dist/Image.js +3 -3
  87. package/dist/Image.js.map +1 -1
  88. package/dist/Image.test.js +2 -2
  89. package/dist/Image.test.js.map +1 -1
  90. package/dist/SemanticSearch.d.ts +3 -3
  91. package/dist/SemanticSearch.d.ts.map +1 -1
  92. package/dist/SemanticSearch.js +1 -1
  93. package/dist/SemanticSearch.js.map +1 -1
  94. package/dist/Sqlite.d.ts +2 -2
  95. package/dist/Sqlite.d.ts.map +1 -1
  96. package/dist/Sqlite.js +1 -1
  97. package/dist/Sqlite.js.map +1 -1
  98. package/dist/ToolkitRenderer.d.ts +2 -2
  99. package/dist/ToolkitRenderer.d.ts.map +1 -1
  100. package/dist/WebToMarkdown.d.ts +2 -2
  101. package/dist/WebToMarkdown.d.ts.map +1 -1
  102. package/dist/WebToMarkdown.js +1 -1
  103. package/dist/WebToMarkdown.js.map +1 -1
  104. package/dist/WebToMarkdown.test.js +1 -1
  105. package/dist/WebToMarkdown.test.js.map +1 -1
  106. package/dist/Xai.d.ts +10 -3
  107. package/dist/Xai.d.ts.map +1 -1
  108. package/dist/Xai.js +26 -2
  109. package/dist/Xai.js.map +1 -1
  110. package/dist/Xai.test.js +38 -4
  111. package/dist/Xai.test.js.map +1 -1
  112. package/dist/XaiAuth.d.ts +2 -2
  113. package/dist/XaiAuth.d.ts.map +1 -1
  114. package/dist/XaiAuth.js +4 -4
  115. package/dist/XaiAuth.js.map +1 -1
  116. package/dist/XaiAuth.test.js +2 -2
  117. package/dist/XaiAuth.test.js.map +1 -1
  118. package/dist/bin/{Effect-CeAMoJlg.mjs → Effect-DvI8YVcR.mjs} +81 -387
  119. package/dist/bin/Effect-DvI8YVcR.mjs.map +1 -0
  120. package/dist/bin/{McpClient-zQibhsnA.mjs → McpClient-CM7u8ZVd.mjs} +3 -3
  121. package/dist/bin/{McpClient-zQibhsnA.mjs.map → McpClient-CM7u8ZVd.mjs.map} +1 -1
  122. package/dist/bin/{OutputFormatter-C7Awn0DS.mjs → OutputFormatter-BpggeGvI.mjs} +3 -3
  123. package/dist/bin/{OutputFormatter-C7Awn0DS.mjs.map → OutputFormatter-BpggeGvI.mjs.map} +1 -1
  124. package/dist/bin/{Schema-Bc06DxcV.mjs → Schema-DyJ738Wp.mjs} +1979 -1663
  125. package/dist/bin/Schema-DyJ738Wp.mjs.map +1 -0
  126. package/dist/bin/{SemanticSearch-BPxQoRSC.mjs → SemanticSearch-BHUGFT1y.mjs} +46 -42
  127. package/dist/bin/SemanticSearch-BHUGFT1y.mjs.map +1 -0
  128. package/dist/bin/{Stream-DlGXvw0L.mjs → Stream-Dg7AGCgJ.mjs} +60 -61
  129. package/dist/bin/Stream-Dg7AGCgJ.mjs.map +1 -0
  130. package/dist/bin/cli.mjs +601 -368
  131. package/dist/bin/cli.mjs.map +1 -1
  132. package/dist/cli.js +7 -5
  133. package/dist/cli.js.map +1 -1
  134. package/dist/fixtures/TestImages.js +2 -2
  135. package/dist/fixtures/TestImages.js.map +1 -1
  136. package/package.json +7 -7
  137. package/src/Acp.test.ts +5 -5
  138. package/src/Acp.ts +8 -8
  139. package/src/AcpImage.test.ts +9 -9
  140. package/src/Agent.test.ts +7 -7
  141. package/src/Agent.ts +10 -10
  142. package/src/AgentExecutor.ts +8 -8
  143. package/src/AgentExecutorImage.test.ts +6 -6
  144. package/src/AgentImage.test.ts +5 -5
  145. package/src/AgentOutput.ts +2 -2
  146. package/src/AgentSkills.test.ts +81 -37
  147. package/src/AgentSkills.ts +5 -1
  148. package/src/AgentTools.ts +5 -5
  149. package/src/AgentToolsImage.test.ts +4 -4
  150. package/src/ChunkRepo.test.ts +2 -2
  151. package/src/ChunkRepo.ts +7 -7
  152. package/src/CodeChunker.ts +2 -2
  153. package/src/Codex.ts +4 -4
  154. package/src/CodexAuth.test.ts +3 -3
  155. package/src/CodexAuth.ts +6 -6
  156. package/src/Compaction.test.ts +3 -3
  157. package/src/Compaction.ts +3 -3
  158. package/src/CompactionImage.test.ts +4 -4
  159. package/src/CompactionTokens.test.ts +3 -3
  160. package/src/CompactionTransport.test.ts +6 -6
  161. package/src/Copilot.ts +2 -2
  162. package/src/CopilotAuth.test.ts +2 -6
  163. package/src/CopilotAuth.ts +4 -4
  164. package/src/GlobalWebSocket.ts +1 -1
  165. package/src/Image.test.ts +2 -2
  166. package/src/Image.ts +4 -4
  167. package/src/OutputFormatter.ts +1 -1
  168. package/src/SemanticSearch.test.ts +1 -1
  169. package/src/SemanticSearch.ts +3 -3
  170. package/src/Sqlite.ts +1 -1
  171. package/src/ToolkitRenderer.ts +2 -2
  172. package/src/WebToMarkdown.test.ts +1 -1
  173. package/src/WebToMarkdown.ts +2 -2
  174. package/src/Xai.test.ts +67 -8
  175. package/src/Xai.ts +52 -3
  176. package/src/XaiAuth.test.ts +2 -2
  177. package/src/XaiAuth.ts +4 -4
  178. package/src/cli.ts +9 -7
  179. package/src/fixtures/TestImages.ts +2 -2
  180. package/src/fixtures/patch13-broken.txt +4 -4
  181. package/src/fixtures/patch13-fixed.txt +4 -4
  182. package/dist/bin/Effect-CeAMoJlg.mjs.map +0 -1
  183. package/dist/bin/Schema-Bc06DxcV.mjs.map +0 -1
  184. package/dist/bin/SemanticSearch-BPxQoRSC.mjs.map +0 -1
  185. package/dist/bin/Stream-DlGXvw0L.mjs.map +0 -1
@@ -9,7 +9,7 @@ import * as Option from "effect/Option"
9
9
  import * as Path from "effect/Path"
10
10
  import * as Predicate from "effect/Predicate"
11
11
  import * as Schema from "effect/Schema"
12
- import * as Yaml from "effect/unstable/encoding/Yaml"
12
+ import * as Yaml from "effect/encoding/Yaml"
13
13
 
14
14
  /**
15
15
  * @since 1.0.0
@@ -90,6 +90,10 @@ export const discover: (options: {
90
90
  .pipe(Effect.orElseSucceed(() => []))
91
91
  entries.sort()
92
92
  for (const entry of entries) {
93
+ const files = yield* fs
94
+ .readDirectory(path.join(skillsDir, entry))
95
+ .pipe(Effect.orElseSucceed((): Array<string> => []))
96
+ if (!files.includes("SKILL.md")) continue
93
97
  const location = path.join(skillsDir, entry, "SKILL.md")
94
98
  const content = yield* Effect.option(
95
99
  fs.stat(location).pipe(
package/src/AgentTools.ts CHANGED
@@ -5,16 +5,16 @@
5
5
  import { parsePatch, patchChunks } from "./ApplyPatch.ts"
6
6
  import * as ExaSearch from "./ExaSearch.ts"
7
7
  import * as WebToMarkdown from "./WebToMarkdown.ts"
8
- import type * as HttpClient from "effect/unstable/http/HttpClient"
8
+ import type * as HttpClient from "effect/http/HttpClient"
9
9
  import * as Context from "effect/Context"
10
10
  import * as Effect from "effect/Effect"
11
- import * as Toolkit from "effect/unstable/ai/Toolkit"
12
- import * as Tool from "effect/unstable/ai/Tool"
11
+ import * as Toolkit from "effect/ai/Toolkit"
12
+ import * as Tool from "effect/ai/Tool"
13
13
  import * as Schema from "effect/Schema"
14
- import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner"
14
+ import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner"
15
15
  import * as FileSystem from "effect/FileSystem"
16
16
  import * as Path from "effect/Path"
17
- import * as ChildProcess from "effect/unstable/process/ChildProcess"
17
+ import * as ChildProcess from "effect/process/ChildProcess"
18
18
  import * as Stream from "effect/Stream"
19
19
  import { pipe } from "effect/Function"
20
20
  import * as Array from "effect/Array"
@@ -10,10 +10,10 @@ import * as FileSystem from "effect/FileSystem"
10
10
  import * as Layer from "effect/Layer"
11
11
  import * as Path from "effect/Path"
12
12
  import * as Stream from "effect/Stream"
13
- import * as LanguageModel from "effect/unstable/ai/LanguageModel"
14
- import * as Model from "effect/unstable/ai/Model"
15
- import type * as Prompt from "effect/unstable/ai/Prompt"
16
- import type * as Response from "effect/unstable/ai/Response"
13
+ import * as LanguageModel from "effect/ai/LanguageModel"
14
+ import * as Model from "effect/ai/Model"
15
+ import type * as Prompt from "effect/ai/Prompt"
16
+ import type * as Response from "effect/ai/Response"
17
17
  import * as Agent from "./Agent.ts"
18
18
  import * as AgentExecutor from "./AgentExecutor.ts"
19
19
  import type * as AgentOutput from "./AgentOutput.ts"
@@ -5,8 +5,8 @@ import * as NodeServices from "@effect/platform-node/NodeServices"
5
5
  import { assert, describe, it } from "@effect/vitest"
6
6
  import * as Effect from "effect/Effect"
7
7
  import * as Layer from "effect/Layer"
8
- import * as EmbeddingModel from "effect/unstable/ai/EmbeddingModel"
9
- import * as SqlClient from "effect/unstable/sql/SqlClient"
8
+ import * as EmbeddingModel from "effect/ai/EmbeddingModel"
9
+ import * as SqlClient from "effect/sql/SqlClient"
10
10
  import { Chunk, ChunkRepo, layer, SyncId } from "./ChunkRepo.ts"
11
11
  import { SqliteLayer } from "./Sqlite.ts"
12
12
 
package/src/ChunkRepo.ts CHANGED
@@ -4,15 +4,15 @@ import * as Layer from "effect/Layer"
4
4
  import * as Schema from "effect/Schema"
5
5
  import * as SchemaTransformation from "effect/SchemaTransformation"
6
6
  import * as Context from "effect/Context"
7
- import * as Model from "effect/unstable/schema/Model"
8
- import * as SqlClient from "effect/unstable/sql/SqlClient"
9
- import * as SqlError from "effect/unstable/sql/SqlError"
10
- import * as SqlModel from "effect/unstable/sql/SqlModel"
11
- import * as SqlSchema from "effect/unstable/sql/SqlSchema"
7
+ import * as Model from "effect/schema/Model"
8
+ import * as SqlClient from "effect/sql/SqlClient"
9
+ import * as SqlError from "effect/sql/SqlError"
10
+ import * as SqlModel from "effect/sql/SqlModel"
11
+ import * as SqlSchema from "effect/sql/SqlSchema"
12
12
  import type * as Cause from "effect/Cause"
13
13
  import type * as Option from "effect/Option"
14
- import * as EmbeddingModel from "effect/unstable/ai/EmbeddingModel"
15
- import * as SqlResolver from "effect/unstable/sql/SqlResolver"
14
+ import * as EmbeddingModel from "effect/ai/EmbeddingModel"
15
+ import * as SqlResolver from "effect/sql/SqlResolver"
16
16
  import * as RequestResolver from "effect/RequestResolver"
17
17
 
18
18
  /**
@@ -9,8 +9,8 @@ import * as Layer from "effect/Layer"
9
9
  import * as Path from "effect/Path"
10
10
  import * as Context from "effect/Context"
11
11
  import * as Stream from "effect/Stream"
12
- import * as ChildProcess from "effect/unstable/process/ChildProcess"
13
- import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner"
12
+ import * as ChildProcess from "effect/process/ChildProcess"
13
+ import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner"
14
14
  import TreeSitter, { type SyntaxNode } from "tree-sitter"
15
15
  import TreeSitterJavaScript from "tree-sitter-javascript"
16
16
  import TreeSitterTypeScript from "tree-sitter-typescript"
package/src/Codex.ts CHANGED
@@ -6,10 +6,10 @@ import * as Layer from "effect/Layer"
6
6
  import * as Struct from "effect/Struct"
7
7
  import { CodexAuth } from "./CodexAuth.ts"
8
8
  import { AgentModelConfig } from "./Agent.ts"
9
- import * as Model from "effect/unstable/ai/Model"
10
- import type * as LanguageModel from "effect/unstable/ai/LanguageModel"
11
- import type * as Socket from "effect/unstable/socket/Socket"
12
- import type * as ResponseIdTracker from "effect/unstable/ai/ResponseIdTracker"
9
+ import * as Model from "effect/ai/Model"
10
+ import type * as LanguageModel from "effect/ai/LanguageModel"
11
+ import type * as Socket from "effect/socket/Socket"
12
+ import type * as ResponseIdTracker from "effect/ai/ResponseIdTracker"
13
13
 
14
14
  /**
15
15
  * @since 1.0.0
@@ -1,8 +1,8 @@
1
1
  import { assert, describe, it } from "@effect/vitest"
2
2
  import * as Effect from "effect/Effect"
3
- import * as Encoding from "effect/Encoding"
3
+ import * as Base64Url from "effect/encoding/Base64Url"
4
4
  import * as Option from "effect/Option"
5
- import * as KeyValueStore from "effect/unstable/persistence/KeyValueStore"
5
+ import * as KeyValueStore from "effect/persistence/KeyValueStore"
6
6
  import {
7
7
  CodexAuthError,
8
8
  STORE_PREFIX,
@@ -17,7 +17,7 @@ import {
17
17
  } from "./CodexAuth.ts"
18
18
 
19
19
  const createJwt = (payload: string): string =>
20
- `${Encoding.encodeBase64Url(JSON.stringify({ alg: "none" }))}.${Encoding.encodeBase64Url(payload)}.sig`
20
+ `${Base64Url.encode(JSON.stringify({ alg: "none" }))}.${Base64Url.encode(payload)}.sig`
21
21
 
22
22
  const createTestJwt = (payload: Record<string, unknown>): string =>
23
23
  createJwt(JSON.stringify(payload))
package/src/CodexAuth.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  */
4
4
  /** @effect-diagnostics schemaNumber:off */
5
5
  import * as Effect from "effect/Effect"
6
- import * as Encoding from "effect/Encoding"
6
+ import * as Base64Url from "effect/encoding/Base64Url"
7
7
  import * as Function from "effect/Function"
8
8
  import * as Layer from "effect/Layer"
9
9
  import * as Option from "effect/Option"
@@ -12,10 +12,10 @@ import * as Schedule from "effect/Schedule"
12
12
  import * as Schema from "effect/Schema"
13
13
  import * as Semaphore from "effect/Semaphore"
14
14
  import * as Context from "effect/Context"
15
- import * as HttpClient from "effect/unstable/http/HttpClient"
16
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
17
- import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
18
- import * as KeyValueStore from "effect/unstable/persistence/KeyValueStore"
15
+ import * as HttpClient from "effect/http/HttpClient"
16
+ import * as HttpClientRequest from "effect/http/HttpClientRequest"
17
+ import * as HttpClientResponse from "effect/http/HttpClientResponse"
18
+ import * as KeyValueStore from "effect/persistence/KeyValueStore"
19
19
  import { DeviceCodeHandler } from "./DeviceCodeHandler.ts"
20
20
 
21
21
  export const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann"
@@ -158,7 +158,7 @@ const decodeJwtPayload = (token: string): Option.Option<string> => {
158
158
  }
159
159
 
160
160
  return Option.fromNullishOr(
161
- Result.getOrUndefined(Encoding.decodeBase64UrlString(payload)),
161
+ Result.getOrUndefined(Base64Url.decodeString(payload)),
162
162
  )
163
163
  }
164
164
 
@@ -1,9 +1,9 @@
1
1
  import { assert, describe, it } from "@effect/vitest"
2
2
  import * as Effect from "effect/Effect"
3
3
  import * as Option from "effect/Option"
4
- import * as AiError from "effect/unstable/ai/AiError"
5
- import * as Prompt from "effect/unstable/ai/Prompt"
6
- import * as ResponseIdTracker from "effect/unstable/ai/ResponseIdTracker"
4
+ import * as AiError from "effect/ai/AiError"
5
+ import * as Prompt from "effect/ai/Prompt"
6
+ import * as ResponseIdTracker from "effect/ai/ResponseIdTracker"
7
7
  import * as Compaction from "./Compaction.ts"
8
8
 
9
9
  // -----------------------------------------------------------------------------
package/src/Compaction.ts CHANGED
@@ -19,9 +19,9 @@ import * as Layer from "effect/Layer"
19
19
  import * as Option from "effect/Option"
20
20
  import * as Predicate from "effect/Predicate"
21
21
  import * as Stream from "effect/Stream"
22
- import * as AiError from "effect/unstable/ai/AiError"
23
- import * as LanguageModel from "effect/unstable/ai/LanguageModel"
24
- import * as Prompt from "effect/unstable/ai/Prompt"
22
+ import * as AiError from "effect/ai/AiError"
23
+ import * as LanguageModel from "effect/ai/LanguageModel"
24
+ import * as Prompt from "effect/ai/Prompt"
25
25
  import type * as AgentOutput from "./AgentOutput.ts"
26
26
  import * as Image from "./Image.ts"
27
27
 
@@ -1,15 +1,15 @@
1
1
  import { assert, describe, it } from "@effect/vitest"
2
2
  import * as Effect from "effect/Effect"
3
- import * as Encoding from "effect/Encoding"
3
+ import * as Base64 from "effect/encoding/Base64"
4
4
  import * as Layer from "effect/Layer"
5
5
  import * as Option from "effect/Option"
6
6
  import * as Stream from "effect/Stream"
7
- import * as LanguageModel from "effect/unstable/ai/LanguageModel"
8
- import * as Prompt from "effect/unstable/ai/Prompt"
7
+ import * as LanguageModel from "effect/ai/LanguageModel"
8
+ import * as Prompt from "effect/ai/Prompt"
9
9
  import * as Compaction from "./Compaction.ts"
10
10
  import { tinyPng } from "./fixtures/TestImages.ts"
11
11
 
12
- const base64 = Encoding.encodeBase64(tinyPng)
12
+ const base64 = Base64.encode(tinyPng)
13
13
 
14
14
  const user = (text: string) =>
15
15
  Prompt.makeMessage("user", {
@@ -1,8 +1,8 @@
1
1
  import { assert, describe, it } from "@effect/vitest"
2
- import * as Encoding from "effect/Encoding"
2
+ import * as Base64 from "effect/encoding/Base64"
3
3
  import * as Option from "effect/Option"
4
4
  import * as Schema from "effect/Schema"
5
- import * as Prompt from "effect/unstable/ai/Prompt"
5
+ import * as Prompt from "effect/ai/Prompt"
6
6
  import * as Compaction from "./Compaction.ts"
7
7
 
8
8
  const text = (value: string) => Prompt.makePart("text", { text: value })
@@ -141,7 +141,7 @@ describe("Compaction image token estimates", () => {
141
141
  if (image.type !== "file") return
142
142
  assert.strictEqual(
143
143
  image.data,
144
- Encoding.encodeBase64(new Uint8Array(1024).fill(137)),
144
+ Base64.encode(new Uint8Array(1024).fill(137)),
145
145
  )
146
146
  assert.strictEqual(
147
147
  Compaction.estimateTokens(restored),
@@ -6,12 +6,12 @@ import * as Exit from "effect/Exit"
6
6
  import * as Layer from "effect/Layer"
7
7
  import * as Option from "effect/Option"
8
8
  import * as Stream from "effect/Stream"
9
- import * as AiError from "effect/unstable/ai/AiError"
10
- import * as LanguageModel from "effect/unstable/ai/LanguageModel"
11
- import * as Prompt from "effect/unstable/ai/Prompt"
12
- import * as HttpClient from "effect/unstable/http/HttpClient"
13
- import type * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
14
- import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
9
+ import * as AiError from "effect/ai/AiError"
10
+ import * as LanguageModel from "effect/ai/LanguageModel"
11
+ import * as Prompt from "effect/ai/Prompt"
12
+ import * as HttpClient from "effect/http/HttpClient"
13
+ import type * as HttpClientRequest from "effect/http/HttpClientRequest"
14
+ import * as HttpClientResponse from "effect/http/HttpClientResponse"
15
15
  import * as Codex from "./Codex.ts"
16
16
  import * as Compaction from "./Compaction.ts"
17
17
  import * as Copilot from "./Copilot.ts"
package/src/Copilot.ts CHANGED
@@ -7,8 +7,8 @@ import * as Struct from "effect/Struct"
7
7
  import { API_URL, GithubCopilotAuth } from "./CopilotAuth.ts"
8
8
  import { AgentModelConfig } from "./Agent.ts"
9
9
  import * as Compaction from "./Compaction.ts"
10
- import * as Model from "effect/unstable/ai/Model"
11
- import type * as LanguageModel from "effect/unstable/ai/LanguageModel"
10
+ import * as Model from "effect/ai/Model"
11
+ import type * as LanguageModel from "effect/ai/LanguageModel"
12
12
 
13
13
  /**
14
14
  * @since 1.0.0
@@ -4,12 +4,8 @@ import * as Effect from "effect/Effect"
4
4
  import * as Fiber from "effect/Fiber"
5
5
  import * as Option from "effect/Option"
6
6
  import * as Ref from "effect/Ref"
7
- import {
8
- HttpClient,
9
- HttpClientRequest,
10
- HttpClientResponse,
11
- } from "effect/unstable/http"
12
- import * as KeyValueStore from "effect/unstable/persistence/KeyValueStore"
7
+ import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/http"
8
+ import * as KeyValueStore from "effect/persistence/KeyValueStore"
13
9
  import {
14
10
  COPILOT_VISION_REQUEST_HEADER,
15
11
  DEFAULT_OPENAI_INTENT,
@@ -10,10 +10,10 @@ import * as Schedule from "effect/Schedule"
10
10
  import * as Schema from "effect/Schema"
11
11
  import * as Semaphore from "effect/Semaphore"
12
12
  import * as Context from "effect/Context"
13
- import * as HttpClient from "effect/unstable/http/HttpClient"
14
- import * as HttpClientRequest from "effect/unstable/http/HttpClientRequest"
15
- import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse"
16
- import * as KeyValueStore from "effect/unstable/persistence/KeyValueStore"
13
+ import * as HttpClient from "effect/http/HttpClient"
14
+ import * as HttpClientRequest from "effect/http/HttpClientRequest"
15
+ import * as HttpClientResponse from "effect/http/HttpClientResponse"
16
+ import * as KeyValueStore from "effect/persistence/KeyValueStore"
17
17
  import { DeviceCodeHandler } from "./DeviceCodeHandler.ts"
18
18
 
19
19
  export const CLIENT_ID = "Ov23li8tweQw6odWQebz"
@@ -2,7 +2,7 @@
2
2
  * @since 1.0.0
3
3
  */
4
4
  import * as Layer from "effect/Layer"
5
- import * as Socket from "effect/unstable/socket/Socket"
5
+ import * as Socket from "effect/socket/Socket"
6
6
 
7
7
  type GlobalWebSocket = InstanceType<typeof globalThis.WebSocket>
8
8
 
package/src/Image.test.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as Photon from "@silvia-odwyer/photon-node"
2
2
  import { assert, describe, it } from "@effect/vitest"
3
3
  import * as Effect from "effect/Effect"
4
- import * as Encoding from "effect/Encoding"
4
+ import * as Base64 from "effect/encoding/Base64"
5
5
  import * as Option from "effect/Option"
6
6
  import { vi } from "vitest"
7
7
  import * as Image from "./Image.ts"
@@ -32,7 +32,7 @@ const withDecoderSpy = <A, E, R>(
32
32
  )
33
33
  })
34
34
 
35
- const base64Length = (bytes: Uint8Array) => Encoding.encodeBase64(bytes).length
35
+ const base64Length = (bytes: Uint8Array) => Base64.encode(bytes).length
36
36
 
37
37
  describe("Image.prepare", () => {
38
38
  it.effect("passes an in-limit image through unchanged", () =>
package/src/Image.ts CHANGED
@@ -14,13 +14,13 @@
14
14
  */
15
15
  import type * as Photon from "@silvia-odwyer/photon-node"
16
16
  import * as Effect from "effect/Effect"
17
- import * as Encoding from "effect/Encoding"
17
+ import * as Base64 from "effect/encoding/Base64"
18
18
  import type * as FileSystem from "effect/FileSystem"
19
19
  import * as Option from "effect/Option"
20
20
  import * as Schema from "effect/Schema"
21
21
  import * as Stream from "effect/Stream"
22
- import type * as AiError from "effect/unstable/ai/AiError"
23
- import * as Prompt from "effect/unstable/ai/Prompt"
22
+ import type * as AiError from "effect/ai/AiError"
23
+ import * as Prompt from "effect/ai/Prompt"
24
24
 
25
25
  /**
26
26
  * @since 1.0.0
@@ -677,7 +677,7 @@ export const partBytes = (part: Prompt.FilePart): Option.Option<Uint8Array> => {
677
677
  const base64 = part.data.startsWith("data:")
678
678
  ? part.data.slice(part.data.indexOf(",") + 1)
679
679
  : part.data
680
- const decoded = Encoding.decodeBase64(base64)
680
+ const decoded = Base64.decode(base64)
681
681
  return decoded._tag === "Success"
682
682
  ? Option.some(decoded.success)
683
683
  : Option.none()
@@ -9,7 +9,7 @@ import * as Context from "effect/Context"
9
9
  import * as Stream from "effect/Stream"
10
10
  import type { AgentFinished, Output } from "./AgentOutput.ts"
11
11
  import chalk from "chalk"
12
- import type * as Prompt from "effect/unstable/ai/Prompt"
12
+ import type * as Prompt from "effect/ai/Prompt"
13
13
  import * as Cause from "effect/Cause"
14
14
  import { identity } from "effect/Function"
15
15
  import * as Predicate from "effect/Predicate"
@@ -4,7 +4,7 @@ import * as Effect from "effect/Effect"
4
4
  import * as Fiber from "effect/Fiber"
5
5
  import * as RequestResolver from "effect/RequestResolver"
6
6
  import { TestClock } from "effect/testing"
7
- import type * as EmbeddingModel from "effect/unstable/ai/EmbeddingModel"
7
+ import type * as EmbeddingModel from "effect/ai/EmbeddingModel"
8
8
  import { makeEmbeddingResolver } from "./SemanticSearch.ts"
9
9
 
10
10
  const baseResolver = RequestResolver.make<EmbeddingModel.EmbeddingRequest>(
@@ -8,7 +8,7 @@ import * as CodeChunker from "./CodeChunker.ts"
8
8
  import * as Layer from "effect/Layer"
9
9
  import * as Stream from "effect/Stream"
10
10
  import { pipe } from "effect/Function"
11
- import * as EmbeddingModel from "effect/unstable/ai/EmbeddingModel"
11
+ import * as EmbeddingModel from "effect/ai/EmbeddingModel"
12
12
  import * as RequestResolver from "effect/RequestResolver"
13
13
  import * as Option from "effect/Option"
14
14
  import * as Path from "effect/Path"
@@ -16,10 +16,10 @@ import * as Fiber from "effect/Fiber"
16
16
  import * as Duration from "effect/Duration"
17
17
  import * as FiberHandle from "effect/FiberHandle"
18
18
  import { SqliteLayer } from "./Sqlite.ts"
19
- import type * as SqlError from "effect/unstable/sql/SqlError"
19
+ import type * as SqlError from "effect/sql/SqlError"
20
20
  import type * as SqliteMigrator from "@effect/sql-sqlite-node/SqliteMigrator"
21
21
  import type * as PlatformError from "effect/PlatformError"
22
- import type * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner"
22
+ import type * as ChildProcessSpawner from "effect/process/ChildProcessSpawner"
23
23
  import type * as FileSystem from "effect/FileSystem"
24
24
  import * as Console from "effect/Console"
25
25
  import { SemanticSearch } from "./SemanticSearch/Service.ts"
package/src/Sqlite.ts CHANGED
@@ -5,7 +5,7 @@ import * as SqliteClient from "@effect/sql-sqlite-node/SqliteClient"
5
5
  import * as SqliteMigrator from "@effect/sql-sqlite-node/SqliteMigrator"
6
6
  import * as Effect from "effect/Effect"
7
7
  import * as Layer from "effect/Layer"
8
- import * as SqlClient from "effect/unstable/sql/SqlClient"
8
+ import * as SqlClient from "effect/sql/SqlClient"
9
9
  import * as FileSystem from "effect/FileSystem"
10
10
  import * as Path from "effect/Path"
11
11
  import { getLoadablePath } from "sqlite-vec"
@@ -5,8 +5,8 @@ import * as Array from "effect/Array"
5
5
  import * as Layer from "effect/Layer"
6
6
  import * as SchemaAST from "effect/SchemaAST"
7
7
  import * as Context from "effect/Context"
8
- import type * as Tool from "effect/unstable/ai/Tool"
9
- import type * as Toolkit from "effect/unstable/ai/Toolkit"
8
+ import type * as Tool from "effect/ai/Tool"
9
+ import type * as Toolkit from "effect/ai/Toolkit"
10
10
  import * as TypeBuilder from "./TypeBuilder.ts"
11
11
  import * as Function from "effect/Function"
12
12
 
@@ -5,7 +5,7 @@ import {
5
5
  HttpClient,
6
6
  type HttpClientRequest,
7
7
  HttpClientResponse,
8
- } from "effect/unstable/http"
8
+ } from "effect/http"
9
9
  import * as WebToMarkdown from "./WebToMarkdown.ts"
10
10
 
11
11
  describe("WebToMarkdown", () => {
@@ -4,8 +4,8 @@
4
4
  import * as Effect from "effect/Effect"
5
5
  import * as Layer from "effect/Layer"
6
6
  import * as Context from "effect/Context"
7
- import * as HttpClient from "effect/unstable/http/HttpClient"
8
- import type * as HttpClientError from "effect/unstable/http/HttpClientError"
7
+ import * as HttpClient from "effect/http/HttpClient"
8
+ import type * as HttpClientError from "effect/http/HttpClientError"
9
9
 
10
10
  /**
11
11
  * @since 1.0.0
package/src/Xai.test.ts CHANGED
@@ -1,16 +1,14 @@
1
1
  import { assert, describe, it } from "@effect/vitest"
2
+ import { OpenAiClient } from "@effect/ai-openai"
2
3
  import * as Effect from "effect/Effect"
3
4
  import * as Exit from "effect/Exit"
4
5
  import * as Layer from "effect/Layer"
5
6
  import * as Stream from "effect/Stream"
6
- import * as LanguageModel from "effect/unstable/ai/LanguageModel"
7
- import * as Model from "effect/unstable/ai/Model"
8
- import {
9
- HttpClient,
10
- type HttpClientRequest,
11
- HttpClientResponse,
12
- } from "effect/unstable/http"
13
- import * as KeyValueStore from "effect/unstable/persistence/KeyValueStore"
7
+ import * as LanguageModel from "effect/ai/LanguageModel"
8
+ import * as Model from "effect/ai/Model"
9
+ import { HttpClient, HttpClientRequest, HttpClientResponse } from "effect/http"
10
+ import * as KeyValueStore from "effect/persistence/KeyValueStore"
11
+ import * as Socket from "effect/socket/Socket"
14
12
  import * as Compaction from "./Compaction.ts"
15
13
  import { DeviceCodeHandler } from "./DeviceCodeHandler.ts"
16
14
  import * as Public from "./index.ts"
@@ -61,6 +59,67 @@ const noLogin = Layer.succeed(DeviceCodeHandler, {
61
59
  })
62
60
 
63
61
  describe("Xai provider", () => {
62
+ it.todo(
63
+ "replays WebSocket history inline with storage enabled once upstream supports disabling item references",
64
+ )
65
+
66
+ for (const store of [undefined, false, true] as const) {
67
+ it.effect("always stores WebSocket responses with store=" + store, () =>
68
+ Effect.gen(function* () {
69
+ const http = capture()
70
+ const requests: Array<
71
+ Parameters<
72
+ OpenAiClient.OpenAiSocket["Service"]["createResponseStream"]
73
+ >[0]
74
+ > = []
75
+ yield* Effect.gen(function* () {
76
+ const ai = yield* LanguageModel.LanguageModel
77
+ const summarize = yield* Compaction.SummarizerTransform
78
+ const request = ai
79
+ .streamText({ prompt: "hello" })
80
+ .pipe(Stream.runDrain)
81
+ yield* request.pipe(Effect.exit)
82
+ yield* summarize(request).pipe(Effect.exit)
83
+ }).pipe(
84
+ Effect.provideService(OpenAiClient.OpenAiSocket, {
85
+ createResponseStream: (request) =>
86
+ Effect.sync(() => {
87
+ requests.push(request)
88
+ return [
89
+ HttpClientResponse.fromWeb(
90
+ HttpClientRequest.post("https://api.x.ai/v1/responses"),
91
+ new Response(),
92
+ ),
93
+ Stream.empty,
94
+ ] as const
95
+ }),
96
+ }),
97
+ Effect.provide(
98
+ Xai.modelWebSocket(
99
+ "grok-4.6",
100
+ store === undefined ? undefined : { store },
101
+ ).pipe(
102
+ Layer.provide(
103
+ OpenAiClient.layer({ apiUrl: "https://api.x.ai/v1" }),
104
+ ),
105
+ Layer.provide(http.layer),
106
+ Layer.provide(
107
+ Layer.succeed(Socket.WebSocketConstructor, () => {
108
+ throw new Error("Unexpected live WebSocket")
109
+ }),
110
+ ),
111
+ ),
112
+ ),
113
+ )
114
+ assert.lengthOf(http.requests, 0)
115
+ assert.lengthOf(requests, 2)
116
+ for (const request of requests) assert.strictEqual(request.store, true)
117
+ assert.isUndefined(requests[0]!.max_output_tokens)
118
+ assert.strictEqual(requests[1]!.max_output_tokens, 4000)
119
+ }),
120
+ )
121
+ }
122
+
64
123
  it("exports Xai, but not XaiAuth, from the public entry point", () => {
65
124
  assert.strictEqual(Public.Xai, Xai)
66
125
  assert.isFalse("XaiAuth" in Public)
package/src/Xai.ts CHANGED
@@ -7,8 +7,10 @@ import * as Struct from "effect/Struct"
7
7
  import { XaiAuth } from "./XaiAuth.ts"
8
8
  import { AgentModelConfig } from "./Agent.ts"
9
9
  import * as Compaction from "./Compaction.ts"
10
- import * as Model from "effect/unstable/ai/Model"
11
- import type * as LanguageModel from "effect/unstable/ai/LanguageModel"
10
+ import * as Model from "effect/ai/Model"
11
+ import type * as LanguageModel from "effect/ai/LanguageModel"
12
+ import type * as Socket from "effect/socket/Socket"
13
+ import type * as ResponseIdTracker from "effect/ai/ResponseIdTracker"
12
14
 
13
15
  /**
14
16
  * @since 1.0.0
@@ -39,7 +41,7 @@ export const model = (
39
41
  "systemPromptTransform",
40
42
  "supportsImages",
41
43
  ]),
42
- store: false,
44
+ store: options?.store ?? false,
43
45
  reasoning: { effort: "high", ...options?.reasoning },
44
46
  },
45
47
  }),
@@ -55,3 +57,50 @@ export const model = (
55
57
  ),
56
58
  ),
57
59
  )
60
+
61
+ /**
62
+ * @since 1.0.0
63
+ * @category Layers
64
+ */
65
+ export const modelWebSocket = (
66
+ model: string,
67
+ options?:
68
+ | (OpenAiLanguageModel.Config["Service"] & typeof AgentModelConfig.Service)
69
+ | undefined,
70
+ ): Model.Model<
71
+ "xai",
72
+ | LanguageModel.LanguageModel
73
+ | OpenAiClient.OpenAiSocket
74
+ | ResponseIdTracker.ResponseIdTracker,
75
+ OpenAiClient.OpenAiClient | Socket.WebSocketConstructor
76
+ > =>
77
+ Model.make(
78
+ "xai",
79
+ model,
80
+ Layer.mergeAll(
81
+ OpenAiLanguageModel.layer({
82
+ model,
83
+ config: {
84
+ ...Struct.omit(options ?? {}, [
85
+ "systemPromptTransform",
86
+ "supportsImages",
87
+ ]),
88
+ // xAI needs stored responses to resolve previous_response_id.
89
+ store: true,
90
+ useItemReferences: false,
91
+ reasoning: { effort: "high", ...options?.reasoning },
92
+ },
93
+ }),
94
+ AgentModelConfig.layer({
95
+ systemPromptTransform: options?.systemPromptTransform,
96
+ supportsImages: options?.supportsImages,
97
+ }),
98
+ // Cap compaction summaries; xAI honours max_output_tokens.
99
+ Layer.succeed(Compaction.SummarizerTransform, (effect) =>
100
+ OpenAiLanguageModel.withConfigOverride(effect, {
101
+ max_output_tokens: Compaction.summarizerMaxOutputTokens,
102
+ }),
103
+ ),
104
+ Layer.fresh(OpenAiClient.layerWebSocketMode),
105
+ ),
106
+ )
@@ -9,8 +9,8 @@ import {
9
9
  HttpClientError,
10
10
  type HttpClientRequest,
11
11
  HttpClientResponse,
12
- } from "effect/unstable/http"
13
- import * as KeyValueStore from "effect/unstable/persistence/KeyValueStore"
12
+ } from "effect/http"
13
+ import * as KeyValueStore from "effect/persistence/KeyValueStore"
14
14
  import { DeviceCodeHandler } from "./DeviceCodeHandler.ts"
15
15
  import { XaiAuth, TokenData, toTokenStore } from "./XaiAuth.ts"
16
16