Skip to content

Commit

Permalink
Merge branch 'main' into cs-7598-ai-assistant-chat-should-automatical…
Browse files Browse the repository at this point in the history
…ly-display-return-value
  • Loading branch information
lukemelia committed Dec 31, 2024
2 parents 4d942c1 + 48bc199 commit 2d55163
Show file tree
Hide file tree
Showing 23 changed files with 348 additions and 169 deletions.
5 changes: 5 additions & 0 deletions packages/base/command.gts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export class SendAiAssistantMessageResult extends CardDef {
@field eventId = contains(StringField);
}

<<<<<<< HEAD
export class GetBoxelUIStateResult extends CardDef {
@field submode = contains(StringField);
//TODO expand this to include more of the UI state:
Expand All @@ -129,3 +130,7 @@ export class LegacyGenerateAppModuleResult extends CardDef {
@field moduleId = contains(StringField);
@field source = contains(StringField);
}

export class OpenAiAssistantRoomInput extends CardDef {
@field roomId = contains(StringField);
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export default class CreateBoxelApp extends Command<
this.commandContext,
undefined,
);

let { productRequirements: prdCard, roomId } =
await createPRDCommand.execute(input);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import ReloadCardCommand from '@cardstack/boxel-host/commands/reload-card';
import CreateAIAssistantRoomCommand from '@cardstack/boxel-host/commands/create-ai-assistant-room';
import AddSkillsToRoomCommand from '@cardstack/boxel-host/commands/add-skills-to-room';
import SendAiAssistantMessageCommand from '@cardstack/boxel-host/commands/send-ai-assistant-message';
import OpenAiAssistantRoomCommand from '@cardstack/boxel-host/commands/open-ai-assistant-room';

export class CreateProductRequirementsInput extends CardDef {
@field targetAudience = contains(StringField);
Expand Down Expand Up @@ -77,6 +78,14 @@ export default class CreateProductRequirementsInstance extends Command<
let { roomId } = await createRoomCommand.execute({
name: 'Product Requirements Doc Creation',
});

let openAiAssistantRoomCommand = new OpenAiAssistantRoomCommand(
this.commandContext,
);
await openAiAssistantRoomCommand.execute({
roomId,
});

let addSkillsToRoomCommand = new AddSkillsToRoomCommand(
this.commandContext,
);
Expand Down
2 changes: 2 additions & 0 deletions packages/experiments-realm/ai-app-generator.gts
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ class DashboardTab extends GlimmerComponent<{
throw new Error('Missing commandContext');
}
let command = new CreateBoxelApp(commandContext, undefined);

this.isGenerating = true;
try {
await command.execute(
Expand Down Expand Up @@ -471,6 +472,7 @@ class RequirementsTab extends GlimmerComponent<{
if (!this.cardRef) {
throw new Error('Can not create a card without a card ref.');
}

await this.args.context?.actions?.createCard?.(
this.cardRef,
this.args.currentRealm,
Expand Down
5 changes: 5 additions & 0 deletions packages/host/app/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { VirtualNetwork } from '@cardstack/runtime-common';

import * as AddSkillsToRoomCommandModule from './add-skills-to-room';
import * as CreateAIAssistantRoomCommandModule from './create-ai-assistant-room';
import * as OpenAiAssistantRoomCommandModule from './open-ai-assistant-room';
import * as PatchCardCommandModule from './patch-card';
import * as ReloadCardCommandModule from './reload-card';
import * as SaveCardCommandModule from './save-card';
Expand Down Expand Up @@ -32,6 +33,10 @@ export function shimHostCommands(virtualNetwork: VirtualNetwork) {
'@cardstack/boxel-host/commands/save-card',
SaveCardCommandModule,
);
virtualNetwork.shimModule(
'@cardstack/boxel-host/commands/open-ai-assistant-room',
OpenAiAssistantRoomCommandModule,
);
virtualNetwork.shimModule(
'@cardstack/boxel-host/commands/send-ai-assistant-message',
SendAiAssistantMessageModule,
Expand Down
29 changes: 29 additions & 0 deletions packages/host/app/commands/open-ai-assistant-room.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { service } from '@ember/service';

import type * as BaseCommandModule from 'https://cardstack.com/base/command';

import HostBaseCommand from '../lib/host-base-command';

import MatrixService from '../services/matrix-service';
import OperatorModeStateService from '../services/operator-mode-state-service';

export default class OpenAiAssistantRoomCommand extends HostBaseCommand<
BaseCommandModule.OpenAiAssistantRoomInput,
undefined
> {
@service private declare operatorModeStateService: OperatorModeStateService;
@service private declare matrixService: MatrixService;

async getInputType() {
let commandModule = await this.loadCommandModule();
const { OpenAiAssistantRoomInput } = commandModule;
return OpenAiAssistantRoomInput;
}

protected async run(
input: BaseCommandModule.OpenAiAssistantRoomInput,
): Promise<undefined> {
this.operatorModeStateService.aiAssistantOpen = true;
this.matrixService.currentRoomId = input.roomId;
}
}
2 changes: 1 addition & 1 deletion packages/host/app/commands/show-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export default class ShowCardCommand extends HostBaseCommand<
1,
);
let newStackItem = await this.operatorModeStateService.createStackItem(
input.cardToShow,
new URL(input.cardToShow.id),
newStackIndex,
);
this.operatorModeStateService.addItemToStack(newStackItem);
Expand Down
24 changes: 12 additions & 12 deletions packages/host/app/components/ai-assistant/panel.gts
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ export default class AiAssistantPanel extends Component<Signature> {
</div>
{{else if this.isReady}}
{{! below if statement is covered in 'isReady' check above but added due to glint not realizing it }}
{{#if this.currentRoomId}}
{{#if this.matrixService.currentRoomId}}
<Room
@roomId={{this.currentRoomId}}
@roomId={{this.matrixService.currentRoomId}}
@monacoSDK={{this.monacoSDK}}
/>
{{/if}}
Expand Down Expand Up @@ -362,7 +362,6 @@ export default class AiAssistantPanel extends Component<Signature> {
@service private declare router: RouterService;
@service private declare commandService: CommandService;

@tracked private currentRoomId: string | undefined;
@tracked private isShowingPastSessions = false;
@tracked private roomToRename: SessionRoomData | undefined = undefined;
@tracked private roomToDelete: SessionRoomData | undefined = undefined;
Expand Down Expand Up @@ -403,14 +402,14 @@ export default class AiAssistantPanel extends Component<Signature> {
]);
}
if (roomToEnter) {
this.currentRoomId = roomToEnter.roomId;
this.matrixService.currentRoomId = roomToEnter.roomId;
return;
}
}

let latestRoom = this.latestRoom;
if (latestRoom) {
this.currentRoomId = latestRoom.roomId;
this.matrixService.currentRoomId = latestRoom.roomId;
return;
}

Expand All @@ -423,8 +422,8 @@ export default class AiAssistantPanel extends Component<Signature> {
}

private get roomResource() {
return this.currentRoomId
? this.roomResources.get(this.currentRoomId)
return this.matrixService.currentRoomId
? this.roomResources.get(this.matrixService.currentRoomId)
: undefined;
}

Expand Down Expand Up @@ -464,7 +463,7 @@ export default class AiAssistantPanel extends Component<Signature> {
} catch (e) {
console.log(e);
this.displayRoomError = true;
this.currentRoomId = undefined;
this.matrixService.currentRoomId = undefined;
}
});

Expand Down Expand Up @@ -538,11 +537,10 @@ export default class AiAssistantPanel extends Component<Signature> {

@action
private enterRoom(roomId: string, hidePastSessionsList = true) {
this.currentRoomId = roomId;
this.matrixService.currentRoomId = roomId;
if (hidePastSessionsList) {
this.hidePastSessions();
}
window.localStorage.setItem(CurrentRoomIdPersistenceKey, roomId);
}

@action private setRoomToRename(room: SessionRoomData) {
Expand Down Expand Up @@ -591,7 +589,7 @@ export default class AiAssistantPanel extends Component<Signature> {
window.localStorage.removeItem(NewSessionIdPersistenceKey);
}

if (this.currentRoomId === roomId) {
if (this.matrixService.currentRoomId === roomId) {
window.localStorage.removeItem(CurrentRoomIdPersistenceKey);
if (this.latestRoom) {
this.enterRoom(this.latestRoom.roomId, false);
Expand Down Expand Up @@ -624,7 +622,9 @@ export default class AiAssistantPanel extends Component<Signature> {

private get isReady() {
return Boolean(
this.currentRoomId && this.maybeMonacoSDK && this.doCreateRoom.isIdle,
this.matrixService.currentRoomId &&
this.maybeMonacoSDK &&
this.doCreateRoom.isIdle,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ export default class CardPreviewPanel extends Component<Signature> {
}

openInInteractMode = task(async () => {
await this.operatorModeStateService.openCardInInteractMode(this.args.card);
await this.operatorModeStateService.openCardInInteractMode(
new URL(this.args.card.id),
);
});

<template>
Expand Down
14 changes: 7 additions & 7 deletions packages/host/app/components/operator-mode/copy-button.gts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,6 @@ const LEFT = 0;
const RIGHT = 1;

export default class CopyButton extends Component<Signature> {
@service declare loaderService: LoaderService;
@service declare cardService: CardService;
@service declare operatorModeStateService: OperatorModeStateService;

<template>
{{#if (gt this.stacks.length 1)}}
{{#if this.state}}
Expand Down Expand Up @@ -102,15 +98,19 @@ export default class CopyButton extends Component<Signature> {
</style>
</template>

get stacks() {
@service private declare loaderService: LoaderService;
@service private declare cardService: CardService;
@service private declare operatorModeStateService: OperatorModeStateService;

private get stacks() {
return this.operatorModeStateService.state?.stacks ?? [];
}

get buttonKind() {
private get buttonKind() {
return this.args.isCopying ? 'primary-dark' : 'primary';
}

get state() {
private get state() {
// Need to have 2 stacks in order for a copy button to exist
if (this.stacks.length < 2) {
return undefined;
Expand Down
53 changes: 27 additions & 26 deletions packages/host/app/components/operator-mode/interact-submode.gts
Original file line number Diff line number Diff line change
Expand Up @@ -198,30 +198,28 @@ export default class InteractSubmode extends Component<Signature> {
doc.data.meta.realmURL = opts.realmURL.href;
}

let newCard = await here.cardService.createFromSerialized(
doc.data,
doc,
relativeTo,
);

let newItem = new StackItem({
owner: here,
card: newCard,
newCard: { doc, relativeTo },
format: opts?.cardModeAfterCreation ?? 'edit',
request: new Deferred(),
isLinkedCard: opts?.isLinkedCard,
stackIndex,
});

// TODO: it is important saveModel happens after newItem because it
// looks like perhaps there is a race condition (or something else) when a
// new linked card is created, and when it is added to the stack and closed
// - the parent card is not updated with the new linked card
await here.cardService.saveModel(newCard);

await newItem.ready();
if (newItem.cardError) {
console.error(
`Encountered error creating card:\n${JSON.stringify(
doc,
null,
2,
)}\nError: ${JSON.stringify(newItem.cardError, null, 2)}`,
);
return undefined;
}
here.addToStack(newItem);
return newCard;
return newItem.card;
},
viewCard: async (
cardOrURL: CardDef | URL,
Expand All @@ -233,9 +231,7 @@ export default class InteractSubmode extends Component<Signature> {
}
let newItem = new StackItem({
owner: here,
...(cardOrURL instanceof URL
? { url: cardOrURL }
: { card: cardOrURL }),
url: cardOrURL instanceof URL ? cardOrURL : new URL(cardOrURL.id),
format,
stackIndex,
});
Expand Down Expand Up @@ -561,19 +557,25 @@ export default class InteractSubmode extends Component<Signature> {
private openSelectedSearchResultInStack = restartableTask(
async (cardId: string) => {
let waiterToken = waiter.beginAsync();
let url = new URL(cardId);
try {
let searchSheetTrigger = this.searchSheetTrigger; // Will be set by showSearchWithTrigger
let card = await this.cardService.getCard(cardId);
if (!card) {
return;
}

// In case the left button was clicked, whatever is currently in stack with index 0 will be moved to stack with index 1,
// and the card will be added to stack with index 0. shiftStack executes this logic.
if (
searchSheetTrigger ===
SearchSheetTriggers.DropCardToLeftNeighborStackButton
) {
let newItem = new StackItem({
owner: this,
url,
format: 'isolated',
stackIndex: 0,
});
// it's important that we await the stack item readiness _before_
// we mutate the stack, otherwise there are very odd visual artifacts
await newItem.ready();
for (
let stackIndex = this.stacks.length - 1;
stackIndex >= 0;
Expand All @@ -584,15 +586,14 @@ export default class InteractSubmode extends Component<Signature> {
stackIndex + 1,
);
}
await this.publicAPI(this, 0).viewCard(card, 'isolated');

this.addToStack(newItem);
// In case the right button was clicked, the card will be added to stack with index 1.
} else if (
searchSheetTrigger ===
SearchSheetTriggers.DropCardToRightNeighborStackButton
) {
await this.publicAPI(this, this.stacks.length).viewCard(
card,
url,
'isolated',
);
} else {
Expand All @@ -606,15 +607,15 @@ export default class InteractSubmode extends Component<Signature> {
numberOfStacks === 0 ||
this.operatorModeStateService.stackIsEmpty(stackIndex)
) {
await this.publicAPI(this, 0).viewCard(card, 'isolated');
await this.publicAPI(this, 0).viewCard(url, 'isolated');
} else {
stack = this.operatorModeStateService.rightMostStack();
if (stack) {
let bottomMostItem = stack[0];
if (bottomMostItem) {
let stackItem = new StackItem({
owner: this,
card,
url,
format: 'isolated',
stackIndex,
});
Expand Down
Loading

0 comments on commit 2d55163

Please sign in to comment.