aimeat 2.4.0 → 2.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 (308) hide show
  1. package/dist/.env.example +33 -0
  2. package/dist/build-stamp.json +13 -0
  3. package/dist/locales/en.json +186 -20
  4. package/dist/locales/fi.json +186 -20
  5. package/dist/public/components/VoiceRecorder.js +116 -0
  6. package/dist/public/connection-done.html +53 -0
  7. package/dist/public/css/components/voice-recorder.css +66 -0
  8. package/dist/public/css/views/inbox.css +41 -0
  9. package/dist/public/css/views/profile.css +171 -95
  10. package/dist/public/css/views/transparency.css +5 -0
  11. package/dist/public/js/services/audio-recorder.js +171 -0
  12. package/dist/public/js/services/messages.js +21 -2
  13. package/dist/public/spa.html +3 -0
  14. package/dist/public/views/landing.js +4 -0
  15. package/dist/public/views/profile/access-tab/connections.js +264 -0
  16. package/dist/public/views/profile/access-tab.js +2 -0
  17. package/dist/public/views/profile/ai-transparency-card.js +22 -17
  18. package/dist/public/views/profile/inbox-tab/components.js +60 -10
  19. package/dist/public/views/profile/inbox-tab/helpers.js +33 -0
  20. package/dist/public/views/profile/inbox-tab/panels.js +6 -1
  21. package/dist/public/views/profile/inbox-tab/use-voice.js +50 -0
  22. package/dist/public/views/profile/inbox-tab/voice-parts.js +111 -0
  23. package/dist/public/views/profile/inbox-tab.js +18 -24
  24. package/dist/public/views/profile/openrouter/budget-panel.js +224 -0
  25. package/dist/public/views/profile/openrouter/model-picker.js +150 -0
  26. package/dist/public/views/profile/openrouter/pricing.js +139 -0
  27. package/dist/public/views/profile/openrouter-settings.js +425 -488
  28. package/dist/public/views/transparency.js +50 -0
  29. package/dist/scripts/build-sdk-libs.d.ts.map +1 -1
  30. package/dist/scripts/build-sdk-libs.js +1 -0
  31. package/dist/scripts/build-sdk-libs.js.map +1 -1
  32. package/dist/scripts/check-ai-disclosure.d.ts.map +1 -1
  33. package/dist/scripts/check-ai-disclosure.js +182 -0
  34. package/dist/scripts/check-ai-disclosure.js.map +1 -1
  35. package/dist/src/cli/connect/ai-provenance-carry.d.ts +247 -0
  36. package/dist/src/cli/connect/ai-provenance-carry.d.ts.map +1 -0
  37. package/dist/src/cli/connect/ai-provenance-carry.js +334 -0
  38. package/dist/src/cli/connect/ai-provenance-carry.js.map +1 -0
  39. package/dist/src/cli/connect/api-client.d.ts +11 -0
  40. package/dist/src/cli/connect/api-client.d.ts.map +1 -1
  41. package/dist/src/cli/connect/api-client.js +2 -0
  42. package/dist/src/cli/connect/api-client.js.map +1 -1
  43. package/dist/src/cli/connect/mcp/local-server.d.ts.map +1 -1
  44. package/dist/src/cli/connect/mcp/local-server.js +11 -0
  45. package/dist/src/cli/connect/mcp/local-server.js.map +1 -1
  46. package/dist/src/cli/connect/mcp/tools/agent-messages.d.ts +2 -0
  47. package/dist/src/cli/connect/mcp/tools/agent-messages.d.ts.map +1 -1
  48. package/dist/src/cli/connect/mcp/tools/agent-messages.js +5 -2
  49. package/dist/src/cli/connect/mcp/tools/agent-messages.js.map +1 -1
  50. package/dist/src/cli/connect/mcp/tools/agent-tasks.d.ts +2 -0
  51. package/dist/src/cli/connect/mcp/tools/agent-tasks.d.ts.map +1 -1
  52. package/dist/src/cli/connect/mcp/tools/agent-tasks.js +5 -2
  53. package/dist/src/cli/connect/mcp/tools/agent-tasks.js.map +1 -1
  54. package/dist/src/cli/connect/mcp/tools/apps.d.ts +3 -0
  55. package/dist/src/cli/connect/mcp/tools/apps.d.ts.map +1 -1
  56. package/dist/src/cli/connect/mcp/tools/apps.js +13 -5
  57. package/dist/src/cli/connect/mcp/tools/apps.js.map +1 -1
  58. package/dist/src/cli/connect/mcp/tools/boards.d.ts +3 -0
  59. package/dist/src/cli/connect/mcp/tools/boards.d.ts.map +1 -1
  60. package/dist/src/cli/connect/mcp/tools/boards.js +5 -2
  61. package/dist/src/cli/connect/mcp/tools/boards.js.map +1 -1
  62. package/dist/src/cli/connect/mcp/tools/core.d.ts +5 -0
  63. package/dist/src/cli/connect/mcp/tools/core.d.ts.map +1 -1
  64. package/dist/src/cli/connect/mcp/tools/core.js +25 -5
  65. package/dist/src/cli/connect/mcp/tools/core.js.map +1 -1
  66. package/dist/src/cli/connect/mcp/tools/dm-messages.d.ts +2 -0
  67. package/dist/src/cli/connect/mcp/tools/dm-messages.d.ts.map +1 -1
  68. package/dist/src/cli/connect/mcp/tools/dm-messages.js +11 -6
  69. package/dist/src/cli/connect/mcp/tools/dm-messages.js.map +1 -1
  70. package/dist/src/cli/connect/mcp/tools/exchange.d.ts +2 -0
  71. package/dist/src/cli/connect/mcp/tools/exchange.d.ts.map +1 -1
  72. package/dist/src/cli/connect/mcp/tools/exchange.js +8 -2
  73. package/dist/src/cli/connect/mcp/tools/exchange.js.map +1 -1
  74. package/dist/src/cli/connect/mcp/tools/knowledge.d.ts +3 -0
  75. package/dist/src/cli/connect/mcp/tools/knowledge.d.ts.map +1 -1
  76. package/dist/src/cli/connect/mcp/tools/knowledge.js +7 -3
  77. package/dist/src/cli/connect/mcp/tools/knowledge.js.map +1 -1
  78. package/dist/src/cli/connect/mcp/tools/organisms.d.ts +2 -0
  79. package/dist/src/cli/connect/mcp/tools/organisms.d.ts.map +1 -1
  80. package/dist/src/cli/connect/mcp/tools/organisms.js +7 -2
  81. package/dist/src/cli/connect/mcp/tools/organisms.js.map +1 -1
  82. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts +3 -0
  83. package/dist/src/cli/connect/mcp/tools/workspaces.d.ts.map +1 -1
  84. package/dist/src/cli/connect/mcp/tools/workspaces.js +8 -2
  85. package/dist/src/cli/connect/mcp/tools/workspaces.js.map +1 -1
  86. package/dist/src/cli/connect/tool-call-defs-core.d.ts +3 -0
  87. package/dist/src/cli/connect/tool-call-defs-core.d.ts.map +1 -1
  88. package/dist/src/cli/connect/tool-call-defs-core.js +7 -0
  89. package/dist/src/cli/connect/tool-call-defs-core.js.map +1 -1
  90. package/dist/src/cli/connect/tool-call.d.ts +3 -0
  91. package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
  92. package/dist/src/cli/connect/tool-call.js +11 -1
  93. package/dist/src/cli/connect/tool-call.js.map +1 -1
  94. package/dist/src/config-types.d.ts +14 -0
  95. package/dist/src/config-types.d.ts.map +1 -1
  96. package/dist/src/config.d.ts.map +1 -1
  97. package/dist/src/config.js +10 -0
  98. package/dist/src/config.js.map +1 -1
  99. package/dist/src/data/public-pages.d.ts +12 -0
  100. package/dist/src/data/public-pages.d.ts.map +1 -1
  101. package/dist/src/data/public-pages.js +12 -0
  102. package/dist/src/data/public-pages.js.map +1 -1
  103. package/dist/src/generated/api-types.d.ts +969 -85
  104. package/dist/src/generated/api-types.d.ts.map +1 -1
  105. package/dist/src/mcp/ai-provenance-input.d.ts +45 -2
  106. package/dist/src/mcp/ai-provenance-input.d.ts.map +1 -1
  107. package/dist/src/mcp/ai-provenance-input.js +48 -2
  108. package/dist/src/mcp/ai-provenance-input.js.map +1 -1
  109. package/dist/src/mcp/apps.d.ts +7 -0
  110. package/dist/src/mcp/apps.d.ts.map +1 -1
  111. package/dist/src/mcp/apps.js +20 -2
  112. package/dist/src/mcp/apps.js.map +1 -1
  113. package/dist/src/models/ai-provenance-schemas.d.ts +7 -1
  114. package/dist/src/models/ai-provenance-schemas.d.ts.map +1 -1
  115. package/dist/src/models/ai-provenance-schemas.js +11 -1
  116. package/dist/src/models/ai-provenance-schemas.js.map +1 -1
  117. package/dist/src/models/connection-schemas.d.ts +203 -0
  118. package/dist/src/models/connection-schemas.d.ts.map +1 -0
  119. package/dist/src/models/connection-schemas.js +33 -0
  120. package/dist/src/models/connection-schemas.js.map +1 -0
  121. package/dist/src/models/message-schemas.d.ts +40 -0
  122. package/dist/src/models/message-schemas.d.ts.map +1 -1
  123. package/dist/src/models/message-schemas.js +23 -0
  124. package/dist/src/models/message-schemas.js.map +1 -1
  125. package/dist/src/routes/ai-provenance.d.ts +6 -0
  126. package/dist/src/routes/ai-provenance.d.ts.map +1 -1
  127. package/dist/src/routes/ai-provenance.js +34 -1
  128. package/dist/src/routes/ai-provenance.js.map +1 -1
  129. package/dist/src/routes/ai-transparency.d.ts +6 -1
  130. package/dist/src/routes/ai-transparency.d.ts.map +1 -1
  131. package/dist/src/routes/ai-transparency.js +17 -3
  132. package/dist/src/routes/ai-transparency.js.map +1 -1
  133. package/dist/src/routes/ai.d.ts +5 -0
  134. package/dist/src/routes/ai.d.ts.map +1 -1
  135. package/dist/src/routes/ai.js +83 -0
  136. package/dist/src/routes/ai.js.map +1 -1
  137. package/dist/src/routes/app-grants.d.ts.map +1 -1
  138. package/dist/src/routes/app-grants.js +4 -0
  139. package/dist/src/routes/app-grants.js.map +1 -1
  140. package/dist/src/routes/apps/drafts.d.ts +3 -0
  141. package/dist/src/routes/apps/drafts.d.ts.map +1 -1
  142. package/dist/src/routes/apps/drafts.js +13 -0
  143. package/dist/src/routes/apps/drafts.js.map +1 -1
  144. package/dist/src/routes/apps/publish.d.ts +5 -0
  145. package/dist/src/routes/apps/publish.d.ts.map +1 -1
  146. package/dist/src/routes/apps/publish.js +21 -5
  147. package/dist/src/routes/apps/publish.js.map +1 -1
  148. package/dist/src/routes/connections.d.ts +35 -0
  149. package/dist/src/routes/connections.d.ts.map +1 -0
  150. package/dist/src/routes/connections.js +406 -0
  151. package/dist/src/routes/connections.js.map +1 -0
  152. package/dist/src/routes/libs.js +1 -1
  153. package/dist/src/routes/libs.js.map +1 -1
  154. package/dist/src/routes/messages.d.ts +5 -0
  155. package/dist/src/routes/messages.d.ts.map +1 -1
  156. package/dist/src/routes/messages.js +92 -0
  157. package/dist/src/routes/messages.js.map +1 -1
  158. package/dist/src/routes/openrouter.d.ts +6 -1
  159. package/dist/src/routes/openrouter.d.ts.map +1 -1
  160. package/dist/src/routes/openrouter.js +37 -7
  161. package/dist/src/routes/openrouter.js.map +1 -1
  162. package/dist/src/routes/upload.d.ts +5 -0
  163. package/dist/src/routes/upload.d.ts.map +1 -1
  164. package/dist/src/routes/upload.js +32 -0
  165. package/dist/src/routes/upload.js.map +1 -1
  166. package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
  167. package/dist/src/server-bootstrap/routes-loader.js +2 -0
  168. package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
  169. package/dist/src/services/ai-completion.d.ts +48 -0
  170. package/dist/src/services/ai-completion.d.ts.map +1 -1
  171. package/dist/src/services/ai-completion.js +112 -72
  172. package/dist/src/services/ai-completion.js.map +1 -1
  173. package/dist/src/services/ai-disclosure.d.ts +6 -0
  174. package/dist/src/services/ai-disclosure.d.ts.map +1 -1
  175. package/dist/src/services/ai-disclosure.js +20 -2
  176. package/dist/src/services/ai-disclosure.js.map +1 -1
  177. package/dist/src/services/ai-provenance-page.d.ts +59 -0
  178. package/dist/src/services/ai-provenance-page.d.ts.map +1 -0
  179. package/dist/src/services/ai-provenance-page.js +185 -0
  180. package/dist/src/services/ai-provenance-page.js.map +1 -0
  181. package/dist/src/services/ai-provenance.d.ts +6 -0
  182. package/dist/src/services/ai-provenance.d.ts.map +1 -1
  183. package/dist/src/services/ai-provenance.js +5 -0
  184. package/dist/src/services/ai-provenance.js.map +1 -1
  185. package/dist/src/services/ai-transcription.d.ts +66 -0
  186. package/dist/src/services/ai-transcription.d.ts.map +1 -0
  187. package/dist/src/services/ai-transcription.js +90 -0
  188. package/dist/src/services/ai-transcription.js.map +1 -0
  189. package/dist/src/services/app-publish.d.ts.map +1 -1
  190. package/dist/src/services/app-publish.js +16 -1
  191. package/dist/src/services/app-publish.js.map +1 -1
  192. package/dist/src/services/build-app-prompt.d.ts.map +1 -1
  193. package/dist/src/services/build-app-prompt.js +2 -1
  194. package/dist/src/services/build-app-prompt.js.map +1 -1
  195. package/dist/src/services/connections/attach.d.ts +62 -0
  196. package/dist/src/services/connections/attach.d.ts.map +1 -0
  197. package/dist/src/services/connections/attach.js +168 -0
  198. package/dist/src/services/connections/attach.js.map +1 -0
  199. package/dist/src/services/connections/credential.d.ts +39 -0
  200. package/dist/src/services/connections/credential.d.ts.map +1 -0
  201. package/dist/src/services/connections/credential.js +66 -0
  202. package/dist/src/services/connections/credential.js.map +1 -0
  203. package/dist/src/services/connections/instance.d.ts +65 -0
  204. package/dist/src/services/connections/instance.d.ts.map +1 -0
  205. package/dist/src/services/connections/instance.js +144 -0
  206. package/dist/src/services/connections/instance.js.map +1 -0
  207. package/dist/src/services/connections/oauth.d.ts +77 -0
  208. package/dist/src/services/connections/oauth.d.ts.map +1 -0
  209. package/dist/src/services/connections/oauth.js +290 -0
  210. package/dist/src/services/connections/oauth.js.map +1 -0
  211. package/dist/src/services/connections/providers.d.ts +118 -0
  212. package/dist/src/services/connections/providers.d.ts.map +1 -0
  213. package/dist/src/services/connections/providers.js +260 -0
  214. package/dist/src/services/connections/providers.js.map +1 -0
  215. package/dist/src/services/connections/publish-gate.d.ts +103 -0
  216. package/dist/src/services/connections/publish-gate.d.ts.map +1 -0
  217. package/dist/src/services/connections/publish-gate.js +0 -0
  218. package/dist/src/services/connections/publish-gate.js.map +1 -0
  219. package/dist/src/services/connections/publish.d.ts +60 -0
  220. package/dist/src/services/connections/publish.d.ts.map +1 -0
  221. package/dist/src/services/connections/publish.js +340 -0
  222. package/dist/src/services/connections/publish.js.map +1 -0
  223. package/dist/src/services/connections/refresh.d.ts +55 -0
  224. package/dist/src/services/connections/refresh.d.ts.map +1 -0
  225. package/dist/src/services/connections/refresh.js +307 -0
  226. package/dist/src/services/connections/refresh.js.map +1 -0
  227. package/dist/src/services/markdown-negotiation.d.ts +17 -0
  228. package/dist/src/services/markdown-negotiation.d.ts.map +1 -1
  229. package/dist/src/services/markdown-negotiation.js +15 -0
  230. package/dist/src/services/markdown-negotiation.js.map +1 -1
  231. package/dist/src/services/message-send.d.ts.map +1 -1
  232. package/dist/src/services/message-send.js +16 -2
  233. package/dist/src/services/message-send.js.map +1 -1
  234. package/dist/src/services/openrouter.d.ts +67 -1
  235. package/dist/src/services/openrouter.d.ts.map +1 -1
  236. package/dist/src/services/openrouter.js +102 -11
  237. package/dist/src/services/openrouter.js.map +1 -1
  238. package/dist/src/services/upload-token.d.ts +5 -1
  239. package/dist/src/services/upload-token.d.ts.map +1 -1
  240. package/dist/src/services/upload-token.js +13 -1
  241. package/dist/src/services/upload-token.js.map +1 -1
  242. package/dist/src/services/workflow/engine-util.d.ts +18 -0
  243. package/dist/src/services/workflow/engine-util.d.ts.map +1 -1
  244. package/dist/src/services/workflow/engine-util.js +27 -0
  245. package/dist/src/services/workflow/engine-util.js.map +1 -1
  246. package/dist/src/services/workflow/engine.d.ts.map +1 -1
  247. package/dist/src/services/workflow/engine.js +4 -2
  248. package/dist/src/services/workflow/engine.js.map +1 -1
  249. package/dist/src/storage/interface.d.ts +2 -1
  250. package/dist/src/storage/interface.d.ts.map +1 -1
  251. package/dist/src/storage/providers/postgres-kysely/db-types.d.ts +65 -0
  252. package/dist/src/storage/providers/postgres-kysely/db-types.d.ts.map +1 -1
  253. package/dist/src/storage/providers/postgres-kysely/index.d.ts.map +1 -1
  254. package/dist/src/storage/providers/postgres-kysely/index.js +2 -1
  255. package/dist/src/storage/providers/postgres-kysely/index.js.map +1 -1
  256. package/dist/src/storage/providers/postgres-kysely/methods/connections.d.ts +44 -0
  257. package/dist/src/storage/providers/postgres-kysely/methods/connections.d.ts.map +1 -0
  258. package/dist/src/storage/providers/postgres-kysely/methods/connections.js +308 -0
  259. package/dist/src/storage/providers/postgres-kysely/methods/connections.js.map +1 -0
  260. package/dist/src/storage/providers/postgres-kysely/methods/node-infra.d.ts.map +1 -1
  261. package/dist/src/storage/providers/postgres-kysely/methods/node-infra.js +4 -2
  262. package/dist/src/storage/providers/postgres-kysely/methods/node-infra.js.map +1 -1
  263. package/dist/src/storage/providers/postgres-kysely/migrations/0021_connections.sql +116 -0
  264. package/dist/src/storage/providers/postgres-kysely/migrations/0022_provider_clients.sql +36 -0
  265. package/dist/src/storage/providers/postgres-kysely/migrations/0023_nonce_payload.sql +13 -0
  266. package/dist/src/storage/providers/sqlite/index.d.ts.map +1 -1
  267. package/dist/src/storage/providers/sqlite/index.js +2 -1
  268. package/dist/src/storage/providers/sqlite/index.js.map +1 -1
  269. package/dist/src/storage/providers/sqlite/methods/community.d.ts.map +1 -1
  270. package/dist/src/storage/providers/sqlite/methods/community.js +2 -1
  271. package/dist/src/storage/providers/sqlite/methods/community.js.map +1 -1
  272. package/dist/src/storage/providers/sqlite/methods/connections.d.ts +60 -0
  273. package/dist/src/storage/providers/sqlite/methods/connections.d.ts.map +1 -0
  274. package/dist/src/storage/providers/sqlite/methods/connections.js +287 -0
  275. package/dist/src/storage/providers/sqlite/methods/connections.js.map +1 -0
  276. package/dist/src/storage/providers/sqlite/schema-tables-1.d.ts.map +1 -1
  277. package/dist/src/storage/providers/sqlite/schema-tables-1.js +4 -0
  278. package/dist/src/storage/providers/sqlite/schema-tables-1.js.map +1 -1
  279. package/dist/src/storage/providers/sqlite/schema-tables-3.d.ts.map +1 -1
  280. package/dist/src/storage/providers/sqlite/schema-tables-3.js +106 -0
  281. package/dist/src/storage/providers/sqlite/schema-tables-3.js.map +1 -1
  282. package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
  283. package/dist/src/storage/providers/sqlite/schema.js +2 -0
  284. package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
  285. package/dist/src/storage/repositories/connection.repository.d.ts +124 -0
  286. package/dist/src/storage/repositories/connection.repository.d.ts.map +1 -0
  287. package/dist/src/storage/repositories/connection.repository.js +2 -0
  288. package/dist/src/storage/repositories/connection.repository.js.map +1 -0
  289. package/dist/src/storage/types/agents-messaging.d.ts +19 -0
  290. package/dist/src/storage/types/agents-messaging.d.ts.map +1 -1
  291. package/dist/src/storage/types/agents-messaging.js.map +1 -1
  292. package/dist/src/storage/types/auth.d.ts +8 -1
  293. package/dist/src/storage/types/auth.d.ts.map +1 -1
  294. package/dist/src/utils/build-stamp.d.ts +56 -0
  295. package/dist/src/utils/build-stamp.d.ts.map +1 -0
  296. package/dist/src/utils/build-stamp.js +142 -0
  297. package/dist/src/utils/build-stamp.js.map +1 -0
  298. package/dist/src/utils/messaging.d.ts +14 -0
  299. package/dist/src/utils/messaging.d.ts.map +1 -1
  300. package/dist/src/utils/messaging.js +0 -0
  301. package/dist/src/utils/messaging.js.map +1 -1
  302. package/dist/static/sdk-libs/connect/index.js +199 -0
  303. package/dist/static/sdk-libs/connect/notes.js +47 -0
  304. package/dist/static/sdk-libs/connect/panel.js +238 -0
  305. package/dist/static/sdk-libs/data/index.js +63 -11
  306. package/dist/static/sdk-libs/dist/aimeat-connect.js +357 -0
  307. package/dist/static/sdk-libs/dist/aimeat-data.js +40 -9
  308. package/package.json +2 -2
package/dist/.env.example CHANGED
@@ -273,6 +273,16 @@ AIMEAT_PORT=40050
273
273
  # AIMEAT_STORAGE_QUOTA_MB=100
274
274
  # AIMEAT_STORAGE_MAX_FILE_SIZE_MB=10
275
275
  # AIMEAT_STORAGE_MAX_CHUNKED_FILE_SIZE_GB=5
276
+ # ── Speech-to-text (POST /v1/ai/transcribe, voice messages) ──
277
+ # Largest audio file accepted for transcription. 25 MB is the provider-side multipart ceiling, so
278
+ # raising this past it turns a clear local refusal into an opaque upstream one.
279
+ # AIMEAT_STT_MAX_MB=25
280
+ # Duration guideline in seconds. Checked after the call (only the response knows the duration) and
281
+ # logged; a transcription the owner has already paid for is never withheld. 0 disables the warning.
282
+ # AIMEAT_STT_MAX_SECONDS=600
283
+ # Hard cap on one browser voice-message recording, in seconds. Served to the UI so the recorder stops
284
+ # at this node's number. Raise it for long-form dictation; every second still costs the owner money.
285
+ # AIMEAT_VOICE_MSG_MAX_SECONDS=300
276
286
  # AIMEAT_MICRO_MEMORY_QUOTA_KB=500
277
287
  # AIMEAT_MICRO_MEMORY_MAX_SETS=50
278
288
  # AIMEAT_MICRO_MEMORY_MAX_KEYS_PER_SET=100
@@ -469,6 +479,29 @@ AIMEAT_PORT=40050
469
479
  # AIMEAT_ENTRA_OAUTH_CLIENT_SECRET="" # Client secret value from the app registration
470
480
  # AIMEAT_ENTRA_OAUTH_REDIRECT_URI="" # default: <baseUrl>/v1/ghii/login/entra/callback
471
481
 
482
+ # ── Outbound connections (TARGET-057, aimeat-connect) ────────
483
+ # Lets a principal connect THEIR OWN account at an external service (Mastodon, YouTube, Bluesky) so
484
+ # an app can publish there on their behalf. The opposite direction from the sign-in blocks above,
485
+ # and deliberately its own client: signing IN with Google and PUBLISHING to a Google account are
486
+ # different consent and must be separately revocable.
487
+ #
488
+ # WHICH SECRET GOES WHERE — the distinction that catches everyone:
489
+ # • The values below identify the APPLICATION. One per node, the SAME for every user. If they were
490
+ # per-user, every user would have to create their own Google Cloud project.
491
+ # • The USER's access/refresh token identifies THE ACCOUNT. It is never here: it lives encrypted in
492
+ # the Connection table, keyed by the principal who connected it.
493
+ # • Mastodon has nothing here at all. Its client credentials are issued PER INSTANCE and there are
494
+ # hundreds of instances, so the node registers itself on first contact and remembers the result.
495
+ #
496
+ # Off by default. An unconfigured provider is absent from discovery and refused at start with a
497
+ # reason; nothing here fails open.
498
+ # AIMEAT_CONNECTIONS_ENABLED=false
499
+ # AIMEAT_CONNECT_GOOGLE_CLIENT_ID="" # Google Cloud → Clients → Web application
500
+ # AIMEAT_CONNECT_GOOGLE_CLIENT_SECRET="" # from the same client; NOT the sign-in client
501
+ # AIMEAT_CONNECT_REDIRECT_URI="" # default: <baseUrl>/v1/connections/callback
502
+ # The redirect URI must match the provider's registration EXACTLY — scheme, port, no trailing
503
+ # slash. A mismatch surfaces only at the provider's consent screen, as redirect_uri_mismatch.
504
+
472
505
  # ── Consul (optional fleet management) ───────────────────────
473
506
  # Connect to HashiCorp Consul for centralized config management across nodes.
474
507
  # Values in Consul KV take precedence over file/.env but below database overrides.
@@ -0,0 +1,13 @@
1
+ {
2
+ "schema_version": 1,
3
+ "version": "2.6.0",
4
+ "commit": "9cca6f004888be424d1b031da77a2a04693b856f",
5
+ "dirty": false,
6
+ "built_at": "2026-08-02T01:53:22.702Z",
7
+ "newest_source_mtime": 1785635326931.713,
8
+ "source_dirs": [
9
+ "src",
10
+ "bin",
11
+ "scripts"
12
+ ]
13
+ }
@@ -2985,7 +2985,27 @@
2985
2985
  "agCapSaved": "Spending limit saved",
2986
2986
  "agCapResetBtn": "Clear counter",
2987
2987
  "agCapReset": "Counter cleared",
2988
- "agCapFailed": "Could not change the limit"
2988
+ "agCapFailed": "Could not change the limit",
2989
+ "cxTitle": "Connected accounts",
2990
+ "cxIntro": "Accounts you have connected at other services. The credential stays on this node — an app is only ever told which account it may use, never the account itself.",
2991
+ "cxEmpty": "No connected accounts yet.",
2992
+ "cxConnect": "Connect",
2993
+ "cxConnecting": "Connecting…",
2994
+ "cxDisconnect": "Disconnect",
2995
+ "cxReconnect": "Reconnect",
2996
+ "cxNeedsReauth": "needs reconnecting",
2997
+ "cxInstance": "instance address, e.g. mastodon.social",
2998
+ "cxConfirm": "Disconnect {account}? Apps that publish to it will stop being able to.",
2999
+ "cxRevokedTold": "Disconnected, and the service was told.",
3000
+ "cxRevokedLocal": "Disconnected here. The service could not be reached to be told, so check it there too.",
3001
+ "cxRevokeFailed": "Could not disconnect that account",
3002
+ "cxConnectFailed": "Could not start connecting that account",
3003
+ "cxNoteMastodonNeeds": "The address of your instance, for example mastodon.social.",
3004
+ "cxNoteMastodonBefore": "Your account lives at one instance, and the same name at another instance is a different account.",
3005
+ "cxNoteYoutubeBefore": "Sign in with the Google account that owns the channel. A Google account with no YouTube channel will connect and then have nowhere to publish.",
3006
+ "cxNoteBlueskyNeeds": "An app password. This is not your Bluesky password.",
3007
+ "cxNoteBlueskyWhere": "Bluesky → Settings → Privacy and security → App passwords.",
3008
+ "cxNoteBlueskyBefore": "This is the one service that asks you to copy a secret to us instead of approving on their own site. You can revoke it from Bluesky at any time, and it cannot be used to sign in as you."
2989
3009
  },
2990
3010
  "nodes": {
2991
3011
  "title": "Personal Nodes",
@@ -3817,7 +3837,133 @@
3817
3837
  "pinRemove": "Unpin",
3818
3838
  "pinLimit": "Max 5 pinned items"
3819
3839
  },
3820
- "mcpConnected": "MCP connected"
3840
+ "mcpConnected": "MCP connected",
3841
+ "openrouter": {
3842
+ "title": "AI provider",
3843
+ "statusReady": "Key saved",
3844
+ "statusNoKey": "No key",
3845
+ "section": {
3846
+ "connection": "Connection",
3847
+ "models": "Models",
3848
+ "params": "Model parameters",
3849
+ "budget": "Budget and app spending"
3850
+ },
3851
+ "provider": "Provider",
3852
+ "provider_openrouter": "OpenRouter",
3853
+ "provider_lmstudio": "LM Studio",
3854
+ "provider_custom": "Custom (OpenAI-compatible)",
3855
+ "baseUrl": "API base URL",
3856
+ "baseUrl_hint": "https://…/v1",
3857
+ "apiKey": "API key",
3858
+ "apiKeyPlaceholder": "sk-or-v1-…",
3859
+ "apiKeyMasked": "●●●●●●●●",
3860
+ "saveKey": "Save key",
3861
+ "keySaved": "Key saved.",
3862
+ "providerSaved": "Provider saved.",
3863
+ "saveFailed": "Save failed.",
3864
+ "save": "Save",
3865
+ "cancel": "Cancel",
3866
+ "saveModels": "Save models",
3867
+ "modelsSaved": "Models saved.",
3868
+ "saveParams": "Save parameters",
3869
+ "paramsSaved": "Parameters saved.",
3870
+ "testConnection": "Test",
3871
+ "testOk": "Connection works ({model}, {ms} ms).",
3872
+ "testFail": "Connection failed",
3873
+ "testBudgetSpent": "Daily AI budget is spent — the key itself is fine",
3874
+ "delete": "Remove key",
3875
+ "deleted": "Key and settings removed.",
3876
+ "deleteConfirm": "Remove your API key and AI settings from this node?",
3877
+ "getKeyLink": "Get an API key",
3878
+ "creditsLink": "Check your credit balance",
3879
+ "modelsRefresh": "Refresh models",
3880
+ "modelsHint": "Fetched from the provider after you save the key.",
3881
+ "modelsError": "Could not load models. Check the base URL and key, save, then refresh.",
3882
+ "modelsEmpty": "The provider returned no models. Check the base URL.",
3883
+ "paramDefault": "default",
3884
+ "autoRetry": "Retry automatically on a validation error",
3885
+ "maxRetries": "Max retries",
3886
+ "temperature": "Temperature",
3887
+ "temperature_hint": "0 = deterministic, 1 = default, 2 = most creative",
3888
+ "topP": "Top P",
3889
+ "topP_hint": "Nucleus sampling: 0.1 = focused, 1.0 = full range",
3890
+ "maxTokens": "Max tokens",
3891
+ "maxTokens_hint": "Longest answer. Empty = the model's own default.",
3892
+ "model": {
3893
+ "default": "Default model",
3894
+ "reasoning": "Reasoning model",
3895
+ "reasoning_hint": "Used for planning and analysis when a caller asks for the reasoning role.",
3896
+ "execution": "Execution model",
3897
+ "execution_hint": "Used for code, tests and assembly when a caller asks for the execution role.",
3898
+ "rolesSummary": "Separate models for reasoning and execution",
3899
+ "vision": "Vision model (images)",
3900
+ "vision_hint": "Reads images you attach. Your default model is often text-only.",
3901
+ "visionNone": "Not in use — do not read images",
3902
+ "stt": "Speech-to-text model",
3903
+ "stt_hint": "Turns voice messages into text. Without one, transcription stays off.",
3904
+ "sttNone": "Not in use — no transcription",
3905
+ "none": "Not selected",
3906
+ "clear": "Clear",
3907
+ "notInList": "not in the current list",
3908
+ "searchPlaceholder": "Search {n} models…",
3909
+ "recommended": "Recommended",
3910
+ "showAll": "Show all {n}",
3911
+ "noMatch": "No model matches that search.",
3912
+ "openPage": "Open the model page on OpenRouter",
3913
+ "customIdPlaceholder": "model id, e.g. whisper-1",
3914
+ "customIdUse": "Use",
3915
+ "customIdHint": "A self-hosted endpoint may serve models its catalogue does not list."
3916
+ },
3917
+ "price": {
3918
+ "perMillionIn": "{usd} / M in",
3919
+ "perMillionOut": "{usd} / M out",
3920
+ "free": "free",
3921
+ "context": "{n} context",
3922
+ "audioReported": "price {value}"
3923
+ },
3924
+ "stt": {
3925
+ "language": "Language",
3926
+ "languageAuto": "Detect automatically",
3927
+ "language_hint": "A hint helps a single known language; leave it automatic for mixed speech.",
3928
+ "lang_fi": "Finnish",
3929
+ "lang_en": "English",
3930
+ "lang_sv": "Swedish",
3931
+ "lang_de": "German",
3932
+ "lang_fr": "French",
3933
+ "lang_es": "Spanish",
3934
+ "lang_et": "Estonian",
3935
+ "listEmpty": "This provider offers no transcription models.",
3936
+ "test": "Test transcription",
3937
+ "testing": "Transcribing…",
3938
+ "testNeedsModel": "Choose a model first.",
3939
+ "testFailed": "Test failed.",
3940
+ "testSilent": "(nothing recognised)",
3941
+ "measured": "Measured: {seconds} s of audio, ${cost}.",
3942
+ "costNotReported": "The provider reported no price."
3943
+ },
3944
+ "budget": {
3945
+ "title": "Daily AI budget",
3946
+ "desc": "Everything that spends your key shares this budget: apps calling AIMEAT.ai.complete(), and transcription. Once it is used up, further calls are refused.",
3947
+ "change": "Change",
3948
+ "budgetSaved": "Budget saved.",
3949
+ "budgetRange": "The budget must be a number between 0 and 1000.",
3950
+ "capRange": "The cap for \"{app}\" must be a number between 0 and 1000.",
3951
+ "capsSaved": "Per-app limits saved.",
3952
+ "saveCaps": "Save per-app limits",
3953
+ "saveFailed": "Save failed.",
3954
+ "perApp": "Per-app limits and spending ({n})",
3955
+ "perAppHint": "Every app may spend up to the daily budget. Set a cap to hold one below it; leave it empty to allow the full budget.",
3956
+ "colApp": "App",
3957
+ "colSpent": "Spent today",
3958
+ "colCap": "Daily cap ($)",
3959
+ "colCalls": "Calls",
3960
+ "chartTitle": "Usage over 30 days",
3961
+ "metricCost": "Cost",
3962
+ "metricTokens": "Tokens",
3963
+ "metricSeconds": "Seconds",
3964
+ "footnote": "Cost is estimated when the provider does not report one (LM Studio, custom). Your provider's own dashboard has the authoritative bill."
3965
+ }
3966
+ }
3821
3967
  },
3822
3968
  "dev": {
3823
3969
  "title": "Connect your AI to this node",
@@ -8379,23 +8525,23 @@
8379
8525
  "unstated": "AI involvement unstated"
8380
8526
  }
8381
8527
  },
8382
- "aiTransparency.title": "AI transparency — what you published",
8383
- "aiTransparency.desc": "How much of what you have published was written by a model, and how much of that carries a label.",
8384
- "aiTransparency.unlabelled": "public, unlabelled",
8385
- "aiTransparency.labelled": "public, labelled",
8386
- "aiTransparency.publicTotal": "public items",
8387
- "aiTransparency.total": "records in all",
8388
- "aiTransparency.scopeNote": "These counts cover content this node holds a provenance record for. Content with no record is unstated and does not appear here.",
8389
- "aiTransparency.unlabelledHelp": "A model produced these, nobody recorded reviewing them, and anyone can read them. Under Article 50(4) that combination owes a label. If a person did read and approve the substance, record that and the label stops being owed.",
8390
- "aiTransparency.unknownSource": "unknown source",
8391
- "aiTransparency.openRecord": "Open the record",
8392
- "aiTransparency.showingOf": "Showing {shown} of {total}.",
8393
- "aiTransparency.appsWithGap": "Apps that generate content and say nothing about it",
8394
- "aiTransparency.policyTitle": "What this node records about a model call",
8395
- "aiTransparency.retention": "Kept",
8396
- "aiTransparency.neverContains": "Never contains",
8397
- "aiTransparency.loadFailed": "Could not read your transparency summary.",
8398
- "aiTransparency.loading": "Reading your records…",
8528
+ "aiTransparencyMine.title": "AI transparency — what you published",
8529
+ "aiTransparencyMine.desc": "How much of what you have published was written by a model, and how much of that carries a label.",
8530
+ "aiTransparencyMine.unlabelled": "public, unlabelled",
8531
+ "aiTransparencyMine.labelled": "public, labelled",
8532
+ "aiTransparencyMine.publicTotal": "public items",
8533
+ "aiTransparencyMine.total": "records in all",
8534
+ "aiTransparencyMine.scopeNote": "These counts cover content this node holds a provenance record for. Content with no record is unstated and does not appear here.",
8535
+ "aiTransparencyMine.unlabelledHelp": "A model produced these, nobody recorded reviewing them, and anyone can read them. Under Article 50(4) that combination owes a label. If a person did read and approve the substance, record that and the label stops being owed.",
8536
+ "aiTransparencyMine.unknownSource": "unknown source",
8537
+ "aiTransparencyMine.openRecord": "Open the record",
8538
+ "aiTransparencyMine.showingOf": "Showing {shown} of {total}.",
8539
+ "aiTransparencyMine.appsWithGap": "Apps that generate content and say nothing about it",
8540
+ "aiTransparencyMine.policyTitle": "What this node records about a model call",
8541
+ "aiTransparencyMine.retention": "Kept",
8542
+ "aiTransparencyMine.neverContains": "Never contains",
8543
+ "aiTransparencyMine.loadFailed": "Could not read your transparency summary.",
8544
+ "aiTransparencyMine.loading": "Reading your records…",
8399
8545
  "transparency.title": "How this node marks AI-generated content",
8400
8546
  "transparency.intro": "When a model writes something here, the node records how it was made — which model, when, on whose account, and how much a person was involved — and keeps that record at an address of its own. Where a person reads that content on this node’s own pages, the record becomes a visible label: the official EU AI Office icon and a sentence in English or Finnish, beside the content, with a link to the full record. Software gets the same facts from the response itself, in the HTTP headers, the page metadata, and the markdown and MCP surfaces.",
8401
8547
  "transparency.limitsTitle": "What this does not do",
@@ -8404,6 +8550,8 @@
8404
8550
  "transparency.limit2": "A mark can be removed by copying. Paste the words somewhere else and the label is gone. The record at its own address survives that, which is why there are two layers — but nothing here makes text tamper-proof, and we will not pretend otherwise.",
8405
8551
  "transparency.limit3": "Content made before this node started recording carries no record, and will not acquire one later. A statement about words nobody witnessed being written would be a fabrication.",
8406
8552
  "transparency.limit4": "A missing record means nothing was stated. It never means a person wrote it.",
8553
+ "transparency.seeItLead": "Somewhere to see one:",
8554
+ "transparency.seeItTail": "is an app on this node that generates text, and the node found the disclosure call in the source it serves.",
8407
8555
  "transparency.opTitle": "Who runs this node, and who supervises it",
8408
8556
  "transparency.opLead": "These are read from this node’s own live statement as you load this page, so they are exactly the values a machine is given.",
8409
8557
  "transparency.opOperator": "Operator",
@@ -8437,10 +8585,28 @@
8437
8585
  "transparency.linkGuide": "The operator guide, for running your own node",
8438
8586
  "transparency.ctaBusiness": "For your business →",
8439
8587
  "transparency.ctaPrivacy": "Privacy →",
8588
+ "landing.footTransparency": "AI transparency",
8440
8589
  "landing.transLine": "Content a model wrote here carries a record of how it was made, and a label where a person reads it.",
8441
8590
  "landing.transCta": "How this node marks AI content →",
8442
8591
  "biz.transTitle": "AI transparency your compliance officer can read",
8443
8592
  "biz.trans1": "Article 50 of the EU AI Act has applied since 2 August 2026. What you get here is an EU-built, self-hostable platform where AI provenance is a primitive of the layer every app sits on: content a model produced carries a record of how it was made, a person reading it on the node’s own surfaces sees a label, and the operator’s legal identity and supervisory authority sit at a fixed machine-readable address your compliance officer can fetch without asking us. Content the node served can be checked by anyone, byte for byte, with no account.",
8444
8593
  "biz.trans2": "What stays yours: the obligations that come with what you publish. Running on AIMEAT does not discharge them, and we would rather say so here than have you discover it later. What the platform does is make marking, labelling and the record the default path instead of a project.",
8445
- "biz.transCta": "How this node marks AI content →"
8594
+ "biz.transCta": "How this node marks AI content →",
8595
+ "voice.record": "Record a voice message",
8596
+ "voice.recording": "Recording",
8597
+ "voice.stop": "Stop",
8598
+ "voice.cancel": "Discard recording",
8599
+ "voice.capped": "Reached the {n} second limit",
8600
+ "voice.errDenied": "Microphone access was denied. Allow it in your browser's site settings.",
8601
+ "voice.errNoMic": "No microphone found.",
8602
+ "voice.errUnsupported": "This browser cannot record audio.",
8603
+ "voice.errFailed": "Recording failed.",
8604
+ "inbox.transcript": "Transcript",
8605
+ "inbox.transcriptBySender": "written by the sender",
8606
+ "inbox.transcriptByYou": "transcribed by you ({model})",
8607
+ "inbox.transcribe": "Transcribe",
8608
+ "inbox.transcribing": "Transcribing…",
8609
+ "inbox.transcribeFailed": "Transcription failed.",
8610
+ "inbox.transcribeNoModel": "Choose a transcription model in Settings to turn speech into text.",
8611
+ "inbox.voiceMessage": "Voice message"
8446
8612
  }
@@ -2985,7 +2985,27 @@
2985
2985
  "agCapSaved": "Kulutusraja tallennettu",
2986
2986
  "agCapResetBtn": "Nollaa laskuri",
2987
2987
  "agCapReset": "Laskuri nollattu",
2988
- "agCapFailed": "Rajan muuttaminen ei onnistunut"
2988
+ "agCapFailed": "Rajan muuttaminen ei onnistunut",
2989
+ "cxTitle": "Liitetyt tilit",
2990
+ "cxIntro": "Tilit jotka olet liittänyt muihin palveluihin. Tunnus pysyy tällä nodella — appi saa tietää vain minkä tilin se saa käyttöönsä, ei itse tiliä.",
2991
+ "cxEmpty": "Et ole vielä liittänyt yhtään tiliä.",
2992
+ "cxConnect": "Liitä",
2993
+ "cxConnecting": "Liitetään…",
2994
+ "cxDisconnect": "Katkaise",
2995
+ "cxReconnect": "Valtuuta uudelleen",
2996
+ "cxNeedsReauth": "vaatii uuden valtuutuksen",
2997
+ "cxInstance": "instanssin osoite, esim. mastodon.social",
2998
+ "cxConfirm": "Katkaistaanko {account}? Sinne julkaisevat apit eivät enää pysty siihen.",
2999
+ "cxRevokedTold": "Katkaistu, ja palvelulle kerrottiin.",
3000
+ "cxRevokedLocal": "Katkaistu täällä. Palveluun ei saatu yhteyttä, joten tarkista tilanne myös sieltä.",
3001
+ "cxRevokeFailed": "Tilin katkaisu ei onnistunut",
3002
+ "cxConnectFailed": "Tilin liittämistä ei saatu käyntiin",
3003
+ "cxNoteMastodonNeeds": "Instanssisi osoite, esimerkiksi mastodon.social.",
3004
+ "cxNoteMastodonBefore": "Tilisi asuu yhdellä instanssilla, ja sama nimi toisella instanssilla on eri tili.",
3005
+ "cxNoteYoutubeBefore": "Kirjaudu sillä Google-tilillä joka omistaa kanavan. Tili jolla ei ole YouTube-kanavaa liittyy kyllä, mutta sillä ei ole mihin julkaista.",
3006
+ "cxNoteBlueskyNeeds": "App password. Se ei ole Bluesky-salasanasi.",
3007
+ "cxNoteBlueskyWhere": "Bluesky → Settings → Privacy and security → App passwords.",
3008
+ "cxNoteBlueskyBefore": "Tämä on ainoa palvelu joka pyytää kopioimaan salaisuuden meille sen sijaan että hyväksyisit sen heidän omalla sivullaan. Voit perua sen Blueskyssä milloin tahansa, eikä sillä voi kirjautua sinuna."
2989
3009
  },
2990
3010
  "nodes": {
2991
3011
  "title": "Henkilökohtaiset solmut",
@@ -3817,7 +3837,133 @@
3817
3837
  "pinRemove": "Irrota",
3818
3838
  "pinLimit": "Enintään 5 kiinnitettyä"
3819
3839
  },
3820
- "mcpConnected": "MCP kytketty"
3840
+ "mcpConnected": "MCP kytketty",
3841
+ "openrouter": {
3842
+ "title": "Tekoälypalvelu",
3843
+ "statusReady": "Avain tallennettu",
3844
+ "statusNoKey": "Ei avainta",
3845
+ "section": {
3846
+ "connection": "Yhteys",
3847
+ "models": "Mallit",
3848
+ "params": "Mallin parametrit",
3849
+ "budget": "Budjetti ja sovellusten kulutus"
3850
+ },
3851
+ "provider": "Palvelu",
3852
+ "provider_openrouter": "OpenRouter",
3853
+ "provider_lmstudio": "LM Studio",
3854
+ "provider_custom": "Oma (OpenAI-yhteensopiva)",
3855
+ "baseUrl": "API-osoite",
3856
+ "baseUrl_hint": "https://…/v1",
3857
+ "apiKey": "API-avain",
3858
+ "apiKeyPlaceholder": "sk-or-v1-…",
3859
+ "apiKeyMasked": "●●●●●●●●",
3860
+ "saveKey": "Tallenna avain",
3861
+ "keySaved": "Avain tallennettu.",
3862
+ "providerSaved": "Palvelu tallennettu.",
3863
+ "saveFailed": "Tallennus epäonnistui.",
3864
+ "save": "Tallenna",
3865
+ "cancel": "Peruuta",
3866
+ "saveModels": "Tallenna mallit",
3867
+ "modelsSaved": "Mallit tallennettu.",
3868
+ "saveParams": "Tallenna parametrit",
3869
+ "paramsSaved": "Parametrit tallennettu.",
3870
+ "testConnection": "Testaa",
3871
+ "testOk": "Yhteys toimii ({model}, {ms} ms).",
3872
+ "testFail": "Yhteys ei toimi",
3873
+ "testBudgetSpent": "Päivän tekoälybudjetti on käytetty — avaimessa ei ole vikaa",
3874
+ "delete": "Poista avain",
3875
+ "deleted": "Avain ja asetukset poistettu.",
3876
+ "deleteConfirm": "Poistetaanko API-avain ja tekoälyasetukset tältä solmulta?",
3877
+ "getKeyLink": "Hanki API-avain",
3878
+ "creditsLink": "Tarkista saldo",
3879
+ "modelsRefresh": "Päivitä mallit",
3880
+ "modelsHint": "Haetaan palvelusta, kun avain on tallennettu.",
3881
+ "modelsError": "Malleja ei saatu. Tarkista osoite ja avain, tallenna ja päivitä.",
3882
+ "modelsEmpty": "Palvelu ei palauttanut yhtään mallia. Tarkista osoite.",
3883
+ "paramDefault": "oletus",
3884
+ "autoRetry": "Yritä automaattisesti uudelleen validointivirheessä",
3885
+ "maxRetries": "Yritysten enimmäismäärä",
3886
+ "temperature": "Lämpötila",
3887
+ "temperature_hint": "0 = toistettava, 1 = oletus, 2 = luovin",
3888
+ "topP": "Top P",
3889
+ "topP_hint": "Nucleus-otanta: 0,1 = kapea, 1,0 = koko kirjo",
3890
+ "maxTokens": "Enimmäistokenit",
3891
+ "maxTokens_hint": "Vastauksen enimmäispituus. Tyhjä = mallin oma oletus.",
3892
+ "model": {
3893
+ "default": "Oletusmalli",
3894
+ "reasoning": "Päättelymalli",
3895
+ "reasoning_hint": "Käytetään suunnitteluun ja analyysiin, kun kutsuja pyytää päättelyroolia.",
3896
+ "execution": "Suoritusmalli",
3897
+ "execution_hint": "Käytetään koodiin, testeihin ja kokoamiseen, kun kutsuja pyytää suoritusroolia.",
3898
+ "rolesSummary": "Erilliset mallit päättelylle ja suoritukselle",
3899
+ "vision": "Kuvamalli",
3900
+ "vision_hint": "Lukee liittämäsi kuvat. Oletusmalli on usein pelkkä tekstimalli.",
3901
+ "visionNone": "Ei käytössä — älä lue kuvia",
3902
+ "stt": "Puheentunnistusmalli",
3903
+ "stt_hint": "Muuttaa ääniviestit tekstiksi. Ilman mallia litterointi on pois käytöstä.",
3904
+ "sttNone": "Ei käytössä — ei litterointia",
3905
+ "none": "Ei valittu",
3906
+ "clear": "Tyhjennä",
3907
+ "notInList": "ei nykyisessä listassa",
3908
+ "searchPlaceholder": "Hae {n} mallista…",
3909
+ "recommended": "Suositellut",
3910
+ "showAll": "Näytä kaikki {n}",
3911
+ "noMatch": "Haku ei osunut yhteenkään malliin.",
3912
+ "openPage": "Avaa mallin sivu OpenRouterissa",
3913
+ "customIdPlaceholder": "mallin tunnus, esim. whisper-1",
3914
+ "customIdUse": "Käytä",
3915
+ "customIdHint": "Oma palvelin voi tarjota malleja, joita sen katalogi ei listaa."
3916
+ },
3917
+ "price": {
3918
+ "perMillionIn": "{usd} / M sisään",
3919
+ "perMillionOut": "{usd} / M ulos",
3920
+ "free": "ilmainen",
3921
+ "context": "konteksti {n}",
3922
+ "audioReported": "hinta {value}"
3923
+ },
3924
+ "stt": {
3925
+ "language": "Kieli",
3926
+ "languageAuto": "Tunnista automaattisesti",
3927
+ "language_hint": "Vihje auttaa yhdessä tunnetussa kielessä; jätä automaattiseksi sekakieliselle puheelle.",
3928
+ "lang_fi": "suomi",
3929
+ "lang_en": "englanti",
3930
+ "lang_sv": "ruotsi",
3931
+ "lang_de": "saksa",
3932
+ "lang_fr": "ranska",
3933
+ "lang_es": "espanja",
3934
+ "lang_et": "viro",
3935
+ "listEmpty": "Tämä palvelu ei tarjoa litterointimalleja.",
3936
+ "test": "Testaa litterointi",
3937
+ "testing": "Litteroidaan…",
3938
+ "testNeedsModel": "Valitse ensin malli.",
3939
+ "testFailed": "Testi epäonnistui.",
3940
+ "testSilent": "(ei tunnistettu mitään)",
3941
+ "measured": "Mitattu: {seconds} s ääntä, {cost} $.",
3942
+ "costNotReported": "Palvelu ei ilmoittanut hintaa."
3943
+ },
3944
+ "budget": {
3945
+ "title": "Päivittäinen tekoälybudjetti",
3946
+ "desc": "Kaikki avaintasi kuluttava jakaa tämän budjetin: AIMEAT.ai.complete() -kutsut sovelluksista ja litterointi. Kun budjetti on käytetty, seuraavat kutsut hylätään.",
3947
+ "change": "Muuta",
3948
+ "budgetSaved": "Budjetti tallennettu.",
3949
+ "budgetRange": "Budjetin on oltava luku väliltä 0–1000.",
3950
+ "capRange": "Sovelluksen \"{app}\" katon on oltava luku väliltä 0–1000.",
3951
+ "capsSaved": "Sovelluskohtaiset rajat tallennettu.",
3952
+ "saveCaps": "Tallenna sovelluskohtaiset rajat",
3953
+ "saveFailed": "Tallennus epäonnistui.",
3954
+ "perApp": "Sovelluskohtaiset rajat ja kulutus ({n})",
3955
+ "perAppHint": "Jokainen sovellus saa kuluttaa koko päiväbudjetin. Aseta katto pitääksesi yhden sen alla; tyhjä = koko budjetti.",
3956
+ "colApp": "Sovellus",
3957
+ "colSpent": "Kulutettu tänään",
3958
+ "colCap": "Päiväkatto ($)",
3959
+ "colCalls": "Kutsuja",
3960
+ "chartTitle": "Käyttö 30 päivän ajalta",
3961
+ "metricCost": "Kulu",
3962
+ "metricTokens": "Tokenit",
3963
+ "metricSeconds": "Sekunnit",
3964
+ "footnote": "Hinta on arvio, kun palvelu ei ilmoita sitä (LM Studio, oma palvelin). Palveluntarjoajan oma näkymä on lasku, joka pätee."
3965
+ }
3966
+ }
3821
3967
  },
3822
3968
  "dev": {
3823
3969
  "title": "Yhdistä tekoälysi tähän nodeen",
@@ -8379,23 +8525,23 @@
8379
8525
  "unstated": "Tekoälyn osuutta ei ole kerrottu"
8380
8526
  }
8381
8527
  },
8382
- "aiTransparency.title": "Tekoälyn läpinäkyvyys — mitä olet julkaissut",
8383
- "aiTransparency.desc": "Kuinka suuren osan julkaisemastasi sisällöstä on kirjoittanut malli, ja kuinka suuri osa siitä on merkitty.",
8384
- "aiTransparency.unlabelled": "julkista, merkitsemättä",
8385
- "aiTransparency.labelled": "julkista, merkittynä",
8386
- "aiTransparency.publicTotal": "julkista kohdetta",
8387
- "aiTransparency.total": "tietuetta kaikkiaan",
8388
- "aiTransparency.scopeNote": "Luvut kattavat sen sisällön, josta tällä solmulla on alkuperätietue. Sisältö, jolla ei ole tietuetta, jää toteamatta eikä näy täällä.",
8389
- "aiTransparency.unlabelledHelp": "Nämä on tuottanut malli, kukaan ei ole kirjannut tarkastaneensa niitä, ja kuka tahansa voi lukea ne. Artiklan 50(4) mukaan tästä yhdistelmästä seuraa merkintävelvollisuus. Jos ihminen on lukenut ja hyväksynyt sisällön, kirjaa se — silloin merkintää ei enää tarvita.",
8390
- "aiTransparency.unknownSource": "lähde tuntematon",
8391
- "aiTransparency.openRecord": "Avaa tietue",
8392
- "aiTransparency.showingOf": "Näytetään {shown}/{total}.",
8393
- "aiTransparency.appsWithGap": "Sovellukset, jotka tuottavat sisältöä eivätkä kerro siitä",
8394
- "aiTransparency.policyTitle": "Mitä tämä solmu kirjaa mallikutsusta",
8395
- "aiTransparency.retention": "Säilytys",
8396
- "aiTransparency.neverContains": "Ei koskaan sisällä",
8397
- "aiTransparency.loadFailed": "Läpinäkyvyystietojasi ei voitu lukea.",
8398
- "aiTransparency.loading": "Luetaan tietueitasi…",
8528
+ "aiTransparencyMine.title": "Tekoälyn läpinäkyvyys — mitä olet julkaissut",
8529
+ "aiTransparencyMine.desc": "Kuinka suuren osan julkaisemastasi sisällöstä on kirjoittanut malli, ja kuinka suuri osa siitä on merkitty.",
8530
+ "aiTransparencyMine.unlabelled": "julkista, merkitsemättä",
8531
+ "aiTransparencyMine.labelled": "julkista, merkittynä",
8532
+ "aiTransparencyMine.publicTotal": "julkista kohdetta",
8533
+ "aiTransparencyMine.total": "tietuetta kaikkiaan",
8534
+ "aiTransparencyMine.scopeNote": "Luvut kattavat sen sisällön, josta tällä solmulla on alkuperätietue. Sisältö, jolla ei ole tietuetta, jää toteamatta eikä näy täällä.",
8535
+ "aiTransparencyMine.unlabelledHelp": "Nämä on tuottanut malli, kukaan ei ole kirjannut tarkastaneensa niitä, ja kuka tahansa voi lukea ne. Artiklan 50(4) mukaan tästä yhdistelmästä seuraa merkintävelvollisuus. Jos ihminen on lukenut ja hyväksynyt sisällön, kirjaa se — silloin merkintää ei enää tarvita.",
8536
+ "aiTransparencyMine.unknownSource": "lähde tuntematon",
8537
+ "aiTransparencyMine.openRecord": "Avaa tietue",
8538
+ "aiTransparencyMine.showingOf": "Näytetään {shown}/{total}.",
8539
+ "aiTransparencyMine.appsWithGap": "Sovellukset, jotka tuottavat sisältöä eivätkä kerro siitä",
8540
+ "aiTransparencyMine.policyTitle": "Mitä tämä solmu kirjaa mallikutsusta",
8541
+ "aiTransparencyMine.retention": "Säilytys",
8542
+ "aiTransparencyMine.neverContains": "Ei koskaan sisällä",
8543
+ "aiTransparencyMine.loadFailed": "Läpinäkyvyystietojasi ei voitu lukea.",
8544
+ "aiTransparencyMine.loading": "Luetaan tietueitasi…",
8399
8545
  "transparency.title": "Näin tämä node merkitsee tekoälyn tekemän sisällön",
8400
8546
  "transparency.intro": "Kun malli kirjoittaa täällä jotain, node tallentaa miten se syntyi: mikä malli, milloin, kenen tunnuksella ja kuinka paljon ihminen oli mukana. Tämä alkuperätieto saa oman osoitteensa. Siellä missä ihminen lukee sisältöä tämän noden omilla sivuilla, alkuperätiedosta tulee näkyvä merkintä: EU:n tekoälytoimiston virallinen kuvake ja lyhyt lause suomeksi tai englanniksi sisällön vieressä, ja linkki koko alkuperätietoon. Ohjelmat saavat samat tiedot suoraan vastauksesta: HTTP-otsakkeista, sivun metatiedoista sekä markdown- ja MCP-pinnoilta.",
8401
8547
  "transparency.limitsTitle": "Mitä tämä ei tee",
@@ -8404,6 +8550,8 @@
8404
8550
  "transparency.limit2": "Merkinnän saa pois kopioimalla. Liitä sanat toiseen paikkaan, ja merkintä on poissa. Omassa osoitteessaan oleva alkuperätieto jää — juuri siksi kerroksia on kaksi — mutta mikään täällä ei tee tekstistä väärentämätöntä, emmekä väitä muuta.",
8405
8551
  "transparency.limit3": "Ennen tallennuksen alkua tehdyllä sisällöllä ei ole alkuperätietoa, eikä sitä saa jälkikäteen. Väite tavuista, joiden syntyä kukaan ei nähnyt, olisi keksitty.",
8406
8552
  "transparency.limit4": "Puuttuva alkuperätieto tarkoittaa, ettei asiasta ole sanottu mitään. Se ei koskaan tarkoita, että kirjoittaja oli ihminen.",
8553
+ "transparency.seeItLead": "Missä sen voi nähdä:",
8554
+ "transparency.seeItTail": "on tämän noden appi joka tuottaa tekstiä, ja node löysi merkintäkutsun siitä lähdekoodista jota se tarjoilee.",
8407
8555
  "transparency.opTitle": "Kuka nodea ylläpitää ja kuka sitä valvoo",
8408
8556
  "transparency.opLead": "Nämä luetaan tämän noden omasta elävästä ilmoituksesta sivua avattaessa, joten ne ovat täsmälleen samat arvot jotka kone saa.",
8409
8557
  "transparency.opOperator": "Ylläpitäjä",
@@ -8437,10 +8585,28 @@
8437
8585
  "transparency.linkGuide": "Ylläpitäjän ohje oman noden ajamiseen",
8438
8586
  "transparency.ctaBusiness": "Yrityksellesi →",
8439
8587
  "transparency.ctaPrivacy": "Tietosuoja →",
8588
+ "landing.footTransparency": "Tekoälyn läpinäkyvyys",
8440
8589
  "landing.transLine": "Täällä mallin kirjoittama sisältö kantaa mukanaan tiedon siitä, miten se on tehty, ja merkinnän siellä missä ihminen sen lukee.",
8441
8590
  "landing.transCta": "Näin tämä node merkitsee tekoälysisällön →",
8442
8591
  "biz.transTitle": "Tekoälyn läpinäkyvyys, jonka vastuuhenkilösi voi lukea",
8443
8592
  "biz.trans1": "EU:n tekoälyasetuksen 50 artiklaa on sovellettu 2.8.2026 alkaen. Täällä saat eurooppalaisen, itse ylläpidettävän alustan, jossa tekoälyn alkuperätieto kuuluu siihen kerrokseen jonka päällä jokainen appi toimii: mallin tuottama sisältö kantaa mukanaan tiedon siitä miten se syntyi, noden omilla pinnoilla lukija näkee merkinnän, ja ylläpitäjän oikeushenkilö sekä valvova viranomainen ovat kiinteässä koneluettavassa osoitteessa, jonka vastuuhenkilösi voi hakea kysymättä meiltä. Noden lähettämän sisällön voi kuka tahansa tarkistaa tavu tavulta ilman tiliä.",
8444
8593
  "biz.trans2": "Sinulle jää vastuu siitä mitä itse julkaiset. AIMEATin päällä ajaminen ei poista sitä, ja sanomme sen mieluummin tässä kuin annamme sinun huomata sen myöhemmin. Alusta tekee sen, että merkitseminen, tallentaminen ja näyttäminen on oletustie eikä projekti.",
8445
- "biz.transCta": "Näin tämä node merkitsee tekoälysisällön →"
8594
+ "biz.transCta": "Näin tämä node merkitsee tekoälysisällön →",
8595
+ "voice.record": "Nauhoita ääniviesti",
8596
+ "voice.recording": "Nauhoitetaan",
8597
+ "voice.stop": "Lopeta",
8598
+ "voice.cancel": "Hylkää nauhoitus",
8599
+ "voice.capped": "Saavutti {n} sekunnin rajan",
8600
+ "voice.errDenied": "Mikrofonin käyttö estettiin. Salli se selaimen sivustoasetuksista.",
8601
+ "voice.errNoMic": "Mikrofonia ei löytynyt.",
8602
+ "voice.errUnsupported": "Tämä selain ei osaa nauhoittaa ääntä.",
8603
+ "voice.errFailed": "Nauhoitus epäonnistui.",
8604
+ "inbox.transcript": "Tekstitys",
8605
+ "inbox.transcriptBySender": "lähettäjän kirjoittama",
8606
+ "inbox.transcriptByYou": "sinun litteroimasi ({model})",
8607
+ "inbox.transcribe": "Litteroi",
8608
+ "inbox.transcribing": "Litteroidaan…",
8609
+ "inbox.transcribeFailed": "Litterointi epäonnistui.",
8610
+ "inbox.transcribeNoModel": "Valitse asetuksista puheentunnistusmalli, niin saat puheen tekstiksi.",
8611
+ "inbox.voiceMessage": "Ääniviesti"
8446
8612
  }