mixdog 0.9.154 → 0.9.155

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 (38) hide show
  1. package/package.json +2 -2
  2. package/scripts/build-voice-runtime-unix.sh +24 -0
  3. package/scripts/voice-runtime-config.json +1 -1
  4. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
  5. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +5 -2
  6. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +5 -2
  7. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +47 -4
  8. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +12 -0
  9. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +7 -0
  10. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +4 -1
  11. package/src/runtime/channels/data/voice-runtime-manifest.json +17 -17
  12. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +59 -0
  13. package/src/runtime/office/assurance-benchmark.mjs +67 -1
  14. package/src/runtime/office/assurance.mjs +24 -17
  15. package/src/runtime/office/capabilities.mjs +17 -17
  16. package/src/runtime/office/composition-system.mjs +451 -0
  17. package/src/runtime/office/design-library.mjs +102 -0
  18. package/src/runtime/office/design-system.mjs +357 -168
  19. package/src/runtime/office/index.mjs +149 -20
  20. package/src/runtime/office/office-com-host.ps1 +132 -46
  21. package/src/runtime/office/pdf-render.mjs +203 -35
  22. package/src/runtime/office/portable-ooxml.mjs +1090 -47
  23. package/src/runtime/office/portable-package.mjs +390 -0
  24. package/src/runtime/office/portable-sheet-styles.mjs +241 -0
  25. package/src/runtime/office/portable-slide-shapes.mjs +283 -0
  26. package/src/runtime/office/quality-live-benchmark.mjs +82 -36
  27. package/src/runtime/office/quality-pipeline.mjs +3 -0
  28. package/src/runtime/office/tool-defs.mjs +2 -2
  29. package/src/session-runtime/goal-reminder.mjs +79 -0
  30. package/src/session-runtime/goal-runtime.mjs +105 -45
  31. package/src/session-runtime/goal-text.mjs +58 -0
  32. package/src/session-runtime/runtime-core.mjs +14 -1
  33. package/src/session-runtime/session-lifecycle.mjs +1 -1
  34. package/src/session-runtime/session-turn-api.mjs +5 -0
  35. package/src/standalone/session-service.mjs +30 -3
  36. package/src/tui/dist/index.mjs +12 -3
  37. package/src/tui/lib/voice-setup.mjs +19 -3
  38. package/src/tui/session/goal-continuation.mjs +7 -0
@@ -33,6 +33,7 @@ const MAX_TEMPLATE_BYTES = 64 * 1024 * 1024;
33
33
  const MAX_TEMPLATE_COUNT = 200;
34
34
  const MAX_LOCAL_TEMPLATE_COUNT = 5_000;
35
35
  const MAX_SCAN_DEPTH = 8;
36
+ const MAX_COMPOSITION_HISTORY = 48;
36
37
  const FORMATS = new Set(['docx', 'xlsx', 'pptx', 'pdf', 'csv', 'tsv']);
37
38
  const TEMPLATE_FORMATS = Object.freeze({
38
39
  '.docx': 'docx',
@@ -139,6 +140,7 @@ function libraryPaths(dataDir) {
139
140
  packs: join(root, 'packs'),
140
141
  templates: join(root, 'templates'),
141
142
  templateIndex: join(root, 'template-index.json'),
143
+ compositionHistory: join(root, 'composition-history.json'),
142
144
  bindings: join(root, 'bindings'),
143
145
  };
144
146
  }
@@ -296,6 +298,12 @@ function normalizeLayoutCapacity(value) {
296
298
  };
297
299
  }
298
300
 
301
+ function normalizeDesignTags(value, limit = 16) {
302
+ return [...new Set((Array.isArray(value) ? value : [])
303
+ .map((entry) => String(entry || '').trim().toLowerCase())
304
+ .filter(Boolean))].slice(0, limit);
305
+ }
306
+
299
307
  function normalizeLayouts(value, { templatePath = '' } = {}) {
300
308
  if (value == null) return [];
301
309
  if (!Array.isArray(value) || value.length > 1_000) throw new Error('Office design layouts must be an array of at most 1000 entries');
@@ -326,6 +334,8 @@ function normalizeLayouts(value, { templatePath = '' } = {}) {
326
334
  profile: layout.profile ? safeId(layout.profile, 'layout profile') : '',
327
335
  density: String(layout.density || '').toLowerCase(),
328
336
  variant: String(layout.variant || '').trim().toLowerCase(),
337
+ purposes: normalizeDesignTags(layout.purposes),
338
+ expressionModes: normalizeDesignTags(layout.expressionModes),
329
339
  templateId: layout.templateId ? safeId(layout.templateId, 'layout templateId') : '',
330
340
  templatePath: templatePath || String(layout.templatePath || ''),
331
341
  sourceSlide,
@@ -373,6 +383,8 @@ function normalizeLocalSamples(value) {
373
383
  kind: String(sample.kind || '').trim().toLowerCase(),
374
384
  density: String(sample.density || '').trim().toLowerCase(),
375
385
  variant: String(sample.variant || '').trim().toLowerCase(),
386
+ purposes: normalizeDesignTags(sample.purposes),
387
+ expressionModes: normalizeDesignTags(sample.expressionModes),
376
388
  priority: Math.max(-100, Math.min(100, Number(sample.priority) || 0)),
377
389
  strict: sample.strict === true,
378
390
  roles,
@@ -969,16 +981,24 @@ export function officeTemplateCoverage(sampleSlides = []) {
969
981
  const samples = Array.isArray(sampleSlides) ? sampleSlides : [];
970
982
  const kinds = [...new Set(samples.map((sample) => String(sample.kind || '')).filter(Boolean))].sort();
971
983
  const densities = [...new Set(samples.map((sample) => String(sample.density || '')).filter(Boolean))].sort();
984
+ const purposes = [...new Set(samples.flatMap((sample) => sample.purposes || []))].sort();
985
+ const expressionModes = [...new Set(samples.flatMap((sample) => sample.expressionModes || []))].sort();
972
986
  const capabilities = [...new Set(samples.flatMap((sample) => sample.capabilities || []))].sort();
973
987
  const recommendedKinds = ['cover', 'content', 'statement', 'comparison', 'process', 'metrics', 'split', 'closing'];
974
988
  const recommendedDensities = ['light', 'balanced', 'dense'];
989
+ const recommendedPurposes = ['compare', 'decide', 'explain', 'monitor'];
990
+ const recommendedExpressionModes = ['conservative', 'strong-fit', 'divergent'];
975
991
  return {
976
992
  sampleCount: samples.length,
977
993
  kinds,
978
994
  densities,
995
+ purposes,
996
+ expressionModes,
979
997
  capabilities,
980
998
  missingKinds: recommendedKinds.filter((kind) => !kinds.includes(kind)),
981
999
  missingDensities: recommendedDensities.filter((density) => !densities.includes(density)),
1000
+ missingPurposes: recommendedPurposes.filter((purpose) => !purposes.includes(purpose)),
1001
+ missingExpressionModes: recommendedExpressionModes.filter((mode) => !expressionModes.includes(mode)),
982
1002
  nativeObjectCoverage: {
983
1003
  image: capabilities.includes('image'),
984
1004
  chart: capabilities.includes('chart'),
@@ -1140,6 +1160,8 @@ export async function indexOfficeTemplates({
1140
1160
  profile: metadata.profile,
1141
1161
  density: sampleMetadata?.density || sample.density,
1142
1162
  variant: sampleMetadata?.variant || 'native',
1163
+ purposes: sampleMetadata?.purposes || [],
1164
+ expressionModes: sampleMetadata?.expressionModes || [],
1143
1165
  templateId: id,
1144
1166
  templatePath: path,
1145
1167
  sourceSlide: sample.slide,
@@ -1178,6 +1200,8 @@ export async function indexOfficeTemplates({
1178
1200
  title: sample.title || titleShape?.text || '',
1179
1201
  kind: layout?.kind || sample.kind,
1180
1202
  density: layout?.density || sample.density,
1203
+ purposes: layout?.purposes || [],
1204
+ expressionModes: layout?.expressionModes || [],
1181
1205
  slots: layout?.slots || sample.slots,
1182
1206
  capacity: layout?.capacity || sample.capacity,
1183
1207
  };
@@ -1389,6 +1413,78 @@ export async function persistOfficeDesignBinding(dataDir, documentPath, binding)
1389
1413
  return record;
1390
1414
  }
1391
1415
 
1416
+ function normalizedCompositionRecord(value) {
1417
+ if (!plainObject(value)) return null;
1418
+ const fingerprint = String(value.fingerprint || '');
1419
+ const format = String(value.format || '').toLowerCase();
1420
+ if (!fingerprint || !FORMATS.has(format)) return null;
1421
+ return {
1422
+ fingerprint,
1423
+ format,
1424
+ profile: String(value.profile || ''),
1425
+ purpose: String(value.purpose || ''),
1426
+ expressionMode: String(value.expressionMode || ''),
1427
+ compositionIds: [...new Set((Array.isArray(value.compositionIds) ? value.compositionIds : [])
1428
+ .map((entry) => String(entry || '').trim())
1429
+ .filter(Boolean))].slice(0, 64),
1430
+ documentKey: String(value.documentKey || ''),
1431
+ createdAt: String(value.createdAt || ''),
1432
+ };
1433
+ }
1434
+
1435
+ export async function readOfficeCompositionHistory(dataDir, {
1436
+ format = '',
1437
+ limit = 24,
1438
+ excludeDocumentPath = '',
1439
+ } = {}) {
1440
+ const paths = libraryPaths(dataDir);
1441
+ const store = await readJson(paths.compositionHistory, { records: [] });
1442
+ const normalizedFormat = String(format || '').toLowerCase();
1443
+ const excludedKey = excludeDocumentPath ? sha256(canonicalPath(excludeDocumentPath)) : '';
1444
+ return (Array.isArray(store?.records) ? store.records : [])
1445
+ .map(normalizedCompositionRecord)
1446
+ .filter(Boolean)
1447
+ .filter((entry) => !normalizedFormat || entry.format === normalizedFormat)
1448
+ .filter((entry) => !excludedKey || entry.documentKey !== excludedKey)
1449
+ .sort((left, right) => right.createdAt.localeCompare(left.createdAt))
1450
+ .slice(0, Math.max(1, Math.min(MAX_COMPOSITION_HISTORY, Number(limit) || 24)));
1451
+ }
1452
+
1453
+ export async function recordOfficeCompositionHistory(dataDir, {
1454
+ documentPath,
1455
+ format,
1456
+ profile = '',
1457
+ purpose = '',
1458
+ expressionMode = '',
1459
+ fingerprint,
1460
+ compositionIds = [],
1461
+ } = {}) {
1462
+ const paths = libraryPaths(dataDir);
1463
+ const documentKey = sha256(canonicalPath(documentPath));
1464
+ const record = normalizedCompositionRecord({
1465
+ documentKey,
1466
+ format,
1467
+ profile,
1468
+ purpose,
1469
+ expressionMode,
1470
+ fingerprint,
1471
+ compositionIds,
1472
+ createdAt: new Date().toISOString(),
1473
+ });
1474
+ if (!record) throw new Error('Office composition history requires a supported format and fingerprint');
1475
+ const store = await readJson(paths.compositionHistory, { records: [] });
1476
+ const existing = (Array.isArray(store?.records) ? store.records : [])
1477
+ .map(normalizedCompositionRecord)
1478
+ .filter(Boolean)
1479
+ .filter((entry) => entry.documentKey !== documentKey);
1480
+ const records = [record, ...existing].slice(0, MAX_COMPOSITION_HISTORY);
1481
+ await writeJsonAtomic(paths.compositionHistory, {
1482
+ schemaVersion: SCHEMA_VERSION,
1483
+ records,
1484
+ });
1485
+ return record;
1486
+ }
1487
+
1392
1488
  function findTemplate(templates, selector, format) {
1393
1489
  const wanted = String(selector || '').trim();
1394
1490
  if (!wanted) return null;
@@ -1444,6 +1540,10 @@ export async function resolveOfficeDesignLibrary({
1444
1540
  const normalizedFormat = String(format || '').toLowerCase();
1445
1541
  if (!FORMATS.has(normalizedFormat)) throw new Error(`Unsupported Office design library format: ${format}`);
1446
1542
  const paths = libraryPaths(dataDir);
1543
+ const recentCompositions = await readOfficeCompositionHistory(dataDir, {
1544
+ format: normalizedFormat,
1545
+ excludeDocumentPath: documentPath,
1546
+ });
1447
1547
  const config = await loadConfig(dataDir, configOverride);
1448
1548
  const explicitUpgrade = request?.upgradeLibrary === true;
1449
1549
  const currentBinding = !created && !explicitUpgrade
@@ -1475,6 +1575,7 @@ export async function resolveOfficeDesignLibrary({
1475
1575
  template,
1476
1576
  layouts: layoutCandidates(pack, template, normalizedFormat),
1477
1577
  coverage: template?.coverage || null,
1578
+ recentCompositions,
1478
1579
  templateIndexRevision: index.revision || '',
1479
1580
  warning,
1480
1581
  pinned: true,
@@ -1527,6 +1628,7 @@ export async function resolveOfficeDesignLibrary({
1527
1628
  template,
1528
1629
  layouts: layoutCandidates(pack, template, normalizedFormat),
1529
1630
  coverage: template?.coverage || null,
1631
+ recentCompositions,
1530
1632
  templateIndexRevision: synced.templates.revision || '',
1531
1633
  warning: synced.warning || '',
1532
1634
  pinned: false,