Skip to content
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

Enhance mediator workflow before platform launch #301

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion frontend/src/components/experimenter/experimenter_panel.scss
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,17 @@

.action-bar {
@include common.flex-row;
justify-content: end;
@include typescale.label-small;
gap: common.$spacing-small;
justify-content: space-between;
}

.checkbox-wrapper {
@include common.flex-row-align-center;
gap: common.$spacing-small;
overflow-wrap: break-word;

md-checkbox {
flex-shrink: 0;
}
}
22 changes: 22 additions & 0 deletions frontend/src/components/experimenter/experimenter_panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import '../../pair-components/tooltip';
import "./experimenter_data_editor";
import './experimenter_manual_chat';

import '@material/web/checkbox/checkbox.js';

import {MobxLitElement} from '@adobe/lit-mobx';
import {CSSResultGroup, html, nothing} from 'lit';
import {customElement, state} from 'lit/decorators.js';
Expand Down Expand Up @@ -182,6 +184,15 @@ export class Panel extends MobxLitElement {
stageId, {...mediator, prompt}, index
);
};
const updateJSON = () => {
const responseConfig = {
...mediator.responseConfig,
isJSON: !mediator.responseConfig.isJSON,
};
this.mediatorEditor.updateMediator(
stageId, {...mediator, responseConfig}, index
);
};

return html`
<div class="mediator">
Expand All @@ -199,6 +210,17 @@ export class Panel extends MobxLitElement {
>
</pr-textarea>
<div class="action-bar">
<div class="checkbox-wrapper">
<md-checkbox
touch-target="wrapper"
?checked=${mediator.responseConfig.isJSON}
@click=${updateJSON}
>
</md-checkbox>
<div>
Parse as JSON
</div>
</div>
<pr-button
color="secondary"
padding="small"
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/stages/chat_editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
}

.description {
@include typescale.label-small;
color: var(--md-sys-color-outline);
font-style: italic;
}
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/components/stages/chat_editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ export class ChatEditor extends MobxLitElement {
chat history (last 10 messages) and sent to the model
(i.e., chat history + custom prompt => response)
</div>
<div class="description">
<b>If JSON parsing enabled:</b> Make sure to
include appropriate instructions/examples in your prompt to
avoid parsing errors (if the specified message field is non-empty,
its contents will be turned into a chat message).
<b>If disabled:</b> non-empty responses will be turned into messages.
</div>
<pr-textarea
placeholder="Custom prompt for mediator"
variant="outlined"
Expand Down Expand Up @@ -267,8 +274,7 @@ export class ChatEditor extends MobxLitElement {
>
</md-checkbox>
<div>
Parse mediator response as JSON (tip: include appropriate
instructions/examples in prompt so that valid JSON is returned)
Parse mediator response as JSON
</div>
</div>
${!config.isJSON ? nothing : html`
Expand Down
1 change: 1 addition & 0 deletions frontend/src/services/mediator.editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export class MediatorEditor extends Service {
// Experiment ID
@observable experimentId: string|null = null;
// Stage ID to chat config
// TODO: Map from stage ID to MediatorConfig list?
@observable configMap: Record<string, ChatStageConfig> = {};

setExperimentId(id: string) {
Expand Down
19 changes: 16 additions & 3 deletions functions/src/stages/chat.triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,22 @@ export const createMediatorMessage = onDocumentCreated(
const response = await getGeminiAPIResponse(apiKeys.geminiKey, prompt);

// Add mediator message if non-empty
const parsed = JSON.parse(response.text);
const isJSON = mediator.responseConfig.isJSON;
const message = isJSON ? (parsed[mediator.responseConfig.messageField] ?? '') : response.text;
let message = response.text;
let parsed = '';

if (mediator.responseConfig.isJSON) {
// Reset message to empty before trying to fill with JSON response
message = '';

try {
// TODO: Hack to get rid of markdown ticks surrounding {} ?
parsed = JSON.parse(response.text);
} catch {
// Response is already logged in console during Gemini API call
console.log('Could not parse JSON!');
}
message = parsed[mediator.responseConfig.messageField] ?? '';
}

if (message.trim() === '') break;
mediatorMessages.push({ mediator, parsed, message });
Expand Down