@volter/supercode-teams 0.2.158 → 0.2.159

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.
@@ -514,16 +514,36 @@ export class TeamsConnector {
514
514
  }
515
515
  labelTurns(key,entries,messages){
516
516
  const labels={...this.state.turn_labels?.[key]},notes=[...(this.state.turn_notes?.[key]??[])];let found=false;
517
+ const annotations=source=>Object.fromEntries([['source_via',source.via],['source_principal_id',source.from?.principalId],['source_name',source.from?.name]].filter(([,item])=>typeof item==='string'&&item));
518
+ const identities=messages.map(message=>{
519
+ if(message.value?.role!=='user')return null;
520
+ const stamp=message.value.metadata?.timestamp,native=typeof stamp==='string'?Date.parse(stamp):NaN;
521
+ const at=Number.isFinite(native)?native:message.recorded_at;
522
+ if(!Number.isFinite(at))return null;
523
+ return {at,key:`turn:${hash(canonicalJson([Number.isFinite(native)?stamp:at,messageText(message.value)]))}`};
524
+ });
525
+ // Positional native keys can be reused after compaction. Upgrade a legacy
526
+ // label only when its dated, fully annotated row matches the prior capture.
527
+ const legacy=new Set(Object.keys(labels).filter(id=>!id.startsWith('turn:'))),prior=new Map();
528
+ const origin=this.state.origins[key];
529
+ if(legacy.size)for(const [index,id]of(origin?.observed_keys??[]).entries())if(legacy.has(id))prior.set(id,origin.observed_digests?.[index]);
530
+ messages.forEach((message,index)=>{
531
+ const identity=identities[index],source=labels[message.native_key];
532
+ if(!identity||labels[identity.key]||!source||!Number.isFinite(Date.parse(message.value.metadata?.timestamp??'')))return;
533
+ const value={...message.value,metadata:{...message.value.metadata,...annotations(source)}};
534
+ if(prior.get(message.native_key)!==hash(canonicalJson(value)))return;
535
+ labels[identity.key]=source;delete labels[message.native_key];found=true;
536
+ });
517
537
  for(const note of [...notes]){
518
- const match=messages.find(message=>!labels[message.native_key]&&message.value?.role==='user'&&(message.recorded_at==null||message.recorded_at>=note.at-60000)&&messageText(message.value)===note.text);
519
- if(match){labels[match.native_key]=note.source;notes.splice(notes.indexOf(note),1);found=true;}
538
+ const index=messages.findIndex((message,index)=>identities[index]&&!labels[identities[index].key]&&identities[index].at>=note.at-60000&&messageText(message.value)===note.text);
539
+ if(index>=0){labels[identities[index].key]=note.source;notes.splice(notes.indexOf(note),1);found=true;}
520
540
  }
521
541
  if(found){(this.state.turn_labels??={})[key]=labels;if(notes.length)this.state.turn_notes[key]=notes;else delete this.state.turn_notes[key];this.save();}
522
542
  messages.forEach((message,index)=>{
523
- const source=labels[message.native_key];if(!source)return;
524
- const annotations=Object.fromEntries([['source_via',source.via],['source_principal_id',source.from?.principalId],['source_name',source.from?.name]].filter(([,item])=>typeof item==='string'&&item));
525
- message.value={...message.value,metadata:{...message.value.metadata,...annotations}};
526
- const entry=entries[index];if(entry.value)entry.value={...entry.value,metadata:{...entry.value.metadata,...annotations}};else entry.metadata={...entry.metadata,...annotations};
543
+ const identity=identities[index],source=identity&&labels[identity.key];if(!source)return;
544
+ const value=annotations(source);
545
+ message.value={...message.value,metadata:{...message.value.metadata,...value}};
546
+ const entry=entries[index];if(entry.value)entry.value={...entry.value,metadata:{...entry.value.metadata,...value}};else entry.metadata={...entry.metadata,...value};
527
547
  });
528
548
  }
529
549
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volter/supercode-teams",
3
- "version": "0.2.158",
3
+ "version": "0.2.159",
4
4
  "type": "module",
5
5
  "description": "A machine daemon serving this machine's doors, and a local or remote Teams server for shared session discovery, OpenTelemetry ingestion and access to enrolled machines.",
6
6
  "license": "MIT",