Skip to content

feat: add AI response content monitoring service #85

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
11 changes: 10 additions & 1 deletion lib/runtime2/threepio/api/transform/stream.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export type ApiStream = AsyncGenerator<ApiStreamChunk>;
export type ApiStreamChunk = ApiStreamTextChunk | ApiStreamUsageChunk | ApiStreamErrorChunk;

export type ApiStreamChunk = ApiStreamTextChunk | ApiStreamUsageChunk | ApiStreamErrorChunk | ApiStreamJSONChunk;

/**
* The text chunk is the main chunk in the stream and contains the text generated by the model.
Expand All @@ -9,6 +10,14 @@ export interface ApiStreamTextChunk {
text: string;
}

/**
* The jsonl chunk is the chunk in the stream and contains the jsonl generated by the JSONLProcessor.
*/
export interface ApiStreamJSONChunk {
type: 'json';
jsonObject: { [key: string]: any; };
}

/**
* The usage chunk is the last chunk in the stream and contains the total number of tokens used by the request.
* It is only included if the `stream` option is set to `true`.
Expand Down
135 changes: 85 additions & 50 deletions lib/runtime2/threepio/capabilities/generate-domcument/DomOperator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { APP_ROOT_ID } from '.';
import { startActiveSpan } from './trace/withFlowMonitoring';
import { reportThreepioError, reportThreepioInfo, reportThreepioWarning } from '../../utils/threepioLog';
import { EmitData } from './interfaces';
import { EmitData, HtmlFragment } from './interfaces';

function appendHtml(htmlstr: string, element: Element) {
const tempDiv = document.createElement('div');
Expand All @@ -17,13 +18,13 @@ export class DomOperator {
return;
}
const { type, fragment } = data;
const { id, content, parentId } = fragment as any;
const { id, content } = fragment as any;
switch (type) {
case 'html':
this.#appendFragment(document, parentId, content);
this.appendFragment(data, document);
break;
case 'css':
this.#appendCss(document, content);
this.appendCss(data, document);
break;
case 'header':
if (!content) {
Expand All @@ -32,13 +33,18 @@ export class DomOperator {
}
const headerCssfragment = `#${APP_ROOT_ID}{${content}}`;
reportThreepioInfo('Processed Header append CSS:', headerCssfragment);
this.#appendCss(document, headerCssfragment);
data.fragment = { content: headerCssfragment, parentId: APP_ROOT_ID, ...data.fragment } as HtmlFragment;
this.appendCss(data, document);
break;
case 'moudle':
const htmlFragment = fragment as HtmlFragment;
const moudleHtmlfragment = `<div id=\'${id}\'></div>`;
const moudleCssfragment = `#${id}{${content}}`;
this.#appendFragment(document, APP_ROOT_ID, moudleHtmlfragment);
this.#appendCss(document, moudleCssfragment);
htmlFragment.parentId = APP_ROOT_ID;
data.fragment.content = moudleHtmlfragment;
this.appendFragment(data, document);
data.fragment.content = moudleCssfragment;
this.appendCss(data, document);
reportThreepioInfo('Processed moudle append CSS:', moudleCssfragment);
break;
default:
Expand All @@ -51,61 +57,90 @@ export class DomOperator {
* @param content css content to be appended.
* @description This method appends the provided CSS content to the document's head element.
*/
#appendCss(document: Document, content: string): void {
reportThreepioInfo('Processed append CSS:', content);
const styleElement = document.createElement('style');
styleElement.appendChild(document.createTextNode(content));
const head = document.head;
if (head) {
head.appendChild(styleElement);
} else {
const body = document.body || document.getElementsByTagName('body')[0];
if (body) {
body.appendChild(styleElement);
reportThreepioInfo('Appended CSS to body in DOM (no head found).');
protected appendCss(data: EmitData, document: Document): void {
const { fragment } = data;
const { content } = fragment;
startActiveSpan({
traceType: 'DOMOperation',
name: '',
context: {
requestId: data.requestId,
parentRequestId: data.parentRequestId,
}
}, () => {
if (document == null) {
reportThreepioWarning('Document is null, cannot operate on it.');
return;
}
reportThreepioInfo('Processed append CSS:', content);
const styleElement = document.createElement('style');
styleElement.appendChild(document.createTextNode(content));
const head = document.head;
if (head) {
head.appendChild(styleElement);
} else {
reportThreepioWarning('Cannot find head or body to append CSS in DOM.');
const body = document.body || document.getElementsByTagName('body')[0];
if (body) {
body.appendChild(styleElement);
reportThreepioInfo('Appended CSS to body in DOM (no head found).');
} else {
reportThreepioWarning('Cannot find head or body to append CSS in DOM.');
}
}
}
});
}

/**
* @param selectId The ID of the parent element to which the HTML content will be appended.
* @param content The HTML content to be appended.
* @description This method appends the provided HTML content to the document's body element.
*/
#appendFragment(document: Document, parentId: string, content: string): void {
reportThreepioInfo('Process append HTML:', parentId, content);
try {
if (parentId === null) {
appendHtml(content, document.body);
} else {
let parentElement = document.getElementById(parentId);
if (!parentElement) {
const newParentElement = parentElement = document.createElement('div');
newParentElement.id = parentId;
const bodyElement = document.body;
if (bodyElement) {
bodyElement.appendChild(newParentElement);
}
reportThreepioInfo('Created new parent element:', parentId, content);
protected appendFragment(data: EmitData, document: Document): void {
startActiveSpan({
traceType: 'DOMOperation',
name: '',
context: {
requestId: data.requestId,
parentRequestId: data.parentRequestId,
}
}, (span) => {
const { fragment } = data;
const { content, parentId } = fragment as any;
if (document == null) {
reportThreepioWarning('Document is null, cannot operate on it.');
return;
}
try {
if (parentId === null) {
appendHtml(content, document.body);
} else {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = content;
if (tempDiv.getAttribute('class')) {
parentElement.setAttribute('class', tempDiv.getAttribute('class'));
reportThreepioInfo('Set attribute:', tempDiv.getAttribute('class'));
}
if (tempDiv.getAttribute('style')) {
parentElement.setAttribute('style', tempDiv.getAttribute('style'));
reportThreepioInfo('Set attribute:', tempDiv.getAttribute('style'));
let parentElement = document.getElementById(parentId);
if (!parentElement) {
const newParentElement = parentElement = document.createElement('div');
newParentElement.id = parentId;
const bodyElement = document.body;
if (bodyElement) {
bodyElement.appendChild(newParentElement);
}
reportThreepioInfo('Created new parent element:', parentId, content);
} else {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = content;
if (tempDiv.getAttribute('class')) {
parentElement.setAttribute('class', tempDiv.getAttribute('class'));
reportThreepioInfo('Set attribute:', tempDiv.getAttribute('class'));
}
if (tempDiv.getAttribute('style')) {
parentElement.setAttribute('style', tempDiv.getAttribute('style'));
reportThreepioInfo('Set attribute:', tempDiv.getAttribute('style'));
}
}
appendHtml(content, parentElement);
}
appendHtml(content, parentElement);
reportThreepioInfo('Appended HTML to DOM.');
} catch (e) {
reportThreepioError('Error appending HTML to DOM:', e);
}
reportThreepioInfo('Appended HTML to DOM.');
} catch (e) {
reportThreepioError('Error appending HTML to DOM:', e);
}
})
}
}
Loading