mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
AIX: transfer/reassemble per-fragment opaque vendor data
This commit is contained in:
@@ -238,11 +238,14 @@ export class ContentReassembler {
|
||||
case 'ii':
|
||||
await this.onAppendInlineImage(op);
|
||||
break;
|
||||
case 'svs':
|
||||
this.onSetVendorState(op);
|
||||
break;
|
||||
case 'urlc':
|
||||
this.onAddUrlCitation(op);
|
||||
break;
|
||||
case 'vp':
|
||||
this.onVoidPlaceholder(op);
|
||||
this.onAppendVoidPlaceholder(op);
|
||||
break;
|
||||
default:
|
||||
// noinspection JSUnusedLocalSymbols
|
||||
@@ -579,7 +582,7 @@ export class ContentReassembler {
|
||||
// This ensures we don't interrupt the text flow
|
||||
}
|
||||
|
||||
private onVoidPlaceholder(vp: Extract<AixWire_Particles.PartParticleOp, { p: 'vp' }>): void {
|
||||
private onAppendVoidPlaceholder(vp: Extract<AixWire_Particles.PartParticleOp, { p: 'vp' }>): void {
|
||||
const { text, mot } = vp;
|
||||
|
||||
// update the model op
|
||||
@@ -603,6 +606,22 @@ export class ContentReassembler {
|
||||
// Placeholders don't affect text fragment indexing
|
||||
}
|
||||
|
||||
private onSetVendorState(vs: Extract<AixWire_Particles.PartParticleOp, { p: 'svs' }>): void {
|
||||
// apply vendor state to the last created fragment
|
||||
const lastFragment = this.accumulator.fragments[this.accumulator.fragments.length - 1];
|
||||
if (!lastFragment) {
|
||||
console.warn('[ContentReassembler] Vendor state particle without preceding content fragment');
|
||||
return;
|
||||
}
|
||||
|
||||
// attach vendor state
|
||||
const { vendor, state } = vs;
|
||||
lastFragment.vendorState = {
|
||||
...lastFragment.vendorState,
|
||||
[vendor]: state,
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to remove placeholder when real content arrives
|
||||
private removePlaceholderIfAtIndex0(): void {
|
||||
if (this.accumulator.fragments.length > 0) {
|
||||
|
||||
@@ -213,6 +213,7 @@ export namespace AixWire_Parts {
|
||||
|
||||
// Model Auxiliary Part (for thinking blocks)
|
||||
|
||||
// NOTE: not a _BasePart_schema for now, may become if we put the vndAnt attributes there
|
||||
export const ModelAuxPart_schema = z.object({
|
||||
pt: z.literal('ma'),
|
||||
aType: z.literal('reasoning'),
|
||||
@@ -669,6 +670,7 @@ export namespace AixWire_Particles {
|
||||
| { p: 'ia', mimeType: string, a_b64: string, label?: string, generator?: string, durationMs?: number } // inline audio, complete
|
||||
| { p: 'ii', mimeType: string, i_b64: string, label?: string, generator?: string, prompt?: string } // inline image, complete
|
||||
| { p: 'urlc', title: string, url: string, num?: number, from?: number, to?: number, text?: string, pubTs?: number } // url citation - pubTs: publication timestamp
|
||||
| { p: 'svs', vendor: string, state: Record<string, unknown> } // set vendor state - applies to the last emitted part (opaque protocol state)
|
||||
| { p: 'vp', text: string, mot: 'search-web' | 'gen-image' | 'code-exec' }; // void placeholder - temporary status text that gets wiped when real content arrives
|
||||
|
||||
}
|
||||
|
||||
@@ -442,6 +442,19 @@ export class ChatGenerateTransmitter implements IParticleTransmitter {
|
||||
} satisfies Extract<AixWire_Particles.PartParticleOp, { p: 'vp' }>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends vendor-specific state modifier for the last emitted part.
|
||||
* This attaches opaque protocol state (e.g., Gemini thoughtSignature) without polluting core part schemas.
|
||||
*/
|
||||
sendSetVendorState(vendor: string, state: Record<string, unknown>) {
|
||||
// queue vendor state particle immediately after the content part has been queued (and if text, it will be emitted sooner anyway)
|
||||
this.transmissionQueue.push({
|
||||
p: 'svs',
|
||||
vendor,
|
||||
state,
|
||||
} satisfies Extract<AixWire_Particles.PartParticleOp, { p: 'svs' }>);
|
||||
}
|
||||
|
||||
/** Communicates the model name to the client */
|
||||
setModelName(modelName: string) {
|
||||
this.transmissionQueue.push({
|
||||
|
||||
@@ -69,6 +69,12 @@ export interface IParticleTransmitter {
|
||||
/** Sends a void placeholder particle - temporary status that gets wiped when real content arrives */
|
||||
sendVoidPlaceholder(mot: 'search-web' | 'gen-image' | 'code-exec', text: string): void;
|
||||
|
||||
/**
|
||||
* Sends vendor-specific state modifier for the last emitted part.
|
||||
* Used to attach opaque protocol state (e.g., Gemini thoughtSignature) without polluting core part schemas.
|
||||
*/
|
||||
sendSetVendorState(vendor: string, state: unknown): void;
|
||||
|
||||
// Non-parts data //
|
||||
|
||||
/** Communicates the model name to the client */
|
||||
|
||||
Reference in New Issue
Block a user