omnius 1.0.700 → 1.0.701

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/dist/library.js CHANGED
@@ -247454,6 +247454,145 @@ init_process_lifecycle();
247454
247454
  // packages/execution/dist/tools/desktop-control.js
247455
247455
  init_system_deps();
247456
247456
 
247457
+ // packages/execution/dist/tools/archive-extract.js
247458
+ init_process_async();
247459
+ var EXTRACT = String.raw`
247460
+ import json, os, re, stat, sys, tarfile, zipfile
247461
+ source, stage = sys.argv[1:3]
247462
+ limits = json.loads(sys.argv[3])
247463
+ seen, kinds, preview = set(), {}, []
247464
+ entries = files = total = 0
247465
+ root = os.open(stage, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
247466
+
247467
+ def path_parts(name, kind):
247468
+ if not isinstance(name, str) or not name or '\x00' in name or '\\' in name or name.startswith('/') or re.match(r'^[a-zA-Z]:', name):
247469
+ raise ValueError('unsafe absolute or invalid archive path')
247470
+ raw = name.split('/')
247471
+ if '..' in raw:
247472
+ raise ValueError('archive path traversal rejected')
247473
+ parts = [part for part in raw if part not in ('', '.')]
247474
+ key = '/'.join(parts)
247475
+ if not parts and kind != 'directory':
247476
+ raise ValueError('invalid empty file path')
247477
+ if key in seen:
247478
+ raise ValueError('duplicate archive path rejected')
247479
+ seen.add(key)
247480
+ for index in range(1, len(parts)):
247481
+ parent = '/'.join(parts[:index])
247482
+ if kinds.get(parent) == 'file':
247483
+ raise ValueError('archive file/directory collision rejected')
247484
+ kinds[parent] = 'directory'
247485
+ if key in kinds and (kind != 'directory' or kinds[key] != 'directory'):
247486
+ raise ValueError('archive path collision rejected')
247487
+ if key:
247488
+ kinds[key] = kind
247489
+ return parts
247490
+
247491
+ def parent_fd(parts):
247492
+ fd = os.dup(root)
247493
+ try:
247494
+ for part in parts:
247495
+ try:
247496
+ os.mkdir(part, 0o700, dir_fd=fd)
247497
+ except FileExistsError:
247498
+ pass
247499
+ child = os.open(part, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=fd)
247500
+ os.close(fd)
247501
+ fd = child
247502
+ return fd
247503
+ except BaseException:
247504
+ os.close(fd)
247505
+ raise
247506
+
247507
+ def member(name, kind, declared, opener):
247508
+ global entries, files, total
247509
+ entries += 1
247510
+ if limits.get('maxEntries') is not None and entries > limits['maxEntries']:
247511
+ raise ValueError('explicit maxEntries limit exceeded')
247512
+ parts = path_parts(name, kind)
247513
+ if kind == 'directory':
247514
+ fd = parent_fd(parts)
247515
+ os.close(fd)
247516
+ else:
247517
+ if declared < 0:
247518
+ raise ValueError('invalid archive file size')
247519
+ if limits.get('maxOutputBytes') is not None and total + declared > limits['maxOutputBytes']:
247520
+ raise ValueError('explicit maxOutputBytes limit exceeded')
247521
+ fd = parent_fd(parts[:-1])
247522
+ try:
247523
+ output = os.open(parts[-1], os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600, dir_fd=fd)
247524
+ finally:
247525
+ os.close(fd)
247526
+ written = 0
247527
+ with os.fdopen(output, 'wb') as target, opener() as input_file:
247528
+ while True:
247529
+ chunk = input_file.read(1024 * 1024)
247530
+ if not chunk:
247531
+ break
247532
+ if limits.get('maxOutputBytes') is not None and total + len(chunk) > limits['maxOutputBytes']:
247533
+ raise ValueError('explicit maxOutputBytes limit exceeded')
247534
+ target.write(chunk)
247535
+ written += len(chunk)
247536
+ total += len(chunk)
247537
+ if written != declared:
247538
+ raise ValueError('archive member length mismatch')
247539
+ files += 1
247540
+ if len(preview) < 40:
247541
+ preview.append({'path': '/'.join(parts)[:512], 'kind': kind, 'bytes': declared if kind == 'file' else 0})
247542
+
247543
+ try:
247544
+ if zipfile.is_zipfile(source):
247545
+ archive_format = 'zip'
247546
+ with zipfile.ZipFile(source) as archive:
247547
+ for info in archive.infolist():
247548
+ mode = stat.S_IFMT(info.external_attr >> 16)
247549
+ if mode not in (0, stat.S_IFREG, stat.S_IFDIR):
247550
+ raise ValueError('archive links, devices and special entries are not allowed')
247551
+ kind = 'directory' if info.is_dir() or mode == stat.S_IFDIR else 'file'
247552
+ member(info.orig_filename, kind, info.file_size, lambda info=info: archive.open(info, 'r'))
247553
+ else:
247554
+ archive_format = 'tar'
247555
+ with tarfile.open(source, 'r|*') as archive:
247556
+ for info in archive:
247557
+ if not (info.isdir() or info.isreg()):
247558
+ raise ValueError('archive links, devices and special entries are not allowed')
247559
+ member(info.name, 'directory' if info.isdir() else 'file', info.size, lambda info=info: archive.extractfile(info))
247560
+ print(json.dumps({'format': archive_format, 'entries': entries, 'files': files,
247561
+ 'directories': sum(kind == 'directory' for kind in kinds.values()), 'bytes': total,
247562
+ 'preview': preview, 'previewOmitted': max(0, entries - len(preview))}))
247563
+ except BaseException as error:
247564
+ # Exception messages from standard readers can contain untrusted filenames;
247565
+ # report a bounded JSON string, never executable or control-sequence output.
247566
+ print(json.dumps({'error': str(error)[:600]}), file=sys.stderr)
247567
+ sys.exit(1)
247568
+ finally:
247569
+ os.close(root)
247570
+ `;
247571
+ var PUBLISH = String.raw`
247572
+ import ctypes, errno, json, os, stat, sys
247573
+ parent, stage, target, dev, ino = sys.argv[1:]
247574
+ try:
247575
+ fd = os.open(parent, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
247576
+ entry = os.stat(stage, dir_fd=fd, follow_symlinks=False)
247577
+ if not stat.S_ISDIR(entry.st_mode) or entry.st_dev != int(dev) or entry.st_ino != int(ino):
247578
+ raise ValueError('staging ownership changed before publication')
247579
+ libc = ctypes.CDLL(None, use_errno=True)
247580
+ rename = getattr(libc, 'renameat2', None)
247581
+ if rename is None:
247582
+ raise ValueError('atomic no-replace directory publication is unavailable on this platform')
247583
+ rename.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_uint]
247584
+ rename.restype = ctypes.c_int
247585
+ if rename(fd, os.fsencode(stage), fd, os.fsencode(target), 1) != 0:
247586
+ code = ctypes.get_errno()
247587
+ if code == errno.EEXIST:
247588
+ raise ValueError('destination already exists; nothing was overwritten')
247589
+ raise OSError(code, os.strerror(code))
247590
+ os.close(fd)
247591
+ except BaseException as error:
247592
+ print(json.dumps({'error': str(error)[:600]}), file=sys.stderr)
247593
+ sys.exit(1)
247594
+ `;
247595
+
247457
247596
  // packages/execution/dist/tools/change-log.js
247458
247597
  import { randomBytes } from "node:crypto";
247459
247598
  var _sessionId = `session-${Date.now()}-${randomBytes(3).toString("hex")}`;
@@ -245166,6 +245166,145 @@ init_process_lifecycle();
245166
245166
  // packages/execution/dist/tools/desktop-control.js
245167
245167
  init_system_deps();
245168
245168
 
245169
+ // packages/execution/dist/tools/archive-extract.js
245170
+ init_process_async();
245171
+ var EXTRACT = String.raw`
245172
+ import json, os, re, stat, sys, tarfile, zipfile
245173
+ source, stage = sys.argv[1:3]
245174
+ limits = json.loads(sys.argv[3])
245175
+ seen, kinds, preview = set(), {}, []
245176
+ entries = files = total = 0
245177
+ root = os.open(stage, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
245178
+
245179
+ def path_parts(name, kind):
245180
+ if not isinstance(name, str) or not name or '\x00' in name or '\\' in name or name.startswith('/') or re.match(r'^[a-zA-Z]:', name):
245181
+ raise ValueError('unsafe absolute or invalid archive path')
245182
+ raw = name.split('/')
245183
+ if '..' in raw:
245184
+ raise ValueError('archive path traversal rejected')
245185
+ parts = [part for part in raw if part not in ('', '.')]
245186
+ key = '/'.join(parts)
245187
+ if not parts and kind != 'directory':
245188
+ raise ValueError('invalid empty file path')
245189
+ if key in seen:
245190
+ raise ValueError('duplicate archive path rejected')
245191
+ seen.add(key)
245192
+ for index in range(1, len(parts)):
245193
+ parent = '/'.join(parts[:index])
245194
+ if kinds.get(parent) == 'file':
245195
+ raise ValueError('archive file/directory collision rejected')
245196
+ kinds[parent] = 'directory'
245197
+ if key in kinds and (kind != 'directory' or kinds[key] != 'directory'):
245198
+ raise ValueError('archive path collision rejected')
245199
+ if key:
245200
+ kinds[key] = kind
245201
+ return parts
245202
+
245203
+ def parent_fd(parts):
245204
+ fd = os.dup(root)
245205
+ try:
245206
+ for part in parts:
245207
+ try:
245208
+ os.mkdir(part, 0o700, dir_fd=fd)
245209
+ except FileExistsError:
245210
+ pass
245211
+ child = os.open(part, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW, dir_fd=fd)
245212
+ os.close(fd)
245213
+ fd = child
245214
+ return fd
245215
+ except BaseException:
245216
+ os.close(fd)
245217
+ raise
245218
+
245219
+ def member(name, kind, declared, opener):
245220
+ global entries, files, total
245221
+ entries += 1
245222
+ if limits.get('maxEntries') is not None and entries > limits['maxEntries']:
245223
+ raise ValueError('explicit maxEntries limit exceeded')
245224
+ parts = path_parts(name, kind)
245225
+ if kind == 'directory':
245226
+ fd = parent_fd(parts)
245227
+ os.close(fd)
245228
+ else:
245229
+ if declared < 0:
245230
+ raise ValueError('invalid archive file size')
245231
+ if limits.get('maxOutputBytes') is not None and total + declared > limits['maxOutputBytes']:
245232
+ raise ValueError('explicit maxOutputBytes limit exceeded')
245233
+ fd = parent_fd(parts[:-1])
245234
+ try:
245235
+ output = os.open(parts[-1], os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600, dir_fd=fd)
245236
+ finally:
245237
+ os.close(fd)
245238
+ written = 0
245239
+ with os.fdopen(output, 'wb') as target, opener() as input_file:
245240
+ while True:
245241
+ chunk = input_file.read(1024 * 1024)
245242
+ if not chunk:
245243
+ break
245244
+ if limits.get('maxOutputBytes') is not None and total + len(chunk) > limits['maxOutputBytes']:
245245
+ raise ValueError('explicit maxOutputBytes limit exceeded')
245246
+ target.write(chunk)
245247
+ written += len(chunk)
245248
+ total += len(chunk)
245249
+ if written != declared:
245250
+ raise ValueError('archive member length mismatch')
245251
+ files += 1
245252
+ if len(preview) < 40:
245253
+ preview.append({'path': '/'.join(parts)[:512], 'kind': kind, 'bytes': declared if kind == 'file' else 0})
245254
+
245255
+ try:
245256
+ if zipfile.is_zipfile(source):
245257
+ archive_format = 'zip'
245258
+ with zipfile.ZipFile(source) as archive:
245259
+ for info in archive.infolist():
245260
+ mode = stat.S_IFMT(info.external_attr >> 16)
245261
+ if mode not in (0, stat.S_IFREG, stat.S_IFDIR):
245262
+ raise ValueError('archive links, devices and special entries are not allowed')
245263
+ kind = 'directory' if info.is_dir() or mode == stat.S_IFDIR else 'file'
245264
+ member(info.orig_filename, kind, info.file_size, lambda info=info: archive.open(info, 'r'))
245265
+ else:
245266
+ archive_format = 'tar'
245267
+ with tarfile.open(source, 'r|*') as archive:
245268
+ for info in archive:
245269
+ if not (info.isdir() or info.isreg()):
245270
+ raise ValueError('archive links, devices and special entries are not allowed')
245271
+ member(info.name, 'directory' if info.isdir() else 'file', info.size, lambda info=info: archive.extractfile(info))
245272
+ print(json.dumps({'format': archive_format, 'entries': entries, 'files': files,
245273
+ 'directories': sum(kind == 'directory' for kind in kinds.values()), 'bytes': total,
245274
+ 'preview': preview, 'previewOmitted': max(0, entries - len(preview))}))
245275
+ except BaseException as error:
245276
+ # Exception messages from standard readers can contain untrusted filenames;
245277
+ # report a bounded JSON string, never executable or control-sequence output.
245278
+ print(json.dumps({'error': str(error)[:600]}), file=sys.stderr)
245279
+ sys.exit(1)
245280
+ finally:
245281
+ os.close(root)
245282
+ `;
245283
+ var PUBLISH = String.raw`
245284
+ import ctypes, errno, json, os, stat, sys
245285
+ parent, stage, target, dev, ino = sys.argv[1:]
245286
+ try:
245287
+ fd = os.open(parent, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
245288
+ entry = os.stat(stage, dir_fd=fd, follow_symlinks=False)
245289
+ if not stat.S_ISDIR(entry.st_mode) or entry.st_dev != int(dev) or entry.st_ino != int(ino):
245290
+ raise ValueError('staging ownership changed before publication')
245291
+ libc = ctypes.CDLL(None, use_errno=True)
245292
+ rename = getattr(libc, 'renameat2', None)
245293
+ if rename is None:
245294
+ raise ValueError('atomic no-replace directory publication is unavailable on this platform')
245295
+ rename.argtypes = [ctypes.c_int, ctypes.c_char_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_uint]
245296
+ rename.restype = ctypes.c_int
245297
+ if rename(fd, os.fsencode(stage), fd, os.fsencode(target), 1) != 0:
245298
+ code = ctypes.get_errno()
245299
+ if code == errno.EEXIST:
245300
+ raise ValueError('destination already exists; nothing was overwritten')
245301
+ raise OSError(code, os.strerror(code))
245302
+ os.close(fd)
245303
+ except BaseException as error:
245304
+ print(json.dumps({'error': str(error)[:600]}), file=sys.stderr)
245305
+ sys.exit(1)
245306
+ `;
245307
+
245169
245308
  // packages/execution/dist/tools/change-log.js
245170
245309
  import { randomBytes } from "node:crypto";
245171
245310
  var _sessionId = `session-${Date.now()}-${randomBytes(3).toString("hex")}`;
@@ -31584,6 +31584,38 @@
31584
31584
  }
31585
31585
  ]
31586
31586
  },
31587
+ {
31588
+ "id": "guide.telegram-large-files",
31589
+ "kind": "guide",
31590
+ "title": "Receiving large Telegram files",
31591
+ "summary": "Omnius has no default inbound attachment byte cap or cache byte cap. Downloads stream to disk, retaining only a small signature prefix in memory. Cache item-count and age eviction still apply. Authenticated admin DMs can pass an uploaded document's exact Telegram alias to fileread or archiveextract; extraction returns a destination and file manifest for subs",
31592
+ "keywords": [
31593
+ "telegram",
31594
+ "large",
31595
+ "files",
31596
+ "md"
31597
+ ],
31598
+ "maturity": "stable",
31599
+ "audiences": [
31600
+ "user",
31601
+ "integrator",
31602
+ "coding-agent"
31603
+ ],
31604
+ "layer": "documentation",
31605
+ "interfaces": [
31606
+ {
31607
+ "type": "file",
31608
+ "target": "docs/telegram-large-files.md"
31609
+ }
31610
+ ],
31611
+ "references": [
31612
+ {
31613
+ "type": "documentation",
31614
+ "target": "docs/telegram-large-files.md",
31615
+ "relation": "canonical-artifact"
31616
+ }
31617
+ ]
31618
+ },
31587
31619
  {
31588
31620
  "id": "guide.telegram-mid-horizon-download-loop-handoff",
31589
31621
  "kind": "guide",
@@ -35244,6 +35276,82 @@
35244
35276
  }
35245
35277
  ]
35246
35278
  },
35279
+ {
35280
+ "id": "guide.work-orders-runtime-health-remediation-wo-51-large-telegram-attachments-uppercase",
35281
+ "kind": "guide",
35282
+ "title": "WO-51: Receive and unpack large Telegram attachments",
35283
+ "summary": "Status: source repair complete and verified. Publication and Local Bot API live acceptance remain with the operator.",
35284
+ "keywords": [
35285
+ "work",
35286
+ "orders",
35287
+ "runtime",
35288
+ "health",
35289
+ "remediation",
35290
+ "WO",
35291
+ "51",
35292
+ "large",
35293
+ "telegram",
35294
+ "attachments",
35295
+ "md"
35296
+ ],
35297
+ "maturity": "internal",
35298
+ "audiences": [
35299
+ "maintainer",
35300
+ "large-context-agent"
35301
+ ],
35302
+ "layer": "documentation",
35303
+ "interfaces": [
35304
+ {
35305
+ "type": "file",
35306
+ "target": "docs/work-orders/runtime-health-remediation/WO-51-large-telegram-attachments.md"
35307
+ }
35308
+ ],
35309
+ "references": [
35310
+ {
35311
+ "type": "documentation",
35312
+ "target": "docs/work-orders/runtime-health-remediation/WO-51-large-telegram-attachments.md",
35313
+ "relation": "canonical-artifact"
35314
+ }
35315
+ ]
35316
+ },
35317
+ {
35318
+ "id": "guide.work-orders-runtime-health-remediation-wo-52-steering-projection-preservation-uppercase",
35319
+ "kind": "guide",
35320
+ "title": "WO-52: Preserve required steering instructions in the actual model request",
35321
+ "summary": "Status: source repair complete; verified and ready for publication. Live acceptance follows the user's publication.",
35322
+ "keywords": [
35323
+ "work",
35324
+ "orders",
35325
+ "runtime",
35326
+ "health",
35327
+ "remediation",
35328
+ "WO",
35329
+ "52",
35330
+ "steering",
35331
+ "projection",
35332
+ "preservation",
35333
+ "md"
35334
+ ],
35335
+ "maturity": "internal",
35336
+ "audiences": [
35337
+ "maintainer",
35338
+ "large-context-agent"
35339
+ ],
35340
+ "layer": "documentation",
35341
+ "interfaces": [
35342
+ {
35343
+ "type": "file",
35344
+ "target": "docs/work-orders/runtime-health-remediation/WO-52-steering-projection-preservation.md"
35345
+ }
35346
+ ],
35347
+ "references": [
35348
+ {
35349
+ "type": "documentation",
35350
+ "target": "docs/work-orders/runtime-health-remediation/WO-52-steering-projection-preservation.md",
35351
+ "relation": "canonical-artifact"
35352
+ }
35353
+ ]
35354
+ },
35247
35355
  {
35248
35356
  "id": "guide.work-orders-telegram-dmn-wo-22-dmn-outreach-and-learning-uppercase",
35249
35357
  "kind": "guide",
@@ -39664,6 +39772,62 @@
39664
39772
  }
39665
39773
  ]
39666
39774
  },
39775
+ {
39776
+ "id": "tool.archive-extract",
39777
+ "kind": "tool",
39778
+ "title": "Archive Extract",
39779
+ "summary": "archive_extract is a directly callable Omnius tool.",
39780
+ "aliases": [
39781
+ "archive_extract"
39782
+ ],
39783
+ "keywords": [
39784
+ "tool",
39785
+ "archive",
39786
+ "extract"
39787
+ ],
39788
+ "maturity": "stable",
39789
+ "layer": "execution",
39790
+ "audiences": [
39791
+ "coding-agent",
39792
+ "integrator",
39793
+ "service-agent"
39794
+ ],
39795
+ "use_when": [
39796
+ "The caller needs this isolated operation and live metadata confirms direct-call availability"
39797
+ ],
39798
+ "avoid_when": [
39799
+ "The live registry reports the tool unavailable or the caller lacks its required scope"
39800
+ ],
39801
+ "interfaces": [
39802
+ {
39803
+ "type": "rest-schema",
39804
+ "target": "/v1/tools/archive_extract"
39805
+ },
39806
+ {
39807
+ "type": "rest-call",
39808
+ "target": "/v1/tools/archive_extract/call"
39809
+ }
39810
+ ],
39811
+ "references": [
39812
+ {
39813
+ "type": "source",
39814
+ "target": "packages/execution/src/tools/archive-extract.ts",
39815
+ "relation": "implementation"
39816
+ }
39817
+ ],
39818
+ "direct_callable": true,
39819
+ "live_metadata": "GET /v1/tools/archive_extract",
39820
+ "source_of_truth": [
39821
+ "packages/execution/src/tools/archive-extract.ts",
39822
+ "GET /v1/tools/archive_extract"
39823
+ ],
39824
+ "verification": [
39825
+ {
39826
+ "check": "Inspect GET /v1/tools/archive_extract before use",
39827
+ "expected": "Schema, security, exposure, and availability match the intended invocation"
39828
+ }
39829
+ ]
39830
+ },
39667
39831
  {
39668
39832
  "id": "tool.asr-listen",
39669
39833
  "kind": "tool",
package/docs/DISCOVERY.md CHANGED
@@ -499,6 +499,7 @@ Daemon equivalents are `GET /v1/discovery/bootstrap`, `GET /v1/discovery?q=<inte
499
499
  | `guide.sana-and-video-generation-integration-plan` | Sana (Image) + `/video` (Video Generation) Integration Plan | &gt; Status: Plan only. Builds a complete, anchored handoff for a downstream implementation agent. &gt; Goal: (A) Promote NVIDIA Sana to the primary image-generation model for /image and the image-generation tool, (B) ship an entirely new /video pipeline modeled exactly on the existing /image and /sound-/music patterns, including its agent tool, Telegram public/pr |
500
500
  | `guide.session-diary-llm-training-analysis` | Session Diary: LLM Training Alignment Analysis | Is the session diary format what LLMs are trained on, such that it helps system handling? |
501
501
  | `guide.telegram-dmn-curiosity-outreach-scaffold` | Telegram DMN Curiosity Outreach Scaffold | This document tracks the root design for idle Telegram channel "daydream" behavior: private meta-analysis while a public group is idle, curiosity-driven exploration, scoped tool awareness, same-group follow-up planning, private DM follow-up planning, and persona document steering. It is intentionally a scaffold: artifacts describe possible actions and tool a |
502
+ | `guide.telegram-large-files` | Receiving large Telegram files | Omnius has no default inbound attachment byte cap or cache byte cap. Downloads stream to disk, retaining only a small signature prefix in memory. Cache item-count and age eviction still apply. Authenticated admin DMs can pass an uploaded document's exact Telegram alias to fileread or archiveextract; extraction returns a destination and file manifest for subs |
502
503
  | `guide.telegram-mid-horizon-download-loop-handoff` | Telegram Mid-Horizon Download Loop Handoff | A Telegram admin-DM action run for "can you please get me the pdf for Snow Crash" burned 60+ turns trying Archive.org, browser clicks, repeated curl downloads, and third-party PDF mirrors. It eventually sent visible self-talk to Telegram: |
503
504
  | `guide.telegram-reflection-corpus-integration-plan` | Telegram Reflection Corpus Integration Plan | Status: planning and implementation tracker |
504
505
  | `guide.telegram-unified-tooling-architecture` | Telegram Unified Tooling Architecture | Goal: give Telegram-sourced agent runs one scoped telegram tool that covers Telegram Bot API operations behind explicit Omnius policy, Telegram bot rights, and admin-controlled toggles. This replaces the current drift where some Telegram powers exist as private helpers, some exist as TUI slash commands, and only telegramsendfile is model-facing. |
@@ -596,6 +597,8 @@ Daemon equivalents are `GET /v1/discovery/bootstrap`, `GET /v1/discovery?q=<inte
596
597
  | `guide.work-orders-runtime-health-remediation-wo-48-conversation-result-evidence-uppercase` | WO-48: Retain command evidence in conversation results | Status: repository repair complete and delivered to origin/main. Publication and live validation remain with the user. |
597
598
  | `guide.work-orders-runtime-health-remediation-wo-49-authored-final-delivery-uppercase` | WO-49: Preserve the authored answer after tool work | Status: repository repair complete; delivered as bfaabd7f to origin/main. Publication and live acceptance remain with the user. |
598
599
  | `guide.work-orders-runtime-health-remediation-wo-50-embedding-unavailability-uppercase` | WO-50: Recover honestly from missing embeddings | Status: repository repair complete; delivered as a3375c63 to origin/main. Requested Nomic re-pull completed and passive server recovery observed. Publication and live acceptance of source changes remain with the user. |
600
+ | `guide.work-orders-runtime-health-remediation-wo-51-large-telegram-attachments-uppercase` | WO-51: Receive and unpack large Telegram attachments | Status: source repair complete and verified. Publication and Local Bot API live acceptance remain with the operator. |
601
+ | `guide.work-orders-runtime-health-remediation-wo-52-steering-projection-preservation-uppercase` | WO-52: Preserve required steering instructions in the actual model request | Status: source repair complete; verified and ready for publication. Live acceptance follows the user's publication. |
599
602
  | `guide.work-orders-telegram-dmn-wo-22-dmn-outreach-and-learning-uppercase` | WO-22: DMN outreach, DM sharing, and outcome learning | On 2026-09-03 at 17:07 PDT the bot posted in the OMNIUS group without being addressed. The operator asked whether this was self-induced reflection. |
600
603
  | `guide.work-orders-telegram-dropbear-context-rca-workorder` | Telegram Dropbear Context Engineering RCA Work Order | Observed run: /home/roko/Documents/Projects/Adjacent/telegramtest/.omnius, run id 1782873796963-i5r7mv. |
601
604
  | `guide.work-orders-wo-am-gaps-uppercase` | Associative Memory Gap Work Orders | Generated: 2026-04-13 Source: Deep audit of multimodal associative memory systems Status: READY FOR IMPLEMENTATION |
@@ -732,6 +735,7 @@ Daemon equivalents are `GET /v1/discovery/bootstrap`, `GET /v1/discovery?q=<inte
732
735
  | `tool.aiwg-health` | Aiwg Health | aiwg_health is a directly callable Omnius tool. |
733
736
  | `tool.aiwg-setup` | Aiwg Setup | aiwg_setup is a directly callable Omnius tool. |
734
737
  | `tool.aiwg-workflow` | Aiwg Workflow | aiwg_workflow is a directly callable Omnius tool. |
738
+ | `tool.archive-extract` | Archive Extract | archive_extract is a directly callable Omnius tool. |
735
739
  | `tool.asr-listen` | Asr Listen | asr_listen is a directly callable Omnius tool. |
736
740
  | `tool.audio-analyze` | Audio Analyze | audio_analyze is a directly callable Omnius tool. |
737
741
  | `tool.audio-capture` | Audio Capture | audio_capture is a directly callable Omnius tool. |
@@ -0,0 +1,37 @@
1
+ # Receiving large Telegram files
2
+
3
+ Omnius has no default inbound attachment byte cap or cache byte cap. Downloads stream to disk, retaining only a small signature prefix in memory. Cache item-count and age eviction still apply. Authenticated admin DMs can pass an uploaded document's exact Telegram alias to `file_read` or `archive_extract`; extraction returns a destination and file manifest for subsequent inspection.
4
+
5
+ Telegram's hosted Bot API limits downloads to 20 MB. A [Local Bot API server](https://core.telegram.org/bots/api#using-a-local-bot-api-server) supports larger downloads. Omnius must use that server for polling and all Bot API methods as well as file retrieval.
6
+
7
+ ## Configure the transport
8
+
9
+ Run the official [Telegram Bot API server](https://github.com/tdlib/telegram-bot-api#usage) in `--local` mode using your own Telegram API application credentials. Use a private endpoint and a shared files directory readable by Omnius. The server's absolute `file_path` must resolve to the same file in Omnius's filesystem; container deployments need matching mount paths. The server directory must not include unrelated private files.
10
+
11
+ Merge these fields into the project's `.omnius/settings.json` or global `~/.omnius/settings.json`, preserving existing settings:
12
+
13
+ ```json
14
+ {
15
+ "telegramBotApiBaseUrl": "http://127.0.0.1:8082",
16
+ "telegramBotApiLocalFilesRoot": "/srv/telegram-bot-api"
17
+ }
18
+ ```
19
+
20
+ These are example values: use the running server's actual endpoint and directory. Port 8081 on the reviewed host belongs to IPFS. Environment variables override the settings:
21
+
22
+ | Setting | Environment variable | Default |
23
+ | --- | --- | --- |
24
+ | `telegramBotApiBaseUrl` | `OMNIUS_TELEGRAM_BOT_API_BASE_URL` | `https://api.telegram.org` |
25
+ | `telegramBotApiLocalFilesRoot` | `OMNIUS_TELEGRAM_BOT_API_LOCAL_FILES_ROOT` | No local filesystem access |
26
+ | `telegramMaxAttachmentBytes` | `OMNIUS_TELEGRAM_MAX_ATTACHMENT_BYTES` | No byte cap |
27
+ | `telegramFileDownloadTimeoutMs` | `OMNIUS_TELEGRAM_FILE_DOWNLOAD_TIMEOUT_MS` | 600000 ms |
28
+
29
+ Leave the attachment limit absent for uncapped downloads. Explicit limits and timeouts must be positive integers. Increase the download timeout for slower transfers; it also applies to `getFile` while the local server obtains the file. Restart Omnius after changing transport settings. Inference endpoint settings are independent.
30
+
31
+ Before switching a running bot, stop its old poller and follow Telegram's [migration procedure](https://github.com/tdlib/telegram-bot-api#moving-a-bot-to-a-local-server), including calling the hosted server's `logOut` method before using the local endpoint. Do not run cloud and local pollers concurrently. This is a live bot migration, not a consequence of installing the source repair.
32
+
33
+ ## Archive consumption and verification
34
+
35
+ `archive_extract` supports ZIP and TAR, including gzip/bzip2/xz-compressed TAR. It requires Python 3 and Linux `renameat2` support. It writes into a fresh destination within the working directory, rejects unsafe paths, links and special files, and never overwrites an existing destination. It does not execute uploaded code. There is no default extracted-byte or entry-count cap; optional `maxOutputBytes`, `maxEntries` and `timeout` arguments are available. Archive extraction is available in authenticated admin DMs under the existing filesystem-tool policy.
36
+
37
+ After publishing and migrating the bot, resend the project archive and ask Omnius to extract it and read its README. Confirm the received byte count, extraction destination/manifest, actual file read, and a delivered result. The repository regression uses a ZIP above 37 MiB through mocked Telegram download, actual cache, alias resolution, extraction and file read. That passing test does not establish live migration or delivery.
@@ -4,6 +4,13 @@
4
4
  **Checked-item rule:** code, focused tests, and named evidence must all exist
5
5
  **Last reconciled:** 2026-09-05
6
6
 
7
+ ## September 5 runtime 1.0.700 large attachment follow-up
8
+
9
+ - [x] [WO-51: large Telegram attachments](WO-51-large-telegram-attachments.md): fixed inbound/cache byte caps removed; streamed download, Local Bot API transport, exact archive aliases and responsive durable Stop verified. Archive implementation `dec18c74` and CLI integration `40a76cea` delivered to `origin/main`.
10
+ - [x] [WO-52: steering projection preservation](WO-52-steering-projection-preservation.md): `766b72f3` delivered to `origin/main`; 118 regression tests passed, typecheck and final orchestrator build passed. Current instructions survive conversation/task projection and visibility receipts match actual admitted request content.
11
+
12
+ The reviewed run rejected a 37.8 MB archive and then looped because the compiler removed its required reconciliation instructions. Ollama was answering requests; no ongoing backend outage was established in the latest journal window. Final verification: clean workspace build and final rebuild passed, execution 1,852 passed / 3 existing skips, CLI full run 2,656 passed plus the final guest-isolation case passed in the focused run (2,657 distinct CLI cases), orchestrator 118 focused regressions passed. Telegram's hosted 20 MB download limit remains external; live larger-file reception requires a configured Local Bot API server and shared directory, documented in [the setup guide](../../telegram-large-files.md). User publication and live acceptance remain pending.
13
+
7
14
  ## September 5 runtime 1.0.698 delivery and Ollama follow-up
8
15
 
9
16
  - [x] [WO-49: authored final delivery](WO-49-authored-final-delivery.md): later authored replies survive earlier prose, tool work and summary-only completion. Commit `bfaabd7f` delivered to `origin/main`; 280 orchestrator and 58 CLI checks passed.
@@ -0,0 +1,56 @@
1
+ # WO-51: Receive and unpack large Telegram attachments
2
+
3
+ Status: source repair complete and verified. Publication and Local Bot API live acceptance remain with the operator.
4
+
5
+ ## Finding and requested behavior
6
+
7
+ On September 5, 2026, runtime 1.0.700 rejected `agent-services.tar.gz` (37,752,526 bytes) against a hardcoded 26,214,400-byte document cap. The user explicitly requested consuming/unpacking files larger than 25 MB and removing the hardcoded cap. Evidence: copied latest run and request projection under `/tmp/omnius-latest-run-20260905-1550/`, intake and conversation capture under `/tmp/omnius-latest-telegram-p7sd8ubn/`.
8
+
9
+ Additional root defects: downloads accumulated the entire file in RAM; the cache could immediately evict a newly received file above its byte budget; archive extensions became `.bin`; received-document aliases had no general reader or archive extractor. Every Bot API and download URL was fixed to Telegram's hosted server.
10
+
11
+ Review also reproduced a FIFO blocking the local-file reader before its regular-file check, and a configured timeout above Node's timer range silently becoming 1 ms. Both are repaired with nonblocking special-file rejection and timer-range validation. The inbound polling loop awaited eager media downloads before accepting subsequent controls; responsive durable dispatch and owned Stop cancellation are included in this order.
12
+
13
+ ## Repair and owned paths
14
+
15
+ - `packages/cli/src/tui/telegram-media-admission.ts` and `platforms/attachment-store.ts`: no default inbound byte cap; explicit operator limits remain optional. Preserve valid file metadata and archive extensions.
16
+ - `telegram-file-download.ts`: stream HTTP or shared local files into exclusive owned cache files; cancellation, partial-write cleanup, prefix-only signature inspection and optional configured limits.
17
+ - `telegram-bot-transport.ts`, `omnius-directory.ts`, `telegram-bridge.ts`: one configured Bot API URL for polling, methods, uploads and downloads; trusted-root handling of local Bot API file paths; independent inference endpoint; no default cache byte eviction; exact chat/message aliases for admin document reads and extraction.
18
+ - `packages/execution/src/tools/archive-extract.ts`: streamed ZIP/TAR extraction into a fresh owned directory, no default byte cap, no content execution, no overwrite, reject traversal/links/devices and report actual manifest facts. Optional explicit resource limits remain available.
19
+ - CLI/execution tests: a real archive larger than 25 MiB through mocked Telegram transport, cache, extraction and file read; local paths; scope/cancellation/cleanup/error controls.
20
+ - `tool-policy.ts` and execution `security-classifier.ts`: classify extraction as a local write and retain the existing admin-DM filesystem boundary, including when public allowlists are expanded.
21
+ - Operator configuration and migration procedure: [Receiving large Telegram files](../../telegram-large-files.md).
22
+
23
+ ## Acceptance
24
+
25
+ - [x] A 37 MiB attachment passes default admission and streamed cache storage without whole-file buffering.
26
+ - [x] Files above former cache byte budgets remain available by exact message alias.
27
+ - [x] Actual archive extraction and subsequent file read succeed; paths cannot escape the owned extraction destination or another chat's media scope.
28
+ - [x] Configured local Bot API URLs and shared paths are respected throughout transport; cloud download refusal is actionable.
29
+ - [x] Cancellation, existing destinations, malformed streams and unsafe archive entries fail honestly and preserve unrelated files.
30
+ - [x] Polling and authorized Stop remain responsive during large-file transfers; cancelled work cannot start afterward.
31
+ - [x] Record tests, builds, scoped commits and push.
32
+
33
+ ## Recorded verification
34
+
35
+ - Execution: 1,852 passed / 3 existing skips across 164 suites, including 31 archive cases and the mutation-authority regression. Command: `pnpm --dir packages/execution exec vitest run --maxWorkers=4 --minWorkers=1`; log `/tmp/omnius-wo51-execution-full.log`. Archive tool and classifier delivered in `dec18c74` on `origin/main`.
36
+ - End-to-end attachment fixture: actual 38 MiB ZIP contents through mocked `getFile`, HTTP streaming, bridge cache, exact message alias, real archive extraction and real text read. Also covers local shared files, cross-chat/missing aliases, retained 900 MiB sparse cache entry, and direct bridge cancellation. Initial focused 49/49 across large attachments, cache and existing admin-alias suites: `/tmp/omnius-wo51-large-attachments.log`.
37
+ - Transport: 25/25 including real FIFO rejection and timer overflow validation: `/tmp/omnius-wo51-telegram-transport-tests.log`; CLI typecheck passed in `/tmp/omnius-wo51-telegram-transport-types.log`.
38
+ - First CLI sweep ran while the two transport follow-up tests were being added. It passed 2,643 cases and failed those two while the module and fixtures were changing; both pass in a fresh run against the final transport source. The final full run passed all 2,656 cases across 278 suites, including the finished transport and dispatch changes: `/tmp/omnius-wo51-cli-final.log`. Command: `pnpm --dir packages/cli exec vitest run --maxWorkers=4 --minWorkers=1`.
39
+ - Clean all-workspace build passed: `/tmp/omnius-wo51-workspace-build.log`. Final all-workspace rebuild passed after the completed source repair: `/tmp/omnius-wo51-final-workspace-build.log`.
40
+
41
+ ## External transport dependency
42
+
43
+ Telegram documents a hosted Bot API download limit of 20 MB; a Local Bot API server supports downloads without that limit and can return an absolute local file path. Removing Omnius's cap alone cannot change the hosted service. Sources: [File/getFile](https://core.telegram.org/bots/api#file), [Local Bot API server](https://core.telegram.org/bots/api#using-a-local-bot-api-server).
44
+
45
+ Read-only host review found no local Bot API executable/service/container, configured API app credentials or endpoint. Port 8081 is already used by IPFS. Repository tests use mocked transport; do not claim live large-file reception until a Local Bot API server and its shared files directory are configured. No bot logout, service switch, Telegram message or inference request was performed. The user reserved publication and subsequent live testing; this source workorder does not change that scope.
46
+
47
+ ## Responsive intake closeout
48
+
49
+ Authoritative polling now schedules a bounded number of attachment dispatch owners outside the poll wait. Deferred ordinary messages stay in the existing SQLite spool, preserving session order across keyset pages. Authenticated, self-targeted controls can bypass a blocked transfer. Stop durably retires its own active attachment and earlier pending session inputs before acknowledgment, including future retries; it never seizes another live dispatch lease. A cancellation fence prevents handler/model startup, and bridge shutdown drains owners before a new generation can start. Downloads and analysis coalesce only within the same session and input, including guest-session isolation. Explicit shadow/disabled durable-intake modes preserve synchronous legacy dispatch because they lack authoritative persistence for safe deferral.
50
+
51
+ - The full CLI run collected 17 large-attachment cases before the last guest-isolation fixture was added. That final fixture also passed in the subsequent 18-case large-attachment suite; all 2,657 distinct non-skipped CLI cases have a passing result on the final implementation.
52
+ - Final focused regression: 108/108 across nine media, alias, polling, durable-intake, control and spool suites; `/tmp/omnius-wo51-poll-tests.log`. Includes actual blocked-body cancellation while another chat progresses; a cancellation receipt inspected inside the Stop reply callback; no post-Stop handler start; unauthorized/wrong-bot/argument-bearing controls; capacity ordering; restart after a late getFile response; guest/ordinary concurrent same-file cancellation isolation.
53
+ - Spool: 11/11 including 2,106-row keyset paging, update-zero query preservation, future retry cancellation, and foreign lease/terminal-state controls; `/tmp/omnius-wo51-telegram-spool-tests.log`. New owned paths include `telegram-update-spool.ts` and its tests.
54
+ - Initial focused run exposed a zero-ID fixture setup error and an existing transport fixture that stopped polling before returning its deliverable batch. Fixtures were corrected to use valid ingress IDs and stop after actual delivery; delivery assertions remain intact.
55
+ - Independent bounded review passed the final ordering, cancellation durability, deferred retry and guest ownership repairs. No live Telegram, inference, bot migration or service change was performed.
56
+ - Archive implementation is in `dec18c74`; final CLI integration commit includes this workorder. Final delivery hashes are recorded in `TRACKER.md`.