@davait/aipictury 1.10.4 → 1.10.6

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.
package/ext/accountUi.js CHANGED
@@ -213,11 +213,31 @@ function register(context, { registry, sessionsView, serverUrl }) {
213
213
  const yes = 'Delete everything'
214
214
  const ok = await vscode.window.showWarningMessage('Delete everything of yours kept with your AIPictury account?', {
215
215
  modal: true, detail: 'Conversations and projects, rules, preferences, usage, your pictures and clips (Renders, and every file kept '
216
- + 'with them), remote-control links and the list of your machines — from every machine and the web app. What is on this '
217
- + 'machine stays, and is not sent back up by itself: only what you do from now on is kept again (while its switch is on).' }, yes)
216
+ + 'with them), remote-control links and the list of your machines — from every machine and the web app; and on your GPU '
217
+ + 'server, its copies of your renders, chats and attached files. Your GPU server choice stays (it is how your apps find it). '
218
+ + 'What is on this machine stays, and is not sent back up by itself: only what you do from now on is kept again (while '
219
+ + 'its switch is on).' }, yes)
218
220
  if (ok !== yes) return null
221
+ const server = gpuServer.url() // read first: the delete must find it
219
222
  const n = await cloud.deleteEverything()
220
- return `Deleted (${n} records and files). Your account stays — sign out or keep using it.`
223
+ const there = await forgetOnServer('all', server)
224
+ return `Deleted (${n} records and files)${there}. Your account stays — sign out or keep using it.`
225
+ }
226
+
227
+ /** The GPU server's own copies of the account's work go too — renders, chats, attached files,
228
+ * its copy of the rules: the web app listed them (Renders) and copied them back. Said, not
229
+ * hidden, when the server cannot be reached. */
230
+ async function forgetOnServer(what, server = gpuServer.url()) {
231
+ if (!server) return '; no GPU server is set, so nothing there was touched'
232
+ try {
233
+ const r = await fetch(`${server}/api/account/data?what=${what}`, { method: 'DELETE', signal: AbortSignal.timeout(120_000) })
234
+ if (!r.ok) throw new Error(`it answered ${r.status}`)
235
+ const d = (await r.json()).deleted || {}
236
+ return what === 'chats' ? `, and ${d.chats || 0} chats on the GPU server`
237
+ : `, and on the GPU server ${d.renders || 0} renders, ${d.chats || 0} chats and ${d.files || 0} files`
238
+ } catch (error) {
239
+ return `. The GPU server could not be reached (${error.message}): its copies stay — delete again once it answers`
240
+ }
221
241
  }
222
242
 
223
243
  const KIND_LABEL = { conversations: 'conversations', memory: 'rules', settings: 'preferences', usage: 'usage' }
@@ -227,8 +247,11 @@ function register(context, { registry, sessionsView, serverUrl }) {
227
247
  const ok = await vscode.window.showWarningMessage(`No longer keeping your ${KIND_LABEL[kind] || kind} with your account. Delete the ones already kept?`, {
228
248
  modal: true, detail: 'From every machine and the web app. What is on this machine stays.' }, yes, 'Keep them')
229
249
  if (ok !== yes) return null
250
+ const server = gpuServer.url()
230
251
  const n = await cloud.deleteKind(kind)
231
- return `No longer sent, and the ${KIND_LABEL[kind] || kind} kept before are deleted (${n} records).`
252
+ // Conversations: the GPU server's copies of the web app's chats go too (else copied back).
253
+ const there = kind === 'conversations' ? await forgetOnServer('chats', server) : ''
254
+ return `No longer sent, and the ${KIND_LABEL[kind] || kind} kept before are deleted (${n} records${there}).`
232
255
  }
233
256
 
234
257
  function localPreferences() {
@@ -248,7 +271,7 @@ function register(context, { registry, sessionsView, serverUrl }) {
248
271
  context.subscriptions.push({ dispose: () => { globalThis.fetch = plainFetch } })
249
272
 
250
273
  account.user().then(changed).catch(() => changed(null))
251
- return { account, cloud, signedIn, signIn, signOut, deleteCloudData, deleteKind, keeps, user: () => user }
274
+ return { account, cloud, signedIn, signIn, signOut, deleteCloudData, deleteKind, forgetOnServer, keeps, user: () => user }
252
275
  }
253
276
 
254
277
  async function projectRulesText() {
@@ -278,7 +301,7 @@ function accountSpec(ctl, note) {
278
301
  { title: 'Kept with your account', items: kinds.map(([id, label, detail]) => ({ id: `keep:${id}`, label, detail, toggle: { on: config().get(`cloud.${id}`, true) } })) },
279
302
  { title: 'Account', items: [
280
303
  { id: 'signout', label: 'Sign out', detail: 'Forgets the session on this machine: nothing of the account stays here.', actions: [{ id: 'signout', label: 'Sign out', always: true }] },
281
- { id: 'delete', label: 'Delete what is kept in the cloud', detail: 'Everything above, and your pictures and clips (Renders), from every machine and the web app. Local files stay.', actions: [{ id: 'delete', label: 'Delete…', danger: true, always: true }] },
304
+ { id: 'delete', label: 'Delete what is kept in the cloud', detail: 'Everything above, and your pictures and clips (Renders), from every machine, the web app and your GPU server. Local files stay.', actions: [{ id: 'delete', label: 'Delete…', danger: true, always: true }] },
282
305
  ] },
283
306
  ] }
284
307
  }
package/ext/cloud.js CHANGED
@@ -378,6 +378,7 @@ class Cloud {
378
378
  async deleteKind(kind) {
379
379
  const base = await this.base()
380
380
  const writes = []
381
+ let kept = null
381
382
  if (kind === 'conversations' || kind === 'memory') {
382
383
  for (const p of await this.db.list(`${base}/projects`)) {
383
384
  if (kind === 'memory') { writes.push({ delete: `${base}/projects/${p.id}/memory/current` }); continue }
@@ -391,19 +392,31 @@ class Cloud {
391
392
  if (kind === 'memory') writes.push({ delete: `${base}/memory/rules` })
392
393
  } else if (kind === 'settings') {
393
394
  writes.push({ delete: `${base}/settings/preferences` })
395
+ kept = await this.serverChoice()
394
396
  } else if (kind === 'usage') {
395
397
  for (const d of await this.db.list(`${base}/usage`)) writes.push({ delete: `${base}/usage/${d.id}` })
396
398
  } else {
397
399
  throw new Error(`nothing kept as ${kind}`)
398
400
  }
399
401
  await this.db.batch(writes)
402
+ if (kept) await this.keepServerChoice(kept)
400
403
  if (kind === 'conversations') this.pushed.clear()
401
404
  return writes.length
402
405
  }
403
406
 
407
+ /** The GPU server chosen with the account (its addresses), or null. */
408
+ async serverChoice() { return (await this.getPreferences().catch(() => null))?.values?.gpuServer || null }
409
+
410
+ /** Put back after a delete: it is how every app finds your server (VS Code reads it from the
411
+ * account), not something you made — deleting it left VS Code with no server at all. */
412
+ async keepServerChoice(gpuServer) {
413
+ await this.db.set(`${await this.base()}/settings/preferences`, { values: { gpuServer }, updated: Date.now(), device: this.device.id })
414
+ }
415
+
404
416
  async deleteEverything() {
405
417
  const base = await this.base()
406
418
  const writes = []
419
+ const server = await this.serverChoice()
407
420
  for (const p of await this.db.list(`${base}/projects`)) {
408
421
  for (const c of await this.db.list(`${base}/projects/${p.id}/conversations`)) {
409
422
  // Every chunk there is, not as many as the summary says: one left by a save cut short stays otherwise.
@@ -421,6 +434,7 @@ class Cloud {
421
434
  if (this.storage) for (const o of await this.storage.list(`${base}/media/`)) { await this.storage.delete(o.name); writes.push(o) }
422
435
  // The moment it was cleared: no app carries back up what it still holds from before.
423
436
  await this.db.set(base, { cleared: Date.now() })
437
+ if (server) await this.keepServerChoice(server)
424
438
  this.pushed.clear()
425
439
  return writes.length
426
440
  }
package/ext/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "aipictury",
3
3
  "displayName": "AIPictury",
4
4
  "description": "A coding agent and a generation studio running on your own GPU, with uncensored local models.",
5
- "version": "1.10.4",
5
+ "version": "1.10.6",
6
6
  "publisher": "aipictury",
7
7
  "license": "SEE LICENSE IN LICENSE.md",
8
8
  "engines": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davait/aipictury",
3
- "version": "1.10.4",
3
+ "version": "1.10.6",
4
4
  "description": "The AIPictury agent in a terminal: the VS Code extension's agent, on your own GPU server, signed in to your AIPictury account.",
5
5
  "bin": {
6
6
  "aipictury": "main.js"