mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-05 00:54:56 +00:00
Compare commits
17 Commits
0.23.0-bet
...
use-jemall
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1d7011047 | ||
|
|
1fe07410c0 | ||
|
|
0f3066f7d0 | ||
|
|
c4c11da976 | ||
|
|
38537bf310 | ||
|
|
1f87cd8752 | ||
|
|
f54cb5c296 | ||
|
|
45c016af8b | ||
|
|
d4c905600b | ||
|
|
f839e5c136 | ||
|
|
39abd1bbb8 | ||
|
|
ecea7bd825 | ||
|
|
d10e5ee92f | ||
|
|
dace1d1738 | ||
|
|
ae74f4ae51 | ||
|
|
9071c5032d | ||
|
|
8236ecf486 |
5
.github/deployment/node/Dockerfile
vendored
5
.github/deployment/node/Dockerfile
vendored
@@ -7,7 +7,10 @@ COPY ./packages/frontend/apps/mobile/dist /app/static/mobile
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends openssl && \
|
||||
apt-get install -y --no-install-recommends openssl libjemalloc2 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Enable jemalloc by preloading the library
|
||||
ENV LD_PRELOAD=libjemalloc.so.2
|
||||
|
||||
CMD ["node", "./dist/main.js"]
|
||||
|
||||
@@ -43,10 +43,14 @@ export class InlineCommentManager extends LifeCycleWatcher {
|
||||
|
||||
this._disposables.add(provider.onCommentAdded(this._handleAddComment));
|
||||
this._disposables.add(
|
||||
provider.onCommentDeleted(this._handleDeleteAndResolve)
|
||||
provider.onCommentDeleted(id =>
|
||||
this._handleDeleteAndResolve(id, 'delete')
|
||||
)
|
||||
);
|
||||
this._disposables.add(
|
||||
provider.onCommentResolved(this._handleDeleteAndResolve)
|
||||
provider.onCommentResolved(id =>
|
||||
this._handleDeleteAndResolve(id, 'resolve')
|
||||
)
|
||||
);
|
||||
this._disposables.add(
|
||||
provider.onCommentHighlighted(this._handleHighlightComment)
|
||||
@@ -64,15 +68,16 @@ export class InlineCommentManager extends LifeCycleWatcher {
|
||||
const provider = this._provider;
|
||||
if (!provider) return;
|
||||
|
||||
const commentsInProvider = await provider.getComments('unresolved');
|
||||
const commentsInProvider = await provider.getComments('all');
|
||||
|
||||
const commentsInEditor = this.getCommentsInEditor();
|
||||
|
||||
// remove comments that are in editor but not in provider
|
||||
// which means the comment may be removed or resolved in provider side
|
||||
difference(commentsInEditor, commentsInProvider).forEach(comment => {
|
||||
this._handleDeleteAndResolve(comment);
|
||||
this.std.get(BlockElementCommentManager).handleDeleteAndResolve(comment);
|
||||
this.std
|
||||
.get(BlockElementCommentManager)
|
||||
.handleDeleteAndResolve(comment, 'delete');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -162,7 +167,10 @@ export class InlineCommentManager extends LifeCycleWatcher {
|
||||
});
|
||||
};
|
||||
|
||||
private readonly _handleDeleteAndResolve = (id: CommentId) => {
|
||||
private readonly _handleDeleteAndResolve = (
|
||||
id: CommentId,
|
||||
type: 'delete' | 'resolve'
|
||||
) => {
|
||||
const commentedTexts = findCommentedTexts(this.std.store, id);
|
||||
if (commentedTexts.length === 0) return;
|
||||
|
||||
@@ -176,7 +184,7 @@ export class InlineCommentManager extends LifeCycleWatcher {
|
||||
inlineEditor?.formatText(
|
||||
selection.from,
|
||||
{
|
||||
[`comment-${id}`]: null,
|
||||
[`comment-${id}`]: type === 'delete' ? null : false,
|
||||
},
|
||||
{
|
||||
withoutTransact: true,
|
||||
|
||||
@@ -22,7 +22,7 @@ import { isEqual } from 'lodash-es';
|
||||
})
|
||||
export class InlineComment extends WithDisposable(ShadowlessElement) {
|
||||
static override styles = css`
|
||||
inline-comment {
|
||||
inline-comment.unresolved {
|
||||
display: inline-block;
|
||||
background-color: ${unsafeCSSVarV2('block/comment/highlightDefault')};
|
||||
border-bottom: 2px solid
|
||||
@@ -41,6 +41,9 @@ export class InlineComment extends WithDisposable(ShadowlessElement) {
|
||||
})
|
||||
accessor commentIds!: string[];
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor unresolved = false;
|
||||
|
||||
private _index: number = 0;
|
||||
|
||||
@consume({ context: stdContext })
|
||||
@@ -54,8 +57,10 @@ export class InlineComment extends WithDisposable(ShadowlessElement) {
|
||||
}
|
||||
|
||||
private readonly _handleClick = () => {
|
||||
this._provider?.highlightComment(this.commentIds[this._index]);
|
||||
this._index = (this._index + 1) % this.commentIds.length;
|
||||
if (this.unresolved) {
|
||||
this._provider?.highlightComment(this.commentIds[this._index]);
|
||||
this._index = (this._index + 1) % this.commentIds.length;
|
||||
}
|
||||
};
|
||||
|
||||
private readonly _handleHighlight = (id: CommentId | null) => {
|
||||
@@ -89,6 +94,13 @@ export class InlineComment extends WithDisposable(ShadowlessElement) {
|
||||
this.classList.remove('highlighted');
|
||||
}
|
||||
}
|
||||
if (_changedProperties.has('unresolved')) {
|
||||
if (this.unresolved) {
|
||||
this.classList.add('unresolved');
|
||||
} else {
|
||||
this.classList.remove('unresolved');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override render() {
|
||||
|
||||
@@ -21,19 +21,25 @@ export const CommentInlineSpecExtension =
|
||||
),
|
||||
match: delta => {
|
||||
if (!delta.attributes) return false;
|
||||
const comments = Object.entries(delta.attributes).filter(
|
||||
([key, value]) => isInlineCommendId(key) && value === true
|
||||
);
|
||||
const comments = Object.keys(delta.attributes).filter(isInlineCommendId);
|
||||
return comments.length > 0;
|
||||
},
|
||||
renderer: ({ delta, children }) =>
|
||||
html`<inline-comment .commentIds=${extractCommentIdFromDelta(delta)}
|
||||
renderer: ({ delta, children }) => {
|
||||
if (!delta.attributes) return html`${nothing}`;
|
||||
|
||||
const unresolved = Object.entries(delta.attributes).some(
|
||||
([key, value]) => isInlineCommendId(key) && value === true
|
||||
);
|
||||
return html`<inline-comment
|
||||
.unresolved=${unresolved}
|
||||
.commentIds=${extractCommentIdFromDelta(delta)}
|
||||
>${when(
|
||||
children,
|
||||
() => html`${children}`,
|
||||
() => nothing
|
||||
)}</inline-comment
|
||||
>`,
|
||||
>`;
|
||||
},
|
||||
wrapper: true,
|
||||
});
|
||||
|
||||
@@ -47,3 +53,7 @@ export const NullCommentInlineSpecExtension =
|
||||
match: () => false,
|
||||
renderer: () => html``,
|
||||
});
|
||||
|
||||
// reuse the same identifier
|
||||
NullCommentInlineSpecExtension.identifier =
|
||||
CommentInlineSpecExtension.identifier;
|
||||
|
||||
@@ -57,10 +57,12 @@ export class BlockElementCommentManager extends LifeCycleWatcher {
|
||||
|
||||
this._disposables.add(provider.onCommentAdded(this._handleAddComment));
|
||||
this._disposables.add(
|
||||
provider.onCommentDeleted(this.handleDeleteAndResolve)
|
||||
provider.onCommentDeleted(id => this.handleDeleteAndResolve(id, 'delete'))
|
||||
);
|
||||
this._disposables.add(
|
||||
provider.onCommentResolved(this.handleDeleteAndResolve)
|
||||
provider.onCommentResolved(id =>
|
||||
this.handleDeleteAndResolve(id, 'resolve')
|
||||
)
|
||||
);
|
||||
this._disposables.add(
|
||||
provider.onCommentHighlighted(this._handleHighlightComment)
|
||||
@@ -123,8 +125,7 @@ export class BlockElementCommentManager extends LifeCycleWatcher {
|
||||
const gfx = this.std.get(GfxControllerIdentifier);
|
||||
const elementsFromSurfaceSelection = selections
|
||||
.filter(s => s instanceof SurfaceSelection)
|
||||
.flatMap(({ blockId, elements }) => {
|
||||
if (blockId !== gfx.surface?.id) return [];
|
||||
.flatMap(({ elements }) => {
|
||||
return elements
|
||||
.map(id => gfx.getElementById<GfxModel>(id))
|
||||
.filter(m => m !== null);
|
||||
@@ -147,18 +148,29 @@ export class BlockElementCommentManager extends LifeCycleWatcher {
|
||||
}
|
||||
};
|
||||
|
||||
readonly handleDeleteAndResolve = (id: CommentId) => {
|
||||
readonly handleDeleteAndResolve = (
|
||||
id: CommentId,
|
||||
type: 'delete' | 'resolve'
|
||||
) => {
|
||||
const commentedBlocks = findCommentedBlocks(this.std.store, id);
|
||||
this.std.store.withoutTransact(() => {
|
||||
commentedBlocks.forEach(block => {
|
||||
delete block.props.comments[id];
|
||||
if (type === 'delete') {
|
||||
delete block.props.comments[id];
|
||||
} else {
|
||||
block.props.comments[id] = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const commentedElements = findCommentedElements(this.std.store, id);
|
||||
this.std.store.withoutTransact(() => {
|
||||
commentedElements.forEach(element => {
|
||||
delete element.comments[id];
|
||||
if (type === 'delete') {
|
||||
delete element.comments[id];
|
||||
} else {
|
||||
element.comments[id] = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -40,7 +40,6 @@ export interface NotificationService {
|
||||
}[];
|
||||
onClose?: () => void;
|
||||
}): void;
|
||||
|
||||
/**
|
||||
* Notify with undo action, it is a helper function to notify with undo action.
|
||||
* And the notification card will be closed when undo action is triggered by shortcut key or other ways.
|
||||
@@ -55,13 +54,16 @@ export const NotificationProvider = createIdentifier<NotificationService>(
|
||||
);
|
||||
|
||||
export function NotificationExtension(
|
||||
notificationService: Omit<NotificationService, 'notifyWithUndoAction'>
|
||||
notificationService: NotificationService
|
||||
): ExtensionType {
|
||||
return {
|
||||
setup: di => {
|
||||
di.addImpl(NotificationProvider, provider => {
|
||||
return {
|
||||
...notificationService,
|
||||
notify: notificationService.notify,
|
||||
toast: notificationService.toast,
|
||||
confirm: notificationService.confirm,
|
||||
prompt: notificationService.prompt,
|
||||
notifyWithUndoAction: options => {
|
||||
notifyWithUndoActionImpl(
|
||||
provider,
|
||||
|
||||
@@ -31,7 +31,7 @@ export interface BlockStdOptions {
|
||||
extensions: ExtensionType[];
|
||||
}
|
||||
|
||||
const internalExtensions = [
|
||||
export const internalExtensions = [
|
||||
ServiceManager,
|
||||
CommandManager,
|
||||
UIEventDispatcher,
|
||||
|
||||
@@ -369,7 +369,7 @@ The term **“CRDT”** was first introduced by Marc Shapiro, Nuno Preguiça, Ca
|
||||
.map(c => JSON.parse(c.citationJson).type)
|
||||
.filter(type => ['attachment', 'doc'].includes(type)).length ===
|
||||
0,
|
||||
'should not have citation'
|
||||
`should not have citation: ${JSON.stringify(c, null, 2)}`
|
||||
);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -73,7 +73,8 @@ e2e('should get comment attachment body', async t => {
|
||||
docId,
|
||||
key,
|
||||
'test.txt',
|
||||
Buffer.from('test')
|
||||
Buffer.from('test'),
|
||||
owner.id
|
||||
);
|
||||
|
||||
const res = await app.GET(
|
||||
|
||||
@@ -361,7 +361,8 @@ export class CommentResolver {
|
||||
docId,
|
||||
key,
|
||||
attachment.filename ?? key,
|
||||
buffer
|
||||
buffer,
|
||||
me.id
|
||||
);
|
||||
return this.commentAttachmentStorage.getUrl(workspaceId, docId, key);
|
||||
}
|
||||
|
||||
@@ -24,11 +24,12 @@ test.after.always(async () => {
|
||||
|
||||
test('should put comment attachment', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const user = await module.create(Mockers.User);
|
||||
const docId = randomUUID();
|
||||
const key = randomUUID();
|
||||
const blob = Buffer.from('test');
|
||||
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob);
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
|
||||
|
||||
const item = await models.commentAttachment.get(workspace.id, docId, key);
|
||||
|
||||
@@ -39,15 +40,17 @@ test('should put comment attachment', async t => {
|
||||
t.is(item?.mime, 'text/plain');
|
||||
t.is(item?.size, blob.length);
|
||||
t.is(item?.name, 'test.txt');
|
||||
t.is(item?.createdBy, user.id);
|
||||
});
|
||||
|
||||
test('should get comment attachment', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const user = await module.create(Mockers.User);
|
||||
const docId = randomUUID();
|
||||
const key = randomUUID();
|
||||
const blob = Buffer.from('test');
|
||||
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob);
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
|
||||
|
||||
const item = await storage.get(workspace.id, docId, key);
|
||||
|
||||
@@ -62,11 +65,12 @@ test('should get comment attachment', async t => {
|
||||
|
||||
test('should get comment attachment with access url', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const user = await module.create(Mockers.User);
|
||||
const docId = randomUUID();
|
||||
const key = randomUUID();
|
||||
const blob = Buffer.from('test');
|
||||
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob);
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
|
||||
|
||||
const url = storage.getUrl(workspace.id, docId, key);
|
||||
|
||||
@@ -79,11 +83,12 @@ test('should get comment attachment with access url', async t => {
|
||||
|
||||
test('should delete comment attachment', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const user = await module.create(Mockers.User);
|
||||
const docId = randomUUID();
|
||||
const key = randomUUID();
|
||||
const blob = Buffer.from('test');
|
||||
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob);
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
|
||||
|
||||
await storage.delete(workspace.id, docId, key);
|
||||
|
||||
@@ -94,11 +99,12 @@ test('should delete comment attachment', async t => {
|
||||
|
||||
test('should handle comment.attachment.delete event', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const user = await module.create(Mockers.User);
|
||||
const docId = randomUUID();
|
||||
const key = randomUUID();
|
||||
const blob = Buffer.from('test');
|
||||
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob);
|
||||
await storage.put(workspace.id, docId, key, 'test.txt', blob, user.id);
|
||||
|
||||
await storage.onCommentAttachmentDelete({
|
||||
workspaceId: workspace.id,
|
||||
@@ -113,14 +119,15 @@ test('should handle comment.attachment.delete event', async t => {
|
||||
|
||||
test('should handle workspace.deleted event', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const user = await module.create(Mockers.User);
|
||||
const docId = randomUUID();
|
||||
const key1 = randomUUID();
|
||||
const key2 = randomUUID();
|
||||
const blob1 = Buffer.from('test');
|
||||
const blob2 = Buffer.from('test2');
|
||||
|
||||
await storage.put(workspace.id, docId, key1, 'test.txt', blob1);
|
||||
await storage.put(workspace.id, docId, key2, 'test.txt', blob2);
|
||||
await storage.put(workspace.id, docId, key1, 'test.txt', blob1, user.id);
|
||||
await storage.put(workspace.id, docId, key2, 'test.txt', blob2, user.id);
|
||||
|
||||
const count = module.event.count('comment.attachment.delete');
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ export class CommentAttachmentStorage {
|
||||
docId: string,
|
||||
key: string,
|
||||
name: string,
|
||||
blob: Buffer
|
||||
blob: Buffer,
|
||||
userId: string
|
||||
) {
|
||||
const meta = autoMetadata(blob);
|
||||
|
||||
@@ -75,6 +76,7 @@ export class CommentAttachmentStorage {
|
||||
name,
|
||||
mime: meta.contentType ?? 'application/octet-stream',
|
||||
size: blob.length,
|
||||
createdBy: userId,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ export class WorkspacesController {
|
||||
await this.ac.user(user.id).doc(workspaceId, docId).assert('Doc.Read');
|
||||
|
||||
const { body, metadata, redirectUrl } =
|
||||
await this.commentAttachmentStorage.get(workspaceId, docId, key);
|
||||
await this.commentAttachmentStorage.get(workspaceId, docId, key, true);
|
||||
|
||||
if (redirectUrl) {
|
||||
return res.redirect(redirectUrl);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { chunk } from 'lodash-es';
|
||||
|
||||
type SessionTime = {
|
||||
sessionId: string;
|
||||
@@ -17,16 +18,19 @@ export class CorrectSessionUpdateTime1751966744168 {
|
||||
},
|
||||
});
|
||||
|
||||
await Promise.all(
|
||||
sessionTime
|
||||
.filter((s): s is SessionTime => !!s._max.createdAt)
|
||||
.map(s =>
|
||||
db.aiSession.update({
|
||||
where: { id: s.sessionId },
|
||||
data: { updatedAt: s._max.createdAt },
|
||||
})
|
||||
)
|
||||
);
|
||||
for (const s of chunk(sessionTime, 100)) {
|
||||
const sessions = s.filter((s): s is SessionTime => !!s._max.createdAt);
|
||||
await db.$transaction(async tx => {
|
||||
await Promise.all(
|
||||
sessions.map(s =>
|
||||
tx.aiSession.update({
|
||||
where: { id: s.sessionId },
|
||||
data: { updatedAt: s._max.createdAt },
|
||||
})
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// revert the migration
|
||||
|
||||
@@ -13,6 +13,7 @@ test.after.always(async () => {
|
||||
|
||||
test('should upsert comment attachment', async t => {
|
||||
const workspace = await module.create(Mockers.Workspace);
|
||||
const user = await module.create(Mockers.User);
|
||||
|
||||
// add
|
||||
const item = await models.commentAttachment.upsert({
|
||||
@@ -22,6 +23,7 @@ test('should upsert comment attachment', async t => {
|
||||
name: 'test-name',
|
||||
mime: 'text/plain',
|
||||
size: 100,
|
||||
createdBy: user.id,
|
||||
});
|
||||
|
||||
t.is(item.workspaceId, workspace.id);
|
||||
@@ -30,6 +32,7 @@ test('should upsert comment attachment', async t => {
|
||||
t.is(item.mime, 'text/plain');
|
||||
t.is(item.size, 100);
|
||||
t.truthy(item.createdAt);
|
||||
t.is(item.createdBy, user.id);
|
||||
|
||||
// update
|
||||
const item2 = await models.commentAttachment.upsert({
|
||||
@@ -46,6 +49,7 @@ test('should upsert comment attachment', async t => {
|
||||
t.is(item2.key, 'test-key');
|
||||
t.is(item2.mime, 'text/html');
|
||||
t.is(item2.size, 200);
|
||||
t.is(item2.createdBy, user.id);
|
||||
|
||||
// make sure only one blob is created
|
||||
const items = await models.commentAttachment.list(workspace.id);
|
||||
|
||||
@@ -32,6 +32,7 @@ export class CommentAttachmentModel extends BaseModel {
|
||||
name: input.name,
|
||||
mime: input.mime,
|
||||
size: input.size,
|
||||
createdBy: input.createdBy,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -112,11 +112,14 @@ class ProductionEmbeddingClient extends EmbeddingClient {
|
||||
);
|
||||
|
||||
try {
|
||||
return ranks.map((score, chunk) => ({
|
||||
chunk,
|
||||
targetId: this.getTargetId(embeddings[chunk]),
|
||||
score,
|
||||
}));
|
||||
return ranks.map((score, i) => {
|
||||
const chunk = embeddings[i];
|
||||
return {
|
||||
chunk: chunk.chunk,
|
||||
targetId: this.getTargetId(chunk),
|
||||
score: Math.max(score, 1 - (chunk.distance || -Infinity)),
|
||||
};
|
||||
});
|
||||
} catch (error) {
|
||||
this.logger.error('Failed to parse rerank results', error);
|
||||
// silent error, will fallback to default sorting in parent method
|
||||
@@ -148,7 +151,7 @@ class ProductionEmbeddingClient extends EmbeddingClient {
|
||||
|
||||
const chunks = sortedEmbeddings.reduce(
|
||||
(acc, e) => {
|
||||
const targetId = 'docId' in e ? e.docId : 'fileId' in e ? e.fileId : '';
|
||||
const targetId = this.getTargetId(e);
|
||||
const key = `${targetId}:${e.chunk}`;
|
||||
acc[key] = e;
|
||||
return acc;
|
||||
@@ -179,7 +182,10 @@ class ProductionEmbeddingClient extends EmbeddingClient {
|
||||
.filter(Boolean);
|
||||
|
||||
this.logger.verbose(
|
||||
`ReRank completed: ${highConfidenceChunks.length} high-confidence results found`
|
||||
`ReRank completed: ${highConfidenceChunks.length} high-confidence results found, total ${sortedEmbeddings.length} embeddings`,
|
||||
highConfidenceChunks.length !== sortedEmbeddings.length
|
||||
? JSON.stringify(ranks)
|
||||
: undefined
|
||||
);
|
||||
return highConfidenceChunks.slice(0, topK);
|
||||
} catch (error) {
|
||||
|
||||
@@ -338,7 +338,7 @@ Convert a multi-speaker audio recording into a structured JSON format by transcr
|
||||
{
|
||||
name: 'Rerank results',
|
||||
action: 'Rerank results',
|
||||
model: 'gpt-4.1-mini',
|
||||
model: 'gpt-4.1',
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
@@ -1286,7 +1286,7 @@ If there are items in the content that can be used as to-do tasks, please refer
|
||||
{
|
||||
name: 'Make it real',
|
||||
action: 'Make it real',
|
||||
model: 'gpt-4.1-2025-04-14',
|
||||
model: 'claude-sonnet-4@20250514',
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
@@ -1327,7 +1327,7 @@ When sent new wireframes, respond ONLY with the contents of the html file.`,
|
||||
{
|
||||
name: 'Make it real with text',
|
||||
action: 'Make it real with text',
|
||||
model: 'gpt-4.1-2025-04-14',
|
||||
model: 'claude-sonnet-4@20250514',
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
@@ -1677,7 +1677,7 @@ This sentence contains information from the first source[^1]. This sentence refe
|
||||
Before starting Tool calling, you need to follow:
|
||||
- DO NOT explain what operation you will perform.
|
||||
- DO NOT embed a tool call mid-sentence.
|
||||
- When searching for unknown information or keyword, prioritize searching the user's workspace.
|
||||
- When searching for unknown information, personal information or keyword, prioritize searching the user's workspace rather than the web.
|
||||
- Depending on the complexity of the question and the information returned by the search tools, you can call different tools multiple times to search.
|
||||
</tool-calling-guidelines>
|
||||
|
||||
|
||||
@@ -53,8 +53,11 @@ export class PromptService implements OnApplicationBootstrap {
|
||||
* @returns prompt messages
|
||||
*/
|
||||
async get(name: string): Promise<ChatPrompt | null> {
|
||||
const cached = this.cache.get(name);
|
||||
if (cached) return cached;
|
||||
// skip cache in dev mode to ensure the latest prompt is always fetched
|
||||
if (!env.dev) {
|
||||
const cached = this.cache.get(name);
|
||||
if (cached) return cached;
|
||||
}
|
||||
|
||||
const prompt = await this.db.aiPrompt.findUnique({
|
||||
where: {
|
||||
|
||||
@@ -62,6 +62,7 @@ export abstract class AnthropicProvider<T> extends CopilotProvider<T> {
|
||||
|
||||
try {
|
||||
metrics.ai.counter('chat_text_calls').add(1, { model: model.id });
|
||||
|
||||
const [system, msgs] = await chatToGPTMessage(messages, true, true);
|
||||
|
||||
const modelInstance = this.instance(model.id);
|
||||
|
||||
@@ -88,6 +88,12 @@ export abstract class GeminiProvider<T> extends CopilotProvider<T> {
|
||||
system,
|
||||
messages: msgs,
|
||||
abortSignal: options.signal,
|
||||
providerOptions: {
|
||||
google: this.getGeminiOptions(options, model.id),
|
||||
},
|
||||
tools: await this.getTools(options, model.id),
|
||||
maxSteps: this.MAX_STEPS,
|
||||
experimental_continueSteps: true,
|
||||
});
|
||||
|
||||
if (!text) throw new Error('Failed to generate text');
|
||||
@@ -233,12 +239,16 @@ export abstract class GeminiProvider<T> extends CopilotProvider<T> {
|
||||
taskType: 'RETRIEVAL_DOCUMENT',
|
||||
});
|
||||
|
||||
const { embeddings } = await embedMany({
|
||||
model: modelInstance,
|
||||
values: messages,
|
||||
});
|
||||
const embeddings = await Promise.allSettled(
|
||||
messages.map(m =>
|
||||
embedMany({ model: modelInstance, values: [m], maxRetries: 3 })
|
||||
)
|
||||
);
|
||||
|
||||
return embeddings.filter(v => v && Array.isArray(v));
|
||||
return embeddings
|
||||
.map(e => (e.status === 'fulfilled' ? e.value.embeddings : null))
|
||||
.flat()
|
||||
.filter((v): v is number[] => !!v && Array.isArray(v));
|
||||
} catch (e: any) {
|
||||
metrics.ai
|
||||
.counter('generate_embedding_errors')
|
||||
@@ -254,16 +264,16 @@ export abstract class GeminiProvider<T> extends CopilotProvider<T> {
|
||||
) {
|
||||
const [system, msgs] = await chatToGPTMessage(messages);
|
||||
const { fullStream } = streamText({
|
||||
model: this.instance(model.id, {
|
||||
useSearchGrounding: this.useSearchGrounding(options),
|
||||
}),
|
||||
model: this.instance(model.id),
|
||||
system,
|
||||
messages: msgs,
|
||||
abortSignal: options.signal,
|
||||
maxSteps: this.MAX_STEPS,
|
||||
providerOptions: {
|
||||
google: this.getGeminiOptions(options, model.id),
|
||||
},
|
||||
tools: await this.getTools(options, model.id),
|
||||
maxSteps: this.MAX_STEPS,
|
||||
experimental_continueSteps: true,
|
||||
});
|
||||
return fullStream;
|
||||
}
|
||||
@@ -282,8 +292,4 @@ export abstract class GeminiProvider<T> extends CopilotProvider<T> {
|
||||
private isReasoningModel(model: string) {
|
||||
return model.startsWith('gemini-2.5');
|
||||
}
|
||||
|
||||
private useSearchGrounding(options: CopilotChatOptions) {
|
||||
return options?.tools?.includes('webSearch');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,9 +274,11 @@ export class OpenAIProvider extends CopilotProvider<OpenAIConfig> {
|
||||
override getProviderSpecificTools(
|
||||
toolName: CopilotChatTools,
|
||||
model: string
|
||||
): [string, Tool] | undefined {
|
||||
): [string, Tool?] | undefined {
|
||||
if (toolName === 'webSearch' && !this.isReasoningModel(model)) {
|
||||
return ['web_search_preview', openai.tools.webSearchPreview()];
|
||||
} else if (toolName === 'docEdit') {
|
||||
return ['doc_edit', undefined];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ export abstract class CopilotProvider<C = any> {
|
||||
protected getProviderSpecificTools(
|
||||
_toolName: CopilotChatTools,
|
||||
_model: string
|
||||
): [string, Tool] | undefined {
|
||||
): [string, Tool?] | undefined {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,10 @@ export abstract class CopilotProvider<C = any> {
|
||||
for (const tool of options.tools) {
|
||||
const toolDef = this.getProviderSpecificTools(tool, model);
|
||||
if (toolDef) {
|
||||
tools[toolDef[0]] = toolDef[1];
|
||||
// allow provider prevent tool creation
|
||||
if (toolDef[1]) {
|
||||
tools[toolDef[0]] = toolDef[1];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
switch (tool) {
|
||||
|
||||
@@ -58,7 +58,7 @@ export const createDocSemanticSearchTool = (
|
||||
) => {
|
||||
return tool({
|
||||
description:
|
||||
'Retrieve conceptually related passages by performing vector-based semantic similarity search across embedded documents; use this tool only when exact keyword search fails or the user explicitly needs meaning-level matches (e.g., paraphrases, synonyms, broader concepts).',
|
||||
'Retrieve conceptually related passages by performing vector-based semantic similarity search across embedded documents; use this tool only when exact keyword search fails or the user explicitly needs meaning-level matches (e.g., paraphrases, synonyms, broader concepts, recent documents).',
|
||||
parameters: z.object({
|
||||
query: z
|
||||
.string()
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package app.affine.pro.ai.chat
|
||||
|
||||
import com.affine.pro.graphql.GetCopilotHistoriesQuery
|
||||
import com.affine.pro.graphql.fragment.CopilotChatHistory
|
||||
import com.affine.pro.graphql.fragment.CopilotChatMessage
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
|
||||
@@ -51,11 +53,11 @@ data class ChatMessage(
|
||||
createAt = Clock.System.now(),
|
||||
)
|
||||
|
||||
fun from(message: GetCopilotHistoriesQuery.Message) = ChatMessage(
|
||||
fun from(message: CopilotChatMessage) = ChatMessage(
|
||||
id = message.id,
|
||||
role = Role.fromValue(message.role),
|
||||
content = message.content,
|
||||
createAt = message.createdAt,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import com.affine.pro.graphql.GetCopilotHistoryIdsQuery
|
||||
import com.affine.pro.graphql.GetCopilotSessionsQuery
|
||||
import com.affine.pro.graphql.type.CreateChatMessageInput
|
||||
import com.affine.pro.graphql.type.CreateChatSessionInput
|
||||
import com.affine.pro.graphql.type.QueryChatSessionsInput
|
||||
import com.affine.pro.graphql.type.PaginationInput
|
||||
import com.affine.pro.graphql.type.QueryChatHistoriesInput
|
||||
import com.apollographql.apollo.ApolloClient
|
||||
import com.apollographql.apollo.api.Mutation
|
||||
import com.apollographql.apollo.api.Optional
|
||||
@@ -29,12 +30,15 @@ class GraphQLService @Inject constructor() {
|
||||
GetCopilotSessionsQuery(
|
||||
workspaceId = workspaceId,
|
||||
docId = Optional.present(docId),
|
||||
options = Optional.present(QueryChatSessionsInput(action = Optional.present(false)))
|
||||
pagination = PaginationInput(
|
||||
first = Optional.present(100)
|
||||
),
|
||||
options = Optional.present(QueryChatHistoriesInput(action = Optional.present(false)))
|
||||
)
|
||||
).mapCatching { data ->
|
||||
data.currentUser?.copilot?.sessions?.find {
|
||||
data.currentUser?.copilot?.chats?.paginatedCopilotChats?.edges?.map { item -> item.node.copilotChatHistory }?.find {
|
||||
it.parentSessionId == null
|
||||
}?.id ?: error(ERROR_NULL_SESSION_ID)
|
||||
}?.sessionId ?: error(ERROR_NULL_SESSION_ID)
|
||||
}
|
||||
|
||||
suspend fun createCopilotSession(
|
||||
@@ -60,12 +64,15 @@ class GraphQLService @Inject constructor() {
|
||||
) = query(
|
||||
GetCopilotHistoriesQuery(
|
||||
workspaceId = workspaceId,
|
||||
pagination = PaginationInput(
|
||||
first = Optional.present(100)
|
||||
),
|
||||
docId = Optional.present(docId),
|
||||
)
|
||||
).mapCatching { data ->
|
||||
data.currentUser?.copilot?.histories?.firstOrNull { history ->
|
||||
history.sessionId == sessionId
|
||||
}?.messages ?: emptyList()
|
||||
data.currentUser?.copilot?.chats?.paginatedCopilotChats?.edges?.map { item -> item.node.copilotChatHistory }?.firstOrNull { history ->
|
||||
history.sessionId == sessionId
|
||||
}?.messages?.map { msg -> msg.copilotChatMessage } ?: emptyList()
|
||||
}
|
||||
|
||||
suspend fun getCopilotHistoryIds(
|
||||
@@ -76,9 +83,12 @@ class GraphQLService @Inject constructor() {
|
||||
GetCopilotHistoryIdsQuery(
|
||||
workspaceId = workspaceId,
|
||||
docId = Optional.present(docId),
|
||||
pagination = PaginationInput(
|
||||
first = Optional.present(100)
|
||||
),
|
||||
)
|
||||
).mapCatching { data ->
|
||||
data.currentUser?.copilot?.histories?.firstOrNull { history ->
|
||||
data.currentUser?.copilot?.chats?.edges?.map { item -> item.node }?.firstOrNull { history ->
|
||||
history.sessionId == sessionId
|
||||
}?.messages ?: emptyList()
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 77;
|
||||
objectVersion = 56;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
@@ -90,6 +90,8 @@
|
||||
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||
C45499AB2D140B5000E21978 /* NBStore */ = {
|
||||
isa = PBXFileSystemSynchronizedRootGroup;
|
||||
exceptions = (
|
||||
);
|
||||
path = NBStore;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -337,13 +339,9 @@
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AFFiNE/Pods-AFFiNE-frameworks.sh\"\n";
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public struct CopilotChatHistory: AffineGraphQL.SelectionSet, Fragment {
|
||||
public static var fragmentDefinition: StaticString {
|
||||
#"fragment CopilotChatHistory on CopilotHistories { __typename sessionId workspaceId docId parentSessionId promptName model optionalModels action pinned title tokens messages { __typename ...CopilotChatMessage } createdAt updatedAt }"#
|
||||
}
|
||||
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistories }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("sessionId", String.self),
|
||||
.field("workspaceId", String.self),
|
||||
.field("docId", String?.self),
|
||||
.field("parentSessionId", String?.self),
|
||||
.field("promptName", String.self),
|
||||
.field("model", String.self),
|
||||
.field("optionalModels", [String].self),
|
||||
.field("action", String?.self),
|
||||
.field("pinned", Bool.self),
|
||||
.field("title", String?.self),
|
||||
.field("tokens", Int.self),
|
||||
.field("messages", [Message].self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("updatedAt", AffineGraphQL.DateTime.self),
|
||||
] }
|
||||
|
||||
public var sessionId: String { __data["sessionId"] }
|
||||
public var workspaceId: String { __data["workspaceId"] }
|
||||
public var docId: String? { __data["docId"] }
|
||||
public var parentSessionId: String? { __data["parentSessionId"] }
|
||||
public var promptName: String { __data["promptName"] }
|
||||
public var model: String { __data["model"] }
|
||||
public var optionalModels: [String] { __data["optionalModels"] }
|
||||
/// An mark identifying which view to use to display the session
|
||||
public var action: String? { __data["action"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
public var title: String? { __data["title"] }
|
||||
/// The number of tokens used in the session
|
||||
public var tokens: Int { __data["tokens"] }
|
||||
public var messages: [Message] { __data["messages"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
|
||||
/// Message
|
||||
///
|
||||
/// Parent Type: `ChatMessage`
|
||||
public struct Message: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ChatMessage }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.fragment(CopilotChatMessage.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID? { __data["id"] }
|
||||
public var role: String { __data["role"] }
|
||||
public var content: String { __data["content"] }
|
||||
public var attachments: [String]? { __data["attachments"] }
|
||||
public var streamObjects: [StreamObject]? { __data["streamObjects"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var copilotChatMessage: CopilotChatMessage { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias StreamObject = CopilotChatMessage.StreamObject
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public struct CopilotChatMessage: AffineGraphQL.SelectionSet, Fragment {
|
||||
public static var fragmentDefinition: StaticString {
|
||||
#"fragment CopilotChatMessage on ChatMessage { __typename id role content attachments streamObjects { __typename type textDelta toolCallId toolName args result } createdAt }"#
|
||||
}
|
||||
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ChatMessage }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID?.self),
|
||||
.field("role", String.self),
|
||||
.field("content", String.self),
|
||||
.field("attachments", [String]?.self),
|
||||
.field("streamObjects", [StreamObject]?.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID? { __data["id"] }
|
||||
public var role: String { __data["role"] }
|
||||
public var content: String { __data["content"] }
|
||||
public var attachments: [String]? { __data["attachments"] }
|
||||
public var streamObjects: [StreamObject]? { __data["streamObjects"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
|
||||
/// StreamObject
|
||||
///
|
||||
/// Parent Type: `StreamObject`
|
||||
public struct StreamObject: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.StreamObject }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("type", String.self),
|
||||
.field("textDelta", String?.self),
|
||||
.field("toolCallId", String?.self),
|
||||
.field("toolName", String?.self),
|
||||
.field("args", AffineGraphQL.JSON?.self),
|
||||
.field("result", AffineGraphQL.JSON?.self),
|
||||
] }
|
||||
|
||||
public var type: String { __data["type"] }
|
||||
public var textDelta: String? { __data["textDelta"] }
|
||||
public var toolCallId: String? { __data["toolCallId"] }
|
||||
public var toolName: String? { __data["toolName"] }
|
||||
public var args: AffineGraphQL.JSON? { __data["args"] }
|
||||
public var result: AffineGraphQL.JSON? { __data["result"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public struct PaginatedCopilotChats: AffineGraphQL.SelectionSet, Fragment {
|
||||
public static var fragmentDefinition: StaticString {
|
||||
#"fragment PaginatedCopilotChats on PaginatedCopilotHistoriesType { __typename pageInfo { __typename hasNextPage hasPreviousPage startCursor endCursor } edges { __typename cursor node { __typename ...CopilotChatHistory } } }"#
|
||||
}
|
||||
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("pageInfo", PageInfo.self),
|
||||
.field("edges", [Edge].self),
|
||||
] }
|
||||
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
/// PageInfo
|
||||
///
|
||||
/// Parent Type: `PageInfo`
|
||||
public struct PageInfo: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PageInfo }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("hasNextPage", Bool.self),
|
||||
.field("hasPreviousPage", Bool.self),
|
||||
.field("startCursor", String?.self),
|
||||
.field("endCursor", String?.self),
|
||||
] }
|
||||
|
||||
public var hasNextPage: Bool { __data["hasNextPage"] }
|
||||
public var hasPreviousPage: Bool { __data["hasPreviousPage"] }
|
||||
public var startCursor: String? { __data["startCursor"] }
|
||||
public var endCursor: String? { __data["endCursor"] }
|
||||
}
|
||||
|
||||
/// Edge
|
||||
///
|
||||
/// Parent Type: `CopilotHistoriesTypeEdge`
|
||||
public struct Edge: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistoriesTypeEdge }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("cursor", String.self),
|
||||
.field("node", Node.self),
|
||||
] }
|
||||
|
||||
public var cursor: String { __data["cursor"] }
|
||||
public var node: Node { __data["node"] }
|
||||
|
||||
/// Edge.Node
|
||||
///
|
||||
/// Parent Type: `CopilotHistories`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistories }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.fragment(CopilotChatHistory.self),
|
||||
] }
|
||||
|
||||
public var sessionId: String { __data["sessionId"] }
|
||||
public var workspaceId: String { __data["workspaceId"] }
|
||||
public var docId: String? { __data["docId"] }
|
||||
public var parentSessionId: String? { __data["parentSessionId"] }
|
||||
public var promptName: String { __data["promptName"] }
|
||||
public var model: String { __data["model"] }
|
||||
public var optionalModels: [String] { __data["optionalModels"] }
|
||||
/// An mark identifying which view to use to display the session
|
||||
public var action: String? { __data["action"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
public var title: String? { __data["title"] }
|
||||
/// The number of tokens used in the session
|
||||
public var tokens: Int { __data["tokens"] }
|
||||
public var messages: [Message] { __data["messages"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var copilotChatHistory: CopilotChatHistory { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias Message = CopilotChatHistory.Message
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class CreateCommentMutation: GraphQLMutation {
|
||||
public static let operationName: String = "createComment"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation createComment($input: CommentCreateInput!) { createComment(input: $input) { __typename id content resolved createdAt updatedAt user { __typename id name avatarUrl } replies { __typename commentId id content createdAt updatedAt user { __typename id name avatarUrl } } } }"#
|
||||
))
|
||||
|
||||
public var input: CommentCreateInput
|
||||
|
||||
public init(input: CommentCreateInput) {
|
||||
self.input = input
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["input": input] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("createComment", CreateComment.self, arguments: ["input": .variable("input")]),
|
||||
] }
|
||||
|
||||
public var createComment: CreateComment { __data["createComment"] }
|
||||
|
||||
/// CreateComment
|
||||
///
|
||||
/// Parent Type: `CommentObjectType`
|
||||
public struct CreateComment: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CommentObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("content", AffineGraphQL.JSONObject.self),
|
||||
.field("resolved", Bool.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("updatedAt", AffineGraphQL.DateTime.self),
|
||||
.field("user", User.self),
|
||||
.field("replies", [Reply].self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
/// The content of the comment
|
||||
public var content: AffineGraphQL.JSONObject { __data["content"] }
|
||||
/// Whether the comment is resolved
|
||||
public var resolved: Bool { __data["resolved"] }
|
||||
/// The created at time of the comment
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
/// The updated at time of the comment
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
/// The user who created the comment
|
||||
public var user: User { __data["user"] }
|
||||
/// The replies of the comment
|
||||
public var replies: [Reply] { __data["replies"] }
|
||||
|
||||
/// CreateComment.User
|
||||
///
|
||||
/// Parent Type: `PublicUserType`
|
||||
public struct User: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PublicUserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", String.self),
|
||||
.field("name", String.self),
|
||||
.field("avatarUrl", String?.self),
|
||||
] }
|
||||
|
||||
public var id: String { __data["id"] }
|
||||
public var name: String { __data["name"] }
|
||||
public var avatarUrl: String? { __data["avatarUrl"] }
|
||||
}
|
||||
|
||||
/// CreateComment.Reply
|
||||
///
|
||||
/// Parent Type: `ReplyObjectType`
|
||||
public struct Reply: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ReplyObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("commentId", AffineGraphQL.ID.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("content", AffineGraphQL.JSONObject.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("updatedAt", AffineGraphQL.DateTime.self),
|
||||
.field("user", User.self),
|
||||
] }
|
||||
|
||||
public var commentId: AffineGraphQL.ID { __data["commentId"] }
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
/// The content of the reply
|
||||
public var content: AffineGraphQL.JSONObject { __data["content"] }
|
||||
/// The created at time of the reply
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
/// The updated at time of the reply
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
/// The user who created the reply
|
||||
public var user: User { __data["user"] }
|
||||
|
||||
/// CreateComment.Reply.User
|
||||
///
|
||||
/// Parent Type: `PublicUserType`
|
||||
public struct User: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PublicUserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", String.self),
|
||||
.field("name", String.self),
|
||||
.field("avatarUrl", String?.self),
|
||||
] }
|
||||
|
||||
public var id: String { __data["id"] }
|
||||
public var name: String { __data["name"] }
|
||||
public var avatarUrl: String? { __data["avatarUrl"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class CreateReplyMutation: GraphQLMutation {
|
||||
public static let operationName: String = "createReply"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation createReply($input: ReplyCreateInput!) { createReply(input: $input) { __typename commentId id content createdAt updatedAt user { __typename id name avatarUrl } } }"#
|
||||
))
|
||||
|
||||
public var input: ReplyCreateInput
|
||||
|
||||
public init(input: ReplyCreateInput) {
|
||||
self.input = input
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["input": input] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("createReply", CreateReply.self, arguments: ["input": .variable("input")]),
|
||||
] }
|
||||
|
||||
public var createReply: CreateReply { __data["createReply"] }
|
||||
|
||||
/// CreateReply
|
||||
///
|
||||
/// Parent Type: `ReplyObjectType`
|
||||
public struct CreateReply: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ReplyObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("commentId", AffineGraphQL.ID.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("content", AffineGraphQL.JSONObject.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("updatedAt", AffineGraphQL.DateTime.self),
|
||||
.field("user", User.self),
|
||||
] }
|
||||
|
||||
public var commentId: AffineGraphQL.ID { __data["commentId"] }
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
/// The content of the reply
|
||||
public var content: AffineGraphQL.JSONObject { __data["content"] }
|
||||
/// The created at time of the reply
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
/// The updated at time of the reply
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
/// The user who created the reply
|
||||
public var user: User { __data["user"] }
|
||||
|
||||
/// CreateReply.User
|
||||
///
|
||||
/// Parent Type: `PublicUserType`
|
||||
public struct User: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PublicUserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", String.self),
|
||||
.field("name", String.self),
|
||||
.field("avatarUrl", String?.self),
|
||||
] }
|
||||
|
||||
public var id: String { __data["id"] }
|
||||
public var name: String { __data["name"] }
|
||||
public var avatarUrl: String? { __data["avatarUrl"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class DeleteCommentMutation: GraphQLMutation {
|
||||
public static let operationName: String = "deleteComment"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation deleteComment($id: String!) { deleteComment(id: $id) }"#
|
||||
))
|
||||
|
||||
public var id: String
|
||||
|
||||
public init(id: String) {
|
||||
self.id = id
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["id": id] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("deleteComment", Bool.self, arguments: ["id": .variable("id")]),
|
||||
] }
|
||||
|
||||
/// Delete a comment
|
||||
public var deleteComment: Bool { __data["deleteComment"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class DeleteReplyMutation: GraphQLMutation {
|
||||
public static let operationName: String = "deleteReply"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation deleteReply($id: String!) { deleteReply(id: $id) }"#
|
||||
))
|
||||
|
||||
public var id: String
|
||||
|
||||
public init(id: String) {
|
||||
self.id = id
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["id": id] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("deleteReply", Bool.self, arguments: ["id": .variable("id")]),
|
||||
] }
|
||||
|
||||
/// Delete a reply
|
||||
public var deleteReply: Bool { __data["deleteReply"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class ReadAllNotificationsMutation: GraphQLMutation {
|
||||
public static let operationName: String = "readAllNotifications"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation readAllNotifications { readAllNotifications }"#
|
||||
))
|
||||
|
||||
public init() {}
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("readAllNotifications", Bool.self),
|
||||
] }
|
||||
|
||||
/// mark all notifications as read
|
||||
public var readAllNotifications: Bool { __data["readAllNotifications"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class ResolveCommentMutation: GraphQLMutation {
|
||||
public static let operationName: String = "resolveComment"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation resolveComment($input: CommentResolveInput!) { resolveComment(input: $input) }"#
|
||||
))
|
||||
|
||||
public var input: CommentResolveInput
|
||||
|
||||
public init(input: CommentResolveInput) {
|
||||
self.input = input
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["input": input] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("resolveComment", Bool.self, arguments: ["input": .variable("input")]),
|
||||
] }
|
||||
|
||||
/// Resolve a comment or not
|
||||
public var resolveComment: Bool { __data["resolveComment"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class UpdateCommentMutation: GraphQLMutation {
|
||||
public static let operationName: String = "updateComment"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation updateComment($input: CommentUpdateInput!) { updateComment(input: $input) }"#
|
||||
))
|
||||
|
||||
public var input: CommentUpdateInput
|
||||
|
||||
public init(input: CommentUpdateInput) {
|
||||
self.input = input
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["input": input] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("updateComment", Bool.self, arguments: ["input": .variable("input")]),
|
||||
] }
|
||||
|
||||
/// Update a comment content
|
||||
public var updateComment: Bool { __data["updateComment"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class UpdateReplyMutation: GraphQLMutation {
|
||||
public static let operationName: String = "updateReply"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation updateReply($input: ReplyUpdateInput!) { updateReply(input: $input) }"#
|
||||
))
|
||||
|
||||
public var input: ReplyUpdateInput
|
||||
|
||||
public init(input: ReplyUpdateInput) {
|
||||
self.input = input
|
||||
}
|
||||
|
||||
public var __variables: Variables? { ["input": input] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("updateReply", Bool.self, arguments: ["input": .variable("input")]),
|
||||
] }
|
||||
|
||||
/// Update a reply content
|
||||
public var updateReply: Bool { __data["updateReply"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class UploadCommentAttachmentMutation: GraphQLMutation {
|
||||
public static let operationName: String = "uploadCommentAttachment"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"mutation uploadCommentAttachment($workspaceId: String!, $docId: String!, $attachment: Upload!) { uploadCommentAttachment( workspaceId: $workspaceId docId: $docId attachment: $attachment ) }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var docId: String
|
||||
public var attachment: Upload
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
docId: String,
|
||||
attachment: Upload
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.docId = docId
|
||||
self.attachment = attachment
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"docId": docId,
|
||||
"attachment": attachment
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Mutation }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("uploadCommentAttachment", String.self, arguments: [
|
||||
"workspaceId": .variable("workspaceId"),
|
||||
"docId": .variable("docId"),
|
||||
"attachment": .variable("attachment")
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Upload a comment attachment and return the access url
|
||||
public var uploadCommentAttachment: String { __data["uploadCommentAttachment"] }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetCopilotDocSessionsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotDocSessions"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotDocSessions($workspaceId: String!, $docId: String!, $pagination: PaginationInput!, $options: QueryChatHistoriesInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats(pagination: $pagination, docId: $docId, options: $options) { __typename ...PaginatedCopilotChats } } } }"#,
|
||||
fragments: [CopilotChatHistory.self, CopilotChatMessage.self, PaginatedCopilotChats.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var docId: String
|
||||
public var pagination: PaginationInput
|
||||
public var options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
docId: String,
|
||||
pagination: PaginationInput,
|
||||
options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.docId = docId
|
||||
self.pagination = pagination
|
||||
self.options = options
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"docId": docId,
|
||||
"pagination": pagination,
|
||||
"options": options
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("currentUser", CurrentUser?.self),
|
||||
] }
|
||||
|
||||
/// Get current user
|
||||
public var currentUser: CurrentUser? { __data["currentUser"] }
|
||||
|
||||
/// CurrentUser
|
||||
///
|
||||
/// Parent Type: `UserType`
|
||||
public struct CurrentUser: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.UserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("copilot", Copilot.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
public var copilot: Copilot { __data["copilot"] }
|
||||
|
||||
/// CurrentUser.Copilot
|
||||
///
|
||||
/// Parent Type: `Copilot`
|
||||
public struct Copilot: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": .variable("pagination"),
|
||||
"docId": .variable("docId"),
|
||||
"options": .variable("options")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.fragment(PaginatedCopilotChats.self),
|
||||
] }
|
||||
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var paginatedCopilotChats: PaginatedCopilotChats { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias PageInfo = PaginatedCopilotChats.PageInfo
|
||||
|
||||
public typealias Edge = PaginatedCopilotChats.Edge
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,25 +7,30 @@ public class GetCopilotHistoriesQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotHistories"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotHistories($workspaceId: String!, $docId: String, $options: QueryChatHistoriesInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename histories(docId: $docId, options: $options) { __typename sessionId pinned tokens action createdAt messages { __typename id role content streamObjects { __typename type textDelta toolCallId toolName args result } attachments createdAt } } } } }"#
|
||||
#"query getCopilotHistories($workspaceId: String!, $pagination: PaginationInput!, $docId: String, $options: QueryChatHistoriesInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats(pagination: $pagination, docId: $docId, options: $options) { __typename ...PaginatedCopilotChats } } } }"#,
|
||||
fragments: [CopilotChatHistory.self, CopilotChatMessage.self, PaginatedCopilotChats.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var pagination: PaginationInput
|
||||
public var docId: GraphQLNullable<String>
|
||||
public var options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
pagination: PaginationInput,
|
||||
docId: GraphQLNullable<String>,
|
||||
options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.pagination = pagination
|
||||
self.docId = docId
|
||||
self.options = options
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"pagination": pagination,
|
||||
"docId": docId,
|
||||
"options": options
|
||||
] }
|
||||
@@ -67,92 +72,41 @@ public class GetCopilotHistoriesQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("histories", [History].self, arguments: [
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": .variable("pagination"),
|
||||
"docId": .variable("docId"),
|
||||
"options": .variable("options")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var histories: [History] { __data["histories"] }
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.History
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `CopilotHistories`
|
||||
public struct History: AffineGraphQL.SelectionSet {
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistories }
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("sessionId", String.self),
|
||||
.field("pinned", Bool.self),
|
||||
.field("tokens", Int.self),
|
||||
.field("action", String?.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("messages", [Message].self),
|
||||
.fragment(PaginatedCopilotChats.self),
|
||||
] }
|
||||
|
||||
public var sessionId: String { __data["sessionId"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
/// The number of tokens used in the session
|
||||
public var tokens: Int { __data["tokens"] }
|
||||
/// An mark identifying which view to use to display the session
|
||||
public var action: String? { __data["action"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
public var messages: [Message] { __data["messages"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
/// CurrentUser.Copilot.History.Message
|
||||
///
|
||||
/// Parent Type: `ChatMessage`
|
||||
public struct Message: AffineGraphQL.SelectionSet {
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ChatMessage }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID?.self),
|
||||
.field("role", String.self),
|
||||
.field("content", String.self),
|
||||
.field("streamObjects", [StreamObject]?.self),
|
||||
.field("attachments", [String]?.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID? { __data["id"] }
|
||||
public var role: String { __data["role"] }
|
||||
public var content: String { __data["content"] }
|
||||
public var streamObjects: [StreamObject]? { __data["streamObjects"] }
|
||||
public var attachments: [String]? { __data["attachments"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
|
||||
/// CurrentUser.Copilot.History.Message.StreamObject
|
||||
///
|
||||
/// Parent Type: `StreamObject`
|
||||
public struct StreamObject: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.StreamObject }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("type", String.self),
|
||||
.field("textDelta", String?.self),
|
||||
.field("toolCallId", String?.self),
|
||||
.field("toolName", String?.self),
|
||||
.field("args", AffineGraphQL.JSON?.self),
|
||||
.field("result", AffineGraphQL.JSON?.self),
|
||||
] }
|
||||
|
||||
public var type: String { __data["type"] }
|
||||
public var textDelta: String? { __data["textDelta"] }
|
||||
public var toolCallId: String? { __data["toolCallId"] }
|
||||
public var toolName: String? { __data["toolName"] }
|
||||
public var args: AffineGraphQL.JSON? { __data["args"] }
|
||||
public var result: AffineGraphQL.JSON? { __data["result"] }
|
||||
}
|
||||
public var paginatedCopilotChats: PaginatedCopilotChats { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias PageInfo = PaginatedCopilotChats.PageInfo
|
||||
|
||||
public typealias Edge = PaginatedCopilotChats.Edge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,25 +7,29 @@ public class GetCopilotHistoryIdsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotHistoryIds"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotHistoryIds($workspaceId: String!, $docId: String, $options: QueryChatHistoriesInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename histories(docId: $docId, options: $options) { __typename sessionId pinned messages { __typename id role createdAt } } } } }"#
|
||||
#"query getCopilotHistoryIds($workspaceId: String!, $pagination: PaginationInput!, $docId: String, $options: QueryChatHistoriesInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats(pagination: $pagination, docId: $docId, options: $options) { __typename pageInfo { __typename hasNextPage hasPreviousPage startCursor endCursor } edges { __typename cursor node { __typename sessionId pinned messages { __typename id role createdAt } } } } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var pagination: PaginationInput
|
||||
public var docId: GraphQLNullable<String>
|
||||
public var options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
pagination: PaginationInput,
|
||||
docId: GraphQLNullable<String>,
|
||||
options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.pagination = pagination
|
||||
self.docId = docId
|
||||
self.options = options
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"pagination": pagination,
|
||||
"docId": docId,
|
||||
"options": options
|
||||
] }
|
||||
@@ -67,51 +71,110 @@ public class GetCopilotHistoryIdsQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("histories", [History].self, arguments: [
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": .variable("pagination"),
|
||||
"docId": .variable("docId"),
|
||||
"options": .variable("options")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var histories: [History] { __data["histories"] }
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.History
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `CopilotHistories`
|
||||
public struct History: AffineGraphQL.SelectionSet {
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistories }
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("sessionId", String.self),
|
||||
.field("pinned", Bool.self),
|
||||
.field("messages", [Message].self),
|
||||
.field("pageInfo", PageInfo.self),
|
||||
.field("edges", [Edge].self),
|
||||
] }
|
||||
|
||||
public var sessionId: String { __data["sessionId"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
public var messages: [Message] { __data["messages"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
/// CurrentUser.Copilot.History.Message
|
||||
/// CurrentUser.Copilot.Chats.PageInfo
|
||||
///
|
||||
/// Parent Type: `ChatMessage`
|
||||
public struct Message: AffineGraphQL.SelectionSet {
|
||||
/// Parent Type: `PageInfo`
|
||||
public struct PageInfo: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ChatMessage }
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PageInfo }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID?.self),
|
||||
.field("role", String.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("hasNextPage", Bool.self),
|
||||
.field("hasPreviousPage", Bool.self),
|
||||
.field("startCursor", String?.self),
|
||||
.field("endCursor", String?.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID? { __data["id"] }
|
||||
public var role: String { __data["role"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
public var hasNextPage: Bool { __data["hasNextPage"] }
|
||||
public var hasPreviousPage: Bool { __data["hasPreviousPage"] }
|
||||
public var startCursor: String? { __data["startCursor"] }
|
||||
public var endCursor: String? { __data["endCursor"] }
|
||||
}
|
||||
|
||||
/// CurrentUser.Copilot.Chats.Edge
|
||||
///
|
||||
/// Parent Type: `CopilotHistoriesTypeEdge`
|
||||
public struct Edge: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistoriesTypeEdge }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("cursor", String.self),
|
||||
.field("node", Node.self),
|
||||
] }
|
||||
|
||||
public var cursor: String { __data["cursor"] }
|
||||
public var node: Node { __data["node"] }
|
||||
|
||||
/// CurrentUser.Copilot.Chats.Edge.Node
|
||||
///
|
||||
/// Parent Type: `CopilotHistories`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistories }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("sessionId", String.self),
|
||||
.field("pinned", Bool.self),
|
||||
.field("messages", [Message].self),
|
||||
] }
|
||||
|
||||
public var sessionId: String { __data["sessionId"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
public var messages: [Message] { __data["messages"] }
|
||||
|
||||
/// CurrentUser.Copilot.Chats.Edge.Node.Message
|
||||
///
|
||||
/// Parent Type: `ChatMessage`
|
||||
public struct Message: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ChatMessage }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID?.self),
|
||||
.field("role", String.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID? { __data["id"] }
|
||||
public var role: String { __data["role"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ public class GetCopilotLatestDocSessionQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotLatestDocSession"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotLatestDocSession($workspaceId: String!, $docId: String!) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename histories( docId: $docId options: { limit: 1, sessionOrder: desc, action: false, fork: false } ) { __typename sessionId workspaceId docId pinned action tokens createdAt updatedAt messages { __typename id role content attachments params createdAt } } } } }"#
|
||||
#"query getCopilotLatestDocSession($workspaceId: String!, $docId: String!) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats( pagination: { first: 1 } docId: $docId options: { sessionOrder: desc, action: false, fork: false, withMessages: true } ) { __typename ...PaginatedCopilotChats } } } }"#,
|
||||
fragments: [CopilotChatHistory.self, CopilotChatMessage.self, PaginatedCopilotChats.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -63,77 +64,46 @@ public class GetCopilotLatestDocSessionQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("histories", [History].self, arguments: [
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": ["first": 1],
|
||||
"docId": .variable("docId"),
|
||||
"options": [
|
||||
"limit": 1,
|
||||
"sessionOrder": "desc",
|
||||
"action": false,
|
||||
"fork": false
|
||||
"fork": false,
|
||||
"withMessages": true
|
||||
]
|
||||
]),
|
||||
] }
|
||||
|
||||
public var histories: [History] { __data["histories"] }
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.History
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `CopilotHistories`
|
||||
public struct History: AffineGraphQL.SelectionSet {
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistories }
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("sessionId", String.self),
|
||||
.field("workspaceId", String.self),
|
||||
.field("docId", String?.self),
|
||||
.field("pinned", Bool.self),
|
||||
.field("action", String?.self),
|
||||
.field("tokens", Int.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("updatedAt", AffineGraphQL.DateTime.self),
|
||||
.field("messages", [Message].self),
|
||||
.fragment(PaginatedCopilotChats.self),
|
||||
] }
|
||||
|
||||
public var sessionId: String { __data["sessionId"] }
|
||||
public var workspaceId: String { __data["workspaceId"] }
|
||||
public var docId: String? { __data["docId"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
/// An mark identifying which view to use to display the session
|
||||
public var action: String? { __data["action"] }
|
||||
/// The number of tokens used in the session
|
||||
public var tokens: Int { __data["tokens"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
public var messages: [Message] { __data["messages"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
/// CurrentUser.Copilot.History.Message
|
||||
///
|
||||
/// Parent Type: `ChatMessage`
|
||||
public struct Message: AffineGraphQL.SelectionSet {
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ChatMessage }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID?.self),
|
||||
.field("role", String.self),
|
||||
.field("content", String.self),
|
||||
.field("attachments", [String]?.self),
|
||||
.field("params", AffineGraphQL.JSON?.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID? { __data["id"] }
|
||||
public var role: String { __data["role"] }
|
||||
public var content: String { __data["content"] }
|
||||
public var attachments: [String]? { __data["attachments"] }
|
||||
public var params: AffineGraphQL.JSON? { __data["params"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
public var paginatedCopilotChats: PaginatedCopilotChats { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias PageInfo = PaginatedCopilotChats.PageInfo
|
||||
|
||||
public typealias Edge = PaginatedCopilotChats.Edge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetCopilotPinnedSessionsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotPinnedSessions"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotPinnedSessions($workspaceId: String!, $docId: String, $messageOrder: ChatHistoryOrder, $withPrompt: Boolean) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats( pagination: { first: 1 } docId: $docId options: { pinned: true, messageOrder: $messageOrder, withPrompt: $withPrompt } ) { __typename ...PaginatedCopilotChats } } } }"#,
|
||||
fragments: [CopilotChatHistory.self, CopilotChatMessage.self, PaginatedCopilotChats.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var docId: GraphQLNullable<String>
|
||||
public var messageOrder: GraphQLNullable<GraphQLEnum<ChatHistoryOrder>>
|
||||
public var withPrompt: GraphQLNullable<Bool>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
docId: GraphQLNullable<String>,
|
||||
messageOrder: GraphQLNullable<GraphQLEnum<ChatHistoryOrder>>,
|
||||
withPrompt: GraphQLNullable<Bool>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.docId = docId
|
||||
self.messageOrder = messageOrder
|
||||
self.withPrompt = withPrompt
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"docId": docId,
|
||||
"messageOrder": messageOrder,
|
||||
"withPrompt": withPrompt
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("currentUser", CurrentUser?.self),
|
||||
] }
|
||||
|
||||
/// Get current user
|
||||
public var currentUser: CurrentUser? { __data["currentUser"] }
|
||||
|
||||
/// CurrentUser
|
||||
///
|
||||
/// Parent Type: `UserType`
|
||||
public struct CurrentUser: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.UserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("copilot", Copilot.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
public var copilot: Copilot { __data["copilot"] }
|
||||
|
||||
/// CurrentUser.Copilot
|
||||
///
|
||||
/// Parent Type: `Copilot`
|
||||
public struct Copilot: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": ["first": 1],
|
||||
"docId": .variable("docId"),
|
||||
"options": [
|
||||
"pinned": true,
|
||||
"messageOrder": .variable("messageOrder"),
|
||||
"withPrompt": .variable("withPrompt")
|
||||
]
|
||||
]),
|
||||
] }
|
||||
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.fragment(PaginatedCopilotChats.self),
|
||||
] }
|
||||
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var paginatedCopilotChats: PaginatedCopilotChats { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias PageInfo = PaginatedCopilotChats.PageInfo
|
||||
|
||||
public typealias Edge = PaginatedCopilotChats.Edge
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,8 @@ public class GetCopilotRecentSessionsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotRecentSessions"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotRecentSessions($workspaceId: String!, $limit: Int = 10) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename histories(options: { limit: $limit, sessionOrder: desc }) { __typename sessionId workspaceId docId pinned action tokens createdAt updatedAt } } } }"#
|
||||
#"query getCopilotRecentSessions($workspaceId: String!, $limit: Int = 10) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats( pagination: { first: $limit } options: { fork: false, sessionOrder: desc, withMessages: true } ) { __typename ...PaginatedCopilotChats } } } }"#,
|
||||
fragments: [CopilotChatHistory.self, CopilotChatMessage.self, PaginatedCopilotChats.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -63,44 +64,44 @@ public class GetCopilotRecentSessionsQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("histories", [History].self, arguments: ["options": [
|
||||
"limit": .variable("limit"),
|
||||
"sessionOrder": "desc"
|
||||
]]),
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": ["first": .variable("limit")],
|
||||
"options": [
|
||||
"fork": false,
|
||||
"sessionOrder": "desc",
|
||||
"withMessages": true
|
||||
]
|
||||
]),
|
||||
] }
|
||||
|
||||
public var histories: [History] { __data["histories"] }
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.History
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `CopilotHistories`
|
||||
public struct History: AffineGraphQL.SelectionSet {
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotHistories }
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("sessionId", String.self),
|
||||
.field("workspaceId", String.self),
|
||||
.field("docId", String?.self),
|
||||
.field("pinned", Bool.self),
|
||||
.field("action", String?.self),
|
||||
.field("tokens", Int.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("updatedAt", AffineGraphQL.DateTime.self),
|
||||
.fragment(PaginatedCopilotChats.self),
|
||||
] }
|
||||
|
||||
public var sessionId: String { __data["sessionId"] }
|
||||
public var workspaceId: String { __data["workspaceId"] }
|
||||
public var docId: String? { __data["docId"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
/// An mark identifying which view to use to display the session
|
||||
public var action: String? { __data["action"] }
|
||||
/// The number of tokens used in the session
|
||||
public var tokens: Int { __data["tokens"] }
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var paginatedCopilotChats: PaginatedCopilotChats { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias PageInfo = PaginatedCopilotChats.PageInfo
|
||||
|
||||
public typealias Edge = PaginatedCopilotChats.Edge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ public class GetCopilotSessionQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotSession"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotSession($workspaceId: String!, $sessionId: String!) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename session(sessionId: $sessionId) { __typename id parentSessionId docId pinned promptName model optionalModels } } } }"#
|
||||
#"query getCopilotSession($workspaceId: String!, $sessionId: String!) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats(pagination: { first: 1 }, options: { sessionId: $sessionId }) { __typename ...PaginatedCopilotChats } } } }"#,
|
||||
fragments: [CopilotChatHistory.self, CopilotChatMessage.self, PaginatedCopilotChats.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -63,38 +64,40 @@ public class GetCopilotSessionQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("session", Session.self, arguments: ["sessionId": .variable("sessionId")]),
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": ["first": 1],
|
||||
"options": ["sessionId": .variable("sessionId")]
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Get the session by id
|
||||
public var session: Session { __data["session"] }
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.Session
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `CopilotSessionType`
|
||||
public struct Session: AffineGraphQL.SelectionSet {
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotSessionType }
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("parentSessionId", AffineGraphQL.ID?.self),
|
||||
.field("docId", String?.self),
|
||||
.field("pinned", Bool.self),
|
||||
.field("promptName", String.self),
|
||||
.field("model", String.self),
|
||||
.field("optionalModels", [String].self),
|
||||
.fragment(PaginatedCopilotChats.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var parentSessionId: AffineGraphQL.ID? { __data["parentSessionId"] }
|
||||
public var docId: String? { __data["docId"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
public var promptName: String { __data["promptName"] }
|
||||
public var model: String { __data["model"] }
|
||||
public var optionalModels: [String] { __data["optionalModels"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var paginatedCopilotChats: PaginatedCopilotChats { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias PageInfo = PaginatedCopilotChats.PageInfo
|
||||
|
||||
public typealias Edge = PaginatedCopilotChats.Edge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,25 +7,30 @@ public class GetCopilotSessionsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotSessions"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotSessions($workspaceId: String!, $docId: String, $options: QueryChatSessionsInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename sessions(docId: $docId, options: $options) { __typename id parentSessionId docId pinned promptName model optionalModels } } } }"#
|
||||
#"query getCopilotSessions($workspaceId: String!, $pagination: PaginationInput!, $docId: String, $options: QueryChatHistoriesInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats(pagination: $pagination, docId: $docId, options: $options) { __typename ...PaginatedCopilotChats } } } }"#,
|
||||
fragments: [CopilotChatHistory.self, CopilotChatMessage.self, PaginatedCopilotChats.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var pagination: PaginationInput
|
||||
public var docId: GraphQLNullable<String>
|
||||
public var options: GraphQLNullable<QueryChatSessionsInput>
|
||||
public var options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
pagination: PaginationInput,
|
||||
docId: GraphQLNullable<String>,
|
||||
options: GraphQLNullable<QueryChatSessionsInput>
|
||||
options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.pagination = pagination
|
||||
self.docId = docId
|
||||
self.options = options
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"pagination": pagination,
|
||||
"docId": docId,
|
||||
"options": options
|
||||
] }
|
||||
@@ -67,41 +72,41 @@ public class GetCopilotSessionsQuery: GraphQLQuery {
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("sessions", [Session].self, arguments: [
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": .variable("pagination"),
|
||||
"docId": .variable("docId"),
|
||||
"options": .variable("options")
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Get the session list in the workspace
|
||||
public var sessions: [Session] { __data["sessions"] }
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.Session
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `CopilotSessionType`
|
||||
public struct Session: AffineGraphQL.SelectionSet {
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CopilotSessionType }
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("parentSessionId", AffineGraphQL.ID?.self),
|
||||
.field("docId", String?.self),
|
||||
.field("pinned", Bool.self),
|
||||
.field("promptName", String.self),
|
||||
.field("model", String.self),
|
||||
.field("optionalModels", [String].self),
|
||||
.fragment(PaginatedCopilotChats.self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var parentSessionId: AffineGraphQL.ID? { __data["parentSessionId"] }
|
||||
public var docId: String? { __data["docId"] }
|
||||
public var pinned: Bool { __data["pinned"] }
|
||||
public var promptName: String { __data["promptName"] }
|
||||
public var model: String { __data["model"] }
|
||||
public var optionalModels: [String] { __data["optionalModels"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var paginatedCopilotChats: PaginatedCopilotChats { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias PageInfo = PaginatedCopilotChats.PageInfo
|
||||
|
||||
public typealias Edge = PaginatedCopilotChats.Edge
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class GetCopilotWorkspaceSessionsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getCopilotWorkspaceSessions"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getCopilotWorkspaceSessions($workspaceId: String!, $pagination: PaginationInput!, $options: QueryChatHistoriesInput) { currentUser { __typename copilot(workspaceId: $workspaceId) { __typename chats(pagination: $pagination, docId: null, options: $options) { __typename ...PaginatedCopilotChats } } } }"#,
|
||||
fragments: [CopilotChatHistory.self, CopilotChatMessage.self, PaginatedCopilotChats.self]
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var pagination: PaginationInput
|
||||
public var options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
pagination: PaginationInput,
|
||||
options: GraphQLNullable<QueryChatHistoriesInput>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.pagination = pagination
|
||||
self.options = options
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"pagination": pagination,
|
||||
"options": options
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("currentUser", CurrentUser?.self),
|
||||
] }
|
||||
|
||||
/// Get current user
|
||||
public var currentUser: CurrentUser? { __data["currentUser"] }
|
||||
|
||||
/// CurrentUser
|
||||
///
|
||||
/// Parent Type: `UserType`
|
||||
public struct CurrentUser: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.UserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("copilot", Copilot.self, arguments: ["workspaceId": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
public var copilot: Copilot { __data["copilot"] }
|
||||
|
||||
/// CurrentUser.Copilot
|
||||
///
|
||||
/// Parent Type: `Copilot`
|
||||
public struct Copilot: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Copilot }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("chats", Chats.self, arguments: [
|
||||
"pagination": .variable("pagination"),
|
||||
"docId": .null,
|
||||
"options": .variable("options")
|
||||
]),
|
||||
] }
|
||||
|
||||
public var chats: Chats { __data["chats"] }
|
||||
|
||||
/// CurrentUser.Copilot.Chats
|
||||
///
|
||||
/// Parent Type: `PaginatedCopilotHistoriesType`
|
||||
public struct Chats: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCopilotHistoriesType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.fragment(PaginatedCopilotChats.self),
|
||||
] }
|
||||
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
|
||||
public struct Fragments: FragmentContainer {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public var paginatedCopilotChats: PaginatedCopilotChats { _toFragment() }
|
||||
}
|
||||
|
||||
public typealias PageInfo = PaginatedCopilotChats.PageInfo
|
||||
|
||||
public typealias Edge = PaginatedCopilotChats.Edge
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ public class GetDocRolePermissionsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getDocRolePermissions"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getDocRolePermissions($workspaceId: String!, $docId: String!) { workspace(id: $workspaceId) { __typename doc(docId: $docId) { __typename permissions { __typename Doc_Copy Doc_Delete Doc_Duplicate Doc_Properties_Read Doc_Properties_Update Doc_Publish Doc_Read Doc_Restore Doc_TransferOwner Doc_Trash Doc_Update Doc_Users_Manage Doc_Users_Read } } } }"#
|
||||
#"query getDocRolePermissions($workspaceId: String!, $docId: String!) { workspace(id: $workspaceId) { __typename doc(docId: $docId) { __typename permissions { __typename Doc_Copy Doc_Delete Doc_Duplicate Doc_Properties_Read Doc_Properties_Update Doc_Publish Doc_Read Doc_Restore Doc_TransferOwner Doc_Trash Doc_Update Doc_Users_Manage Doc_Users_Read Doc_Comments_Create Doc_Comments_Delete Doc_Comments_Read Doc_Comments_Resolve } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
@@ -92,6 +92,10 @@ public class GetDocRolePermissionsQuery: GraphQLQuery {
|
||||
.field("Doc_Update", Bool.self),
|
||||
.field("Doc_Users_Manage", Bool.self),
|
||||
.field("Doc_Users_Read", Bool.self),
|
||||
.field("Doc_Comments_Create", Bool.self),
|
||||
.field("Doc_Comments_Delete", Bool.self),
|
||||
.field("Doc_Comments_Read", Bool.self),
|
||||
.field("Doc_Comments_Resolve", Bool.self),
|
||||
] }
|
||||
|
||||
public var doc_Copy: Bool { __data["Doc_Copy"] }
|
||||
@@ -107,6 +111,10 @@ public class GetDocRolePermissionsQuery: GraphQLQuery {
|
||||
public var doc_Update: Bool { __data["Doc_Update"] }
|
||||
public var doc_Users_Manage: Bool { __data["Doc_Users_Manage"] }
|
||||
public var doc_Users_Read: Bool { __data["Doc_Users_Read"] }
|
||||
public var doc_Comments_Create: Bool { __data["Doc_Comments_Create"] }
|
||||
public var doc_Comments_Delete: Bool { __data["Doc_Comments_Delete"] }
|
||||
public var doc_Comments_Read: Bool { __data["Doc_Comments_Read"] }
|
||||
public var doc_Comments_Resolve: Bool { __data["Doc_Comments_Resolve"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ public class GetUserSettingsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "getUserSettings"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query getUserSettings { currentUser { __typename settings { __typename receiveInvitationEmail receiveMentionEmail } } }"#
|
||||
#"query getUserSettings { currentUser { __typename settings { __typename receiveInvitationEmail receiveMentionEmail receiveCommentEmail } } }"#
|
||||
))
|
||||
|
||||
public init() {}
|
||||
@@ -52,12 +52,15 @@ public class GetUserSettingsQuery: GraphQLQuery {
|
||||
.field("__typename", String.self),
|
||||
.field("receiveInvitationEmail", Bool.self),
|
||||
.field("receiveMentionEmail", Bool.self),
|
||||
.field("receiveCommentEmail", Bool.self),
|
||||
] }
|
||||
|
||||
/// Receive invitation email
|
||||
public var receiveInvitationEmail: Bool { __data["receiveInvitationEmail"] }
|
||||
/// Receive mention email
|
||||
public var receiveMentionEmail: Bool { __data["receiveMentionEmail"] }
|
||||
/// Receive comment email
|
||||
public var receiveCommentEmail: Bool { __data["receiveCommentEmail"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class ListCommentChangesQuery: GraphQLQuery {
|
||||
public static let operationName: String = "listCommentChanges"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query listCommentChanges($workspaceId: String!, $docId: String!, $pagination: PaginationInput!) { workspace(id: $workspaceId) { __typename commentChanges(docId: $docId, pagination: $pagination) { __typename totalCount edges { __typename cursor node { __typename action id commentId item } } pageInfo { __typename startCursor endCursor hasNextPage hasPreviousPage } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var docId: String
|
||||
public var pagination: PaginationInput
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
docId: String,
|
||||
pagination: PaginationInput
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.docId = docId
|
||||
self.pagination = pagination
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"docId": docId,
|
||||
"pagination": pagination
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
/// Workspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct Workspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("commentChanges", CommentChanges.self, arguments: [
|
||||
"docId": .variable("docId"),
|
||||
"pagination": .variable("pagination")
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Get comment changes of a doc
|
||||
public var commentChanges: CommentChanges { __data["commentChanges"] }
|
||||
|
||||
/// Workspace.CommentChanges
|
||||
///
|
||||
/// Parent Type: `PaginatedCommentChangeObjectType`
|
||||
public struct CommentChanges: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCommentChangeObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("totalCount", Int.self),
|
||||
.field("edges", [Edge].self),
|
||||
.field("pageInfo", PageInfo.self),
|
||||
] }
|
||||
|
||||
public var totalCount: Int { __data["totalCount"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
|
||||
/// Workspace.CommentChanges.Edge
|
||||
///
|
||||
/// Parent Type: `CommentChangeObjectTypeEdge`
|
||||
public struct Edge: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CommentChangeObjectTypeEdge }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("cursor", String.self),
|
||||
.field("node", Node.self),
|
||||
] }
|
||||
|
||||
public var cursor: String { __data["cursor"] }
|
||||
public var node: Node { __data["node"] }
|
||||
|
||||
/// Workspace.CommentChanges.Edge.Node
|
||||
///
|
||||
/// Parent Type: `CommentChangeObjectType`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CommentChangeObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("action", GraphQLEnum<AffineGraphQL.CommentChangeAction>.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("commentId", AffineGraphQL.ID?.self),
|
||||
.field("item", AffineGraphQL.JSONObject.self),
|
||||
] }
|
||||
|
||||
/// The action of the comment change
|
||||
public var action: GraphQLEnum<AffineGraphQL.CommentChangeAction> { __data["action"] }
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
public var commentId: AffineGraphQL.ID? { __data["commentId"] }
|
||||
/// The item of the comment or reply, different types have different fields, see UnionCommentObjectType
|
||||
public var item: AffineGraphQL.JSONObject { __data["item"] }
|
||||
}
|
||||
}
|
||||
|
||||
/// Workspace.CommentChanges.PageInfo
|
||||
///
|
||||
/// Parent Type: `PageInfo`
|
||||
public struct PageInfo: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PageInfo }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("startCursor", String?.self),
|
||||
.field("endCursor", String?.self),
|
||||
.field("hasNextPage", Bool.self),
|
||||
.field("hasPreviousPage", Bool.self),
|
||||
] }
|
||||
|
||||
public var startCursor: String? { __data["startCursor"] }
|
||||
public var endCursor: String? { __data["endCursor"] }
|
||||
public var hasNextPage: Bool { __data["hasNextPage"] }
|
||||
public var hasPreviousPage: Bool { __data["hasPreviousPage"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
@_exported import ApolloAPI
|
||||
|
||||
public class ListCommentsQuery: GraphQLQuery {
|
||||
public static let operationName: String = "listComments"
|
||||
public static let operationDocument: ApolloAPI.OperationDocument = .init(
|
||||
definition: .init(
|
||||
#"query listComments($workspaceId: String!, $docId: String!, $pagination: PaginationInput) { workspace(id: $workspaceId) { __typename comments(docId: $docId, pagination: $pagination) { __typename totalCount edges { __typename cursor node { __typename id content resolved createdAt updatedAt user { __typename id name avatarUrl } replies { __typename commentId id content createdAt updatedAt user { __typename id name avatarUrl } } } } pageInfo { __typename startCursor endCursor hasNextPage hasPreviousPage } } } }"#
|
||||
))
|
||||
|
||||
public var workspaceId: String
|
||||
public var docId: String
|
||||
public var pagination: GraphQLNullable<PaginationInput>
|
||||
|
||||
public init(
|
||||
workspaceId: String,
|
||||
docId: String,
|
||||
pagination: GraphQLNullable<PaginationInput>
|
||||
) {
|
||||
self.workspaceId = workspaceId
|
||||
self.docId = docId
|
||||
self.pagination = pagination
|
||||
}
|
||||
|
||||
public var __variables: Variables? { [
|
||||
"workspaceId": workspaceId,
|
||||
"docId": docId,
|
||||
"pagination": pagination
|
||||
] }
|
||||
|
||||
public struct Data: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.Query }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("workspace", Workspace.self, arguments: ["id": .variable("workspaceId")]),
|
||||
] }
|
||||
|
||||
/// Get workspace by id
|
||||
public var workspace: Workspace { __data["workspace"] }
|
||||
|
||||
/// Workspace
|
||||
///
|
||||
/// Parent Type: `WorkspaceType`
|
||||
public struct Workspace: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.WorkspaceType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("comments", Comments.self, arguments: [
|
||||
"docId": .variable("docId"),
|
||||
"pagination": .variable("pagination")
|
||||
]),
|
||||
] }
|
||||
|
||||
/// Get comments of a doc
|
||||
public var comments: Comments { __data["comments"] }
|
||||
|
||||
/// Workspace.Comments
|
||||
///
|
||||
/// Parent Type: `PaginatedCommentObjectType`
|
||||
public struct Comments: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PaginatedCommentObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("totalCount", Int.self),
|
||||
.field("edges", [Edge].self),
|
||||
.field("pageInfo", PageInfo.self),
|
||||
] }
|
||||
|
||||
public var totalCount: Int { __data["totalCount"] }
|
||||
public var edges: [Edge] { __data["edges"] }
|
||||
public var pageInfo: PageInfo { __data["pageInfo"] }
|
||||
|
||||
/// Workspace.Comments.Edge
|
||||
///
|
||||
/// Parent Type: `CommentObjectTypeEdge`
|
||||
public struct Edge: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CommentObjectTypeEdge }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("cursor", String.self),
|
||||
.field("node", Node.self),
|
||||
] }
|
||||
|
||||
public var cursor: String { __data["cursor"] }
|
||||
public var node: Node { __data["node"] }
|
||||
|
||||
/// Workspace.Comments.Edge.Node
|
||||
///
|
||||
/// Parent Type: `CommentObjectType`
|
||||
public struct Node: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.CommentObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("content", AffineGraphQL.JSONObject.self),
|
||||
.field("resolved", Bool.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("updatedAt", AffineGraphQL.DateTime.self),
|
||||
.field("user", User.self),
|
||||
.field("replies", [Reply].self),
|
||||
] }
|
||||
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
/// The content of the comment
|
||||
public var content: AffineGraphQL.JSONObject { __data["content"] }
|
||||
/// Whether the comment is resolved
|
||||
public var resolved: Bool { __data["resolved"] }
|
||||
/// The created at time of the comment
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
/// The updated at time of the comment
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
/// The user who created the comment
|
||||
public var user: User { __data["user"] }
|
||||
/// The replies of the comment
|
||||
public var replies: [Reply] { __data["replies"] }
|
||||
|
||||
/// Workspace.Comments.Edge.Node.User
|
||||
///
|
||||
/// Parent Type: `PublicUserType`
|
||||
public struct User: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PublicUserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", String.self),
|
||||
.field("name", String.self),
|
||||
.field("avatarUrl", String?.self),
|
||||
] }
|
||||
|
||||
public var id: String { __data["id"] }
|
||||
public var name: String { __data["name"] }
|
||||
public var avatarUrl: String? { __data["avatarUrl"] }
|
||||
}
|
||||
|
||||
/// Workspace.Comments.Edge.Node.Reply
|
||||
///
|
||||
/// Parent Type: `ReplyObjectType`
|
||||
public struct Reply: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.ReplyObjectType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("commentId", AffineGraphQL.ID.self),
|
||||
.field("id", AffineGraphQL.ID.self),
|
||||
.field("content", AffineGraphQL.JSONObject.self),
|
||||
.field("createdAt", AffineGraphQL.DateTime.self),
|
||||
.field("updatedAt", AffineGraphQL.DateTime.self),
|
||||
.field("user", User.self),
|
||||
] }
|
||||
|
||||
public var commentId: AffineGraphQL.ID { __data["commentId"] }
|
||||
public var id: AffineGraphQL.ID { __data["id"] }
|
||||
/// The content of the reply
|
||||
public var content: AffineGraphQL.JSONObject { __data["content"] }
|
||||
/// The created at time of the reply
|
||||
public var createdAt: AffineGraphQL.DateTime { __data["createdAt"] }
|
||||
/// The updated at time of the reply
|
||||
public var updatedAt: AffineGraphQL.DateTime { __data["updatedAt"] }
|
||||
/// The user who created the reply
|
||||
public var user: User { __data["user"] }
|
||||
|
||||
/// Workspace.Comments.Edge.Node.Reply.User
|
||||
///
|
||||
/// Parent Type: `PublicUserType`
|
||||
public struct User: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PublicUserType }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("id", String.self),
|
||||
.field("name", String.self),
|
||||
.field("avatarUrl", String?.self),
|
||||
] }
|
||||
|
||||
public var id: String { __data["id"] }
|
||||
public var name: String { __data["name"] }
|
||||
public var avatarUrl: String? { __data["avatarUrl"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Workspace.Comments.PageInfo
|
||||
///
|
||||
/// Parent Type: `PageInfo`
|
||||
public struct PageInfo: AffineGraphQL.SelectionSet {
|
||||
public let __data: DataDict
|
||||
public init(_dataDict: DataDict) { __data = _dataDict }
|
||||
|
||||
public static var __parentType: any ApolloAPI.ParentType { AffineGraphQL.Objects.PageInfo }
|
||||
public static var __selections: [ApolloAPI.Selection] { [
|
||||
.field("__typename", String.self),
|
||||
.field("startCursor", String?.self),
|
||||
.field("endCursor", String?.self),
|
||||
.field("hasNextPage", Bool.self),
|
||||
.field("hasPreviousPage", Bool.self),
|
||||
] }
|
||||
|
||||
public var startCursor: String? { __data["startCursor"] }
|
||||
public var endCursor: String? { __data["endCursor"] }
|
||||
public var hasNextPage: Bool { __data["hasNextPage"] }
|
||||
public var hasPreviousPage: Bool { __data["hasPreviousPage"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
/// Comment change action
|
||||
public enum CommentChangeAction: String, EnumType {
|
||||
case delete = "delete"
|
||||
case update = "update"
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import ApolloAPI
|
||||
|
||||
/// User permission in doc
|
||||
public enum DocRole: String, EnumType {
|
||||
case commenter = "Commenter"
|
||||
case editor = "Editor"
|
||||
case external = "External"
|
||||
case manager = "Manager"
|
||||
|
||||
@@ -5,6 +5,8 @@ import ApolloAPI
|
||||
|
||||
/// Notification type
|
||||
public enum NotificationType: String, EnumType {
|
||||
case comment = "Comment"
|
||||
case commentMention = "CommentMention"
|
||||
case invitation = "Invitation"
|
||||
case invitationAccepted = "InvitationAccepted"
|
||||
case invitationBlocked = "InvitationBlocked"
|
||||
|
||||
@@ -5,9 +5,11 @@ import ApolloAPI
|
||||
|
||||
public enum ServerFeature: String, EnumType {
|
||||
case captcha = "Captcha"
|
||||
case comment = "Comment"
|
||||
case copilot = "Copilot"
|
||||
case copilotEmbedding = "CopilotEmbedding"
|
||||
case indexer = "Indexer"
|
||||
case localWorkspace = "LocalWorkspace"
|
||||
case oAuth = "OAuth"
|
||||
case payment = "Payment"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ public struct AddContextFileInput: InputObject {
|
||||
}
|
||||
|
||||
public init(
|
||||
blobId: String,
|
||||
blobId: GraphQLNullable<String> = nil,
|
||||
contextId: String
|
||||
) {
|
||||
__data = InputDict([
|
||||
@@ -20,7 +20,7 @@ public struct AddContextFileInput: InputObject {
|
||||
])
|
||||
}
|
||||
|
||||
public var blobId: String {
|
||||
public var blobId: GraphQLNullable<String> {
|
||||
get { __data["blobId"] }
|
||||
set { __data["blobId"] = newValue }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public struct CommentCreateInput: InputObject {
|
||||
public private(set) var __data: InputDict
|
||||
|
||||
public init(_ data: InputDict) {
|
||||
__data = data
|
||||
}
|
||||
|
||||
public init(
|
||||
content: JSONObject,
|
||||
docId: ID,
|
||||
docMode: GraphQLEnum<DocMode>,
|
||||
docTitle: String,
|
||||
mentions: GraphQLNullable<[String]> = nil,
|
||||
workspaceId: ID
|
||||
) {
|
||||
__data = InputDict([
|
||||
"content": content,
|
||||
"docId": docId,
|
||||
"docMode": docMode,
|
||||
"docTitle": docTitle,
|
||||
"mentions": mentions,
|
||||
"workspaceId": workspaceId
|
||||
])
|
||||
}
|
||||
|
||||
public var content: JSONObject {
|
||||
get { __data["content"] }
|
||||
set { __data["content"] = newValue }
|
||||
}
|
||||
|
||||
public var docId: ID {
|
||||
get { __data["docId"] }
|
||||
set { __data["docId"] = newValue }
|
||||
}
|
||||
|
||||
public var docMode: GraphQLEnum<DocMode> {
|
||||
get { __data["docMode"] }
|
||||
set { __data["docMode"] = newValue }
|
||||
}
|
||||
|
||||
public var docTitle: String {
|
||||
get { __data["docTitle"] }
|
||||
set { __data["docTitle"] = newValue }
|
||||
}
|
||||
|
||||
/// The mention user ids, if not provided, the comment will not be mentioned
|
||||
public var mentions: GraphQLNullable<[String]> {
|
||||
get { __data["mentions"] }
|
||||
set { __data["mentions"] = newValue }
|
||||
}
|
||||
|
||||
public var workspaceId: ID {
|
||||
get { __data["workspaceId"] }
|
||||
set { __data["workspaceId"] = newValue }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public struct CommentResolveInput: InputObject {
|
||||
public private(set) var __data: InputDict
|
||||
|
||||
public init(_ data: InputDict) {
|
||||
__data = data
|
||||
}
|
||||
|
||||
public init(
|
||||
id: ID,
|
||||
resolved: Bool
|
||||
) {
|
||||
__data = InputDict([
|
||||
"id": id,
|
||||
"resolved": resolved
|
||||
])
|
||||
}
|
||||
|
||||
public var id: ID {
|
||||
get { __data["id"] }
|
||||
set { __data["id"] = newValue }
|
||||
}
|
||||
|
||||
/// Whether the comment is resolved
|
||||
public var resolved: Bool {
|
||||
get { __data["resolved"] }
|
||||
set { __data["resolved"] = newValue }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public struct CommentUpdateInput: InputObject {
|
||||
public private(set) var __data: InputDict
|
||||
|
||||
public init(_ data: InputDict) {
|
||||
__data = data
|
||||
}
|
||||
|
||||
public init(
|
||||
content: JSONObject,
|
||||
id: ID
|
||||
) {
|
||||
__data = InputDict([
|
||||
"content": content,
|
||||
"id": id
|
||||
])
|
||||
}
|
||||
|
||||
public var content: JSONObject {
|
||||
get { __data["content"] }
|
||||
set { __data["content"] = newValue }
|
||||
}
|
||||
|
||||
public var id: ID {
|
||||
get { __data["id"] }
|
||||
set { __data["id"] = newValue }
|
||||
}
|
||||
}
|
||||
@@ -14,12 +14,14 @@ public struct CreateChatSessionInput: InputObject {
|
||||
docId: GraphQLNullable<String> = nil,
|
||||
pinned: GraphQLNullable<Bool> = nil,
|
||||
promptName: String,
|
||||
reuseLatestChat: GraphQLNullable<Bool> = nil,
|
||||
workspaceId: String
|
||||
) {
|
||||
__data = InputDict([
|
||||
"docId": docId,
|
||||
"pinned": pinned,
|
||||
"promptName": promptName,
|
||||
"reuseLatestChat": reuseLatestChat,
|
||||
"workspaceId": workspaceId
|
||||
])
|
||||
}
|
||||
@@ -40,6 +42,12 @@ public struct CreateChatSessionInput: InputObject {
|
||||
set { __data["promptName"] = newValue }
|
||||
}
|
||||
|
||||
/// true by default, compliant for old version
|
||||
public var reuseLatestChat: GraphQLNullable<Bool> {
|
||||
get { __data["reuseLatestChat"] }
|
||||
set { __data["reuseLatestChat"] = newValue }
|
||||
}
|
||||
|
||||
public var workspaceId: String {
|
||||
get { __data["workspaceId"] }
|
||||
set { __data["workspaceId"] = newValue }
|
||||
|
||||
@@ -19,6 +19,7 @@ public struct QueryChatHistoriesInput: InputObject {
|
||||
sessionId: GraphQLNullable<String> = nil,
|
||||
sessionOrder: GraphQLNullable<GraphQLEnum<ChatHistoryOrder>> = nil,
|
||||
skip: GraphQLNullable<Int> = nil,
|
||||
withMessages: GraphQLNullable<Bool> = nil,
|
||||
withPrompt: GraphQLNullable<Bool> = nil
|
||||
) {
|
||||
__data = InputDict([
|
||||
@@ -30,6 +31,7 @@ public struct QueryChatHistoriesInput: InputObject {
|
||||
"sessionId": sessionId,
|
||||
"sessionOrder": sessionOrder,
|
||||
"skip": skip,
|
||||
"withMessages": withMessages,
|
||||
"withPrompt": withPrompt
|
||||
])
|
||||
}
|
||||
@@ -74,6 +76,11 @@ public struct QueryChatHistoriesInput: InputObject {
|
||||
set { __data["skip"] = newValue }
|
||||
}
|
||||
|
||||
public var withMessages: GraphQLNullable<Bool> {
|
||||
get { __data["withMessages"] }
|
||||
set { __data["withMessages"] = newValue }
|
||||
}
|
||||
|
||||
public var withPrompt: GraphQLNullable<Bool> {
|
||||
get { __data["withPrompt"] }
|
||||
set { __data["withPrompt"] = newValue }
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public struct QueryChatSessionsInput: InputObject {
|
||||
public private(set) var __data: InputDict
|
||||
|
||||
public init(_ data: InputDict) {
|
||||
__data = data
|
||||
}
|
||||
|
||||
public init(
|
||||
action: GraphQLNullable<Bool> = nil,
|
||||
fork: GraphQLNullable<Bool> = nil,
|
||||
limit: GraphQLNullable<Int> = nil,
|
||||
pinned: GraphQLNullable<Bool> = nil,
|
||||
skip: GraphQLNullable<Int> = nil
|
||||
) {
|
||||
__data = InputDict([
|
||||
"action": action,
|
||||
"fork": fork,
|
||||
"limit": limit,
|
||||
"pinned": pinned,
|
||||
"skip": skip
|
||||
])
|
||||
}
|
||||
|
||||
public var action: GraphQLNullable<Bool> {
|
||||
get { __data["action"] }
|
||||
set { __data["action"] = newValue }
|
||||
}
|
||||
|
||||
public var fork: GraphQLNullable<Bool> {
|
||||
get { __data["fork"] }
|
||||
set { __data["fork"] = newValue }
|
||||
}
|
||||
|
||||
public var limit: GraphQLNullable<Int> {
|
||||
get { __data["limit"] }
|
||||
set { __data["limit"] = newValue }
|
||||
}
|
||||
|
||||
public var pinned: GraphQLNullable<Bool> {
|
||||
get { __data["pinned"] }
|
||||
set { __data["pinned"] = newValue }
|
||||
}
|
||||
|
||||
public var skip: GraphQLNullable<Int> {
|
||||
get { __data["skip"] }
|
||||
set { __data["skip"] = newValue }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public struct ReplyCreateInput: InputObject {
|
||||
public private(set) var __data: InputDict
|
||||
|
||||
public init(_ data: InputDict) {
|
||||
__data = data
|
||||
}
|
||||
|
||||
public init(
|
||||
commentId: ID,
|
||||
content: JSONObject,
|
||||
docMode: GraphQLEnum<DocMode>,
|
||||
docTitle: String,
|
||||
mentions: GraphQLNullable<[String]> = nil
|
||||
) {
|
||||
__data = InputDict([
|
||||
"commentId": commentId,
|
||||
"content": content,
|
||||
"docMode": docMode,
|
||||
"docTitle": docTitle,
|
||||
"mentions": mentions
|
||||
])
|
||||
}
|
||||
|
||||
public var commentId: ID {
|
||||
get { __data["commentId"] }
|
||||
set { __data["commentId"] = newValue }
|
||||
}
|
||||
|
||||
public var content: JSONObject {
|
||||
get { __data["content"] }
|
||||
set { __data["content"] = newValue }
|
||||
}
|
||||
|
||||
public var docMode: GraphQLEnum<DocMode> {
|
||||
get { __data["docMode"] }
|
||||
set { __data["docMode"] = newValue }
|
||||
}
|
||||
|
||||
public var docTitle: String {
|
||||
get { __data["docTitle"] }
|
||||
set { __data["docTitle"] = newValue }
|
||||
}
|
||||
|
||||
/// The mention user ids, if not provided, the comment reply will not be mentioned
|
||||
public var mentions: GraphQLNullable<[String]> {
|
||||
get { __data["mentions"] }
|
||||
set { __data["mentions"] = newValue }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public struct ReplyUpdateInput: InputObject {
|
||||
public private(set) var __data: InputDict
|
||||
|
||||
public init(_ data: InputDict) {
|
||||
__data = data
|
||||
}
|
||||
|
||||
public init(
|
||||
content: JSONObject,
|
||||
id: ID
|
||||
) {
|
||||
__data = InputDict([
|
||||
"content": content,
|
||||
"id": id
|
||||
])
|
||||
}
|
||||
|
||||
public var content: JSONObject {
|
||||
get { __data["content"] }
|
||||
set { __data["content"] = newValue }
|
||||
}
|
||||
|
||||
public var id: ID {
|
||||
get { __data["id"] }
|
||||
set { __data["id"] = newValue }
|
||||
}
|
||||
}
|
||||
@@ -11,15 +11,23 @@ public struct UpdateUserSettingsInput: InputObject {
|
||||
}
|
||||
|
||||
public init(
|
||||
receiveCommentEmail: GraphQLNullable<Bool> = nil,
|
||||
receiveInvitationEmail: GraphQLNullable<Bool> = nil,
|
||||
receiveMentionEmail: GraphQLNullable<Bool> = nil
|
||||
) {
|
||||
__data = InputDict([
|
||||
"receiveCommentEmail": receiveCommentEmail,
|
||||
"receiveInvitationEmail": receiveInvitationEmail,
|
||||
"receiveMentionEmail": receiveMentionEmail
|
||||
])
|
||||
}
|
||||
|
||||
/// Receive comment email
|
||||
public var receiveCommentEmail: GraphQLNullable<Bool> {
|
||||
get { __data["receiveCommentEmail"] }
|
||||
set { __data["receiveCommentEmail"] = newValue }
|
||||
}
|
||||
|
||||
/// Receive invitation email
|
||||
public var receiveInvitationEmail: GraphQLNullable<Bool> {
|
||||
get { __data["receiveInvitationEmail"] }
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let CommentChangeObjectType = ApolloAPI.Object(
|
||||
typename: "CommentChangeObjectType",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let CommentChangeObjectTypeEdge = ApolloAPI.Object(
|
||||
typename: "CommentChangeObjectTypeEdge",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
}
|
||||
@@ -4,8 +4,8 @@
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let CopilotSessionType = ApolloAPI.Object(
|
||||
typename: "CopilotSessionType",
|
||||
static let CommentObjectType = ApolloAPI.Object(
|
||||
typename: "CommentObjectType",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let CommentObjectTypeEdge = ApolloAPI.Object(
|
||||
typename: "CommentObjectTypeEdge",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let CopilotHistoriesTypeEdge = ApolloAPI.Object(
|
||||
typename: "CopilotHistoriesTypeEdge",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let PaginatedCommentChangeObjectType = ApolloAPI.Object(
|
||||
typename: "PaginatedCommentChangeObjectType",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let PaginatedCommentObjectType = ApolloAPI.Object(
|
||||
typename: "PaginatedCommentObjectType",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let PaginatedCopilotHistoriesType = ApolloAPI.Object(
|
||||
typename: "PaginatedCopilotHistoriesType",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @generated
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import ApolloAPI
|
||||
|
||||
public extension Objects {
|
||||
static let ReplyObjectType = ApolloAPI.Object(
|
||||
typename: "ReplyObjectType",
|
||||
implementedInterfaces: [],
|
||||
keyFields: nil
|
||||
)
|
||||
}
|
||||
@@ -25,6 +25,10 @@ public enum SchemaMetadata: ApolloAPI.SchemaMetadata {
|
||||
case "AggregateResultObjectType": return AffineGraphQL.Objects.AggregateResultObjectType
|
||||
case "AppConfigValidateResult": return AffineGraphQL.Objects.AppConfigValidateResult
|
||||
case "ChatMessage": return AffineGraphQL.Objects.ChatMessage
|
||||
case "CommentChangeObjectType": return AffineGraphQL.Objects.CommentChangeObjectType
|
||||
case "CommentChangeObjectTypeEdge": return AffineGraphQL.Objects.CommentChangeObjectTypeEdge
|
||||
case "CommentObjectType": return AffineGraphQL.Objects.CommentObjectType
|
||||
case "CommentObjectTypeEdge": return AffineGraphQL.Objects.CommentObjectTypeEdge
|
||||
case "ContextMatchedDocChunk": return AffineGraphQL.Objects.ContextMatchedDocChunk
|
||||
case "ContextMatchedFileChunk": return AffineGraphQL.Objects.ContextMatchedFileChunk
|
||||
case "ContextWorkspaceEmbeddingStatus": return AffineGraphQL.Objects.ContextWorkspaceEmbeddingStatus
|
||||
@@ -35,11 +39,11 @@ public enum SchemaMetadata: ApolloAPI.SchemaMetadata {
|
||||
case "CopilotContextFile": return AffineGraphQL.Objects.CopilotContextFile
|
||||
case "CopilotDocType": return AffineGraphQL.Objects.CopilotDocType
|
||||
case "CopilotHistories": return AffineGraphQL.Objects.CopilotHistories
|
||||
case "CopilotHistoriesTypeEdge": return AffineGraphQL.Objects.CopilotHistoriesTypeEdge
|
||||
case "CopilotPromptConfigType": return AffineGraphQL.Objects.CopilotPromptConfigType
|
||||
case "CopilotPromptMessageType": return AffineGraphQL.Objects.CopilotPromptMessageType
|
||||
case "CopilotPromptType": return AffineGraphQL.Objects.CopilotPromptType
|
||||
case "CopilotQuota": return AffineGraphQL.Objects.CopilotQuota
|
||||
case "CopilotSessionType": return AffineGraphQL.Objects.CopilotSessionType
|
||||
case "CopilotWorkspaceConfig": return AffineGraphQL.Objects.CopilotWorkspaceConfig
|
||||
case "CopilotWorkspaceFile": return AffineGraphQL.Objects.CopilotWorkspaceFile
|
||||
case "CopilotWorkspaceFileTypeEdge": return AffineGraphQL.Objects.CopilotWorkspaceFileTypeEdge
|
||||
@@ -67,6 +71,9 @@ public enum SchemaMetadata: ApolloAPI.SchemaMetadata {
|
||||
case "NotificationObjectType": return AffineGraphQL.Objects.NotificationObjectType
|
||||
case "NotificationObjectTypeEdge": return AffineGraphQL.Objects.NotificationObjectTypeEdge
|
||||
case "PageInfo": return AffineGraphQL.Objects.PageInfo
|
||||
case "PaginatedCommentChangeObjectType": return AffineGraphQL.Objects.PaginatedCommentChangeObjectType
|
||||
case "PaginatedCommentObjectType": return AffineGraphQL.Objects.PaginatedCommentObjectType
|
||||
case "PaginatedCopilotHistoriesType": return AffineGraphQL.Objects.PaginatedCopilotHistoriesType
|
||||
case "PaginatedCopilotWorkspaceFileType": return AffineGraphQL.Objects.PaginatedCopilotWorkspaceFileType
|
||||
case "PaginatedDocType": return AffineGraphQL.Objects.PaginatedDocType
|
||||
case "PaginatedGrantedDocUserType": return AffineGraphQL.Objects.PaginatedGrantedDocUserType
|
||||
@@ -77,6 +84,7 @@ public enum SchemaMetadata: ApolloAPI.SchemaMetadata {
|
||||
case "Query": return AffineGraphQL.Objects.Query
|
||||
case "ReleaseVersionType": return AffineGraphQL.Objects.ReleaseVersionType
|
||||
case "RemoveAvatar": return AffineGraphQL.Objects.RemoveAvatar
|
||||
case "ReplyObjectType": return AffineGraphQL.Objects.ReplyObjectType
|
||||
case "SearchDocObjectType": return AffineGraphQL.Objects.SearchDocObjectType
|
||||
case "SearchNodeObjectType": return AffineGraphQL.Objects.SearchNodeObjectType
|
||||
case "SearchResultObjectType": return AffineGraphQL.Objects.SearchResultObjectType
|
||||
|
||||
@@ -33,7 +33,7 @@ extension ChatManager {
|
||||
append(sessionId: sessionId, UserMessageCellViewModel(
|
||||
id: .init(),
|
||||
content: inputBoxData.text,
|
||||
timestamp: .init(),
|
||||
timestamp: .init()
|
||||
))
|
||||
append(sessionId: sessionId, UserHintCellViewModel(
|
||||
id: .init(),
|
||||
|
||||
@@ -55,7 +55,7 @@ class AssistantMessageCell: ChatBaseCell {
|
||||
)
|
||||
markdownViewForSizeCalculation.setMarkdown(
|
||||
vm.documentBlocks,
|
||||
renderedContent: vm.documentRenderedContent,
|
||||
renderedContent: vm.documentRenderedContent
|
||||
)
|
||||
let boundingSize = markdownViewForSizeCalculation.boundingSize(for: width)
|
||||
return ceil(boundingSize.height)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type {
|
||||
AddContextFileInput,
|
||||
ContextMatchedDocChunk,
|
||||
ContextMatchedFileChunk,
|
||||
ContextWorkspaceEmbeddingStatus,
|
||||
@@ -295,10 +296,7 @@ declare global {
|
||||
}) => Promise<boolean>;
|
||||
addContextFile: (
|
||||
file: File,
|
||||
options: {
|
||||
contextId: string;
|
||||
blobId: string;
|
||||
}
|
||||
options: AddContextFileInput
|
||||
) => Promise<CopilotContextFile>;
|
||||
removeContextFile: (options: {
|
||||
contextId: string;
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import type { TextRendererOptions } from '@affine/core/blocksuite/ai/components/text-renderer';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import {
|
||||
NotificationProvider,
|
||||
ThemeProvider,
|
||||
} from '@blocksuite/affine-shared/services';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
@@ -65,6 +69,7 @@ export class AIChatBlockMessage extends LitElement {
|
||||
}
|
||||
|
||||
private renderStreamObjects(answer: StreamObject[]) {
|
||||
const notificationService = this.host.std.get(NotificationProvider);
|
||||
return html`<chat-content-stream-objects
|
||||
.answer=${answer}
|
||||
.host=${this.host}
|
||||
@@ -72,17 +77,19 @@ export class AIChatBlockMessage extends LitElement {
|
||||
.extensions=${this.textRendererOptions.extensions}
|
||||
.affineFeatureFlagService=${this.textRendererOptions
|
||||
.affineFeatureFlagService}
|
||||
.notificationService=${notificationService}
|
||||
.theme=${this.host.std.get(ThemeProvider).app$}
|
||||
></chat-content-stream-objects>`;
|
||||
}
|
||||
|
||||
private renderRichText(text: string) {
|
||||
return html`<chat-content-rich-text
|
||||
.host=${this.host}
|
||||
.text=${text}
|
||||
.state=${this.state}
|
||||
.extensions=${this.textRendererOptions.extensions}
|
||||
.affineFeatureFlagService=${this.textRendererOptions
|
||||
.affineFeatureFlagService}
|
||||
.theme=${this.host.std.get(ThemeProvider).app$}
|
||||
></chat-content-rich-text>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
ArrowDownBigIcon as ArrowDownIcon,
|
||||
ArrowUpBigIcon as ArrowUpIcon,
|
||||
@@ -163,16 +164,18 @@ export class ActionWrapper extends WithDisposable(LitElement) {
|
||||
></chat-content-images>`
|
||||
: nothing}
|
||||
${answer
|
||||
? createTextRenderer(this.host, {
|
||||
? createTextRenderer({
|
||||
customHeading: true,
|
||||
testId: 'chat-message-action-answer',
|
||||
theme: this.host.std.get(ThemeProvider).app$,
|
||||
})(answer)
|
||||
: nothing}
|
||||
${originalText
|
||||
? html`<div class="subtitle prompt">Prompt</div>
|
||||
${createTextRenderer(this.host, {
|
||||
${createTextRenderer({
|
||||
customHeading: true,
|
||||
testId: 'chat-message-action-prompt',
|
||||
theme: this.host.std.get(ThemeProvider).app$,
|
||||
})(item.messages[0].content + originalText)}`
|
||||
: nothing}
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import './action-wrapper';
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { unsafeCSSVar } from '@blocksuite/affine/shared/theme';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import { ThemeProvider } from '@blocksuite/affine-shared/services';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
@@ -57,8 +58,9 @@ export class ActionText extends WithDisposable(LitElement) {
|
||||
class="original-text"
|
||||
data-testid="original-text"
|
||||
>
|
||||
${createTextRenderer(this.host, {
|
||||
${createTextRenderer({
|
||||
customHeading: true,
|
||||
theme: this.host.std.get(ThemeProvider).app$,
|
||||
})(originalText)}
|
||||
</div>
|
||||
</action-wrapper>`;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
||||
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import type { AppThemeService } from '@affine/core/modules/theme';
|
||||
import type { WorkbenchService } from '@affine/core/modules/workbench';
|
||||
import type {
|
||||
ContextEmbedStatus,
|
||||
@@ -7,7 +8,7 @@ import type {
|
||||
UpdateChatSessionInput,
|
||||
} from '@affine/graphql';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { NotificationProvider } from '@blocksuite/affine/shared/services';
|
||||
import { type NotificationService } from '@blocksuite/affine/shared/services';
|
||||
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
@@ -125,6 +126,12 @@ export class ChatPanel extends SignalWatcher(
|
||||
@property({ attribute: false })
|
||||
accessor affineWorkbenchService!: WorkbenchService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor affineThemeService!: AppThemeService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@state()
|
||||
accessor session: CopilotChatHistoryFragment | null | undefined;
|
||||
|
||||
@@ -144,7 +151,6 @@ export class ChatPanel extends SignalWatcher(
|
||||
private get chatTitle() {
|
||||
const [done, total] = this.embeddingProgress;
|
||||
const isEmbedding = total > 0 && done < total;
|
||||
const notification = this.host.std.getOptional(NotificationProvider);
|
||||
|
||||
return html`
|
||||
<div class="chat-panel-title-text">
|
||||
@@ -170,7 +176,7 @@ export class ChatPanel extends SignalWatcher(
|
||||
.onOpenSession=${this.openSession}
|
||||
.onOpenDoc=${this.openDoc}
|
||||
.docDisplayConfig=${this.docDisplayConfig}
|
||||
.notification=${notification}
|
||||
.notificationService=${this.notificationService}
|
||||
></ai-chat-toolbar>
|
||||
`;
|
||||
}
|
||||
@@ -371,6 +377,8 @@ export class ChatPanel extends SignalWatcher(
|
||||
.docDisplayConfig=${this.docDisplayConfig}
|
||||
.extensions=${this.extensions}
|
||||
.affineFeatureFlagService=${this.affineFeatureFlagService}
|
||||
.affineThemeService=${this.affineThemeService}
|
||||
.notificationService=${this.notificationService}
|
||||
></playground-content>
|
||||
`;
|
||||
|
||||
@@ -444,6 +452,8 @@ export class ChatPanel extends SignalWatcher(
|
||||
.extensions=${this.extensions}
|
||||
.affineFeatureFlagService=${this.affineFeatureFlagService}
|
||||
.affineWorkspaceDialogService=${this.affineWorkspaceDialogService}
|
||||
.affineThemeService=${this.affineThemeService}
|
||||
.notificationService=${this.notificationService}
|
||||
.onEmbeddingProgressChange=${this.onEmbeddingProgressChange}
|
||||
.onContextChange=${this.onContextChange}
|
||||
.width=${this.sidebarWidth}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import type { AppThemeService } from '@affine/core/modules/theme';
|
||||
import type { CopilotChatHistoryFragment } from '@affine/graphql';
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { isInsidePageEditor } from '@blocksuite/affine/shared/utils';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import type { ExtensionType } from '@blocksuite/affine/store';
|
||||
import type { NotificationService } from '@blocksuite/affine-shared/services';
|
||||
import type { Signal } from '@preact/signals-core';
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
@@ -35,9 +37,6 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
accessor host: EditorHost | null | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor docId: string | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor item!: ChatMessage;
|
||||
|
||||
@@ -56,6 +55,9 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
accessor affineFeatureFlagService!: FeatureFlagService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor affineThemeService!: AppThemeService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor session!: CopilotChatHistoryFragment | null | undefined;
|
||||
|
||||
@@ -68,6 +70,9 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
accessor width: Signal<number | undefined> | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
get state() {
|
||||
const { isLast, status } = this;
|
||||
return isLast
|
||||
@@ -118,27 +123,29 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
|
||||
|
||||
private renderStreamObjects(answer: StreamObject[]) {
|
||||
return html`<chat-content-stream-objects
|
||||
.answer=${answer}
|
||||
.host=${this.host}
|
||||
.answer=${answer}
|
||||
.state=${this.state}
|
||||
.width=${this.width}
|
||||
.extensions=${this.extensions}
|
||||
.affineFeatureFlagService=${this.affineFeatureFlagService}
|
||||
.notificationService=${this.notificationService}
|
||||
.theme=${this.affineThemeService.appTheme.themeSignal}
|
||||
></chat-content-stream-objects>`;
|
||||
}
|
||||
|
||||
private renderRichText(text: string) {
|
||||
return html`<chat-content-rich-text
|
||||
.host=${this.host}
|
||||
.text=${text}
|
||||
.state=${this.state}
|
||||
.extensions=${this.extensions}
|
||||
.affineFeatureFlagService=${this.affineFeatureFlagService}
|
||||
.theme=${this.affineThemeService.appTheme.themeSignal}
|
||||
></chat-content-rich-text>`;
|
||||
}
|
||||
|
||||
private renderEditorActions() {
|
||||
const { item, isLast, status, host, session, docId } = this;
|
||||
const { item, isLast, status, host, session } = this;
|
||||
|
||||
if (!isChatMessage(item) || item.role !== 'assistant') return nothing;
|
||||
|
||||
@@ -161,7 +168,7 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
|
||||
: EdgelessEditorActions
|
||||
: null;
|
||||
|
||||
const showActions = host && docId && !!markdown;
|
||||
const showActions = host && !!markdown;
|
||||
|
||||
return html`
|
||||
<chat-copy-more
|
||||
@@ -173,6 +180,7 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
|
||||
.messageId=${messageId}
|
||||
.withMargin=${true}
|
||||
.retry=${() => this.retry()}
|
||||
.notificationService=${this.notificationService}
|
||||
></chat-copy-more>
|
||||
${isLast && showActions
|
||||
? html`<chat-action-list
|
||||
@@ -182,6 +190,7 @@ export class ChatMessageAssistant extends WithDisposable(ShadowlessElement) {
|
||||
.content=${markdown}
|
||||
.messageId=${messageId ?? undefined}
|
||||
.withMargin=${true}
|
||||
.notificationService=${this.notificationService}
|
||||
></chat-action-list>`
|
||||
: nothing}
|
||||
`;
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { TagMeta } from '@affine/core/components/page-list';
|
||||
import { createLitPortal } from '@blocksuite/affine/components/portal';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import { type EditorHost, ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { MoreVerticalIcon, PlusIcon } from '@blocksuite/icons/lit';
|
||||
import { flip, offset } from '@floating-ui/dom';
|
||||
import { computed, type Signal, signal } from '@preact/signals-core';
|
||||
@@ -82,9 +82,6 @@ export class ChatPanelChips extends SignalWatcher(
|
||||
|
||||
private _abortController: AbortController | null = null;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor host: EditorHost | null | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor chips!: ChatChip[];
|
||||
|
||||
@@ -167,7 +164,6 @@ export class ChatPanelChips extends SignalWatcher(
|
||||
.removeChip=${this._removeChip}
|
||||
.checkTokenLimit=${this._checkTokenLimit}
|
||||
.docDisplayConfig=${this.docDisplayConfig}
|
||||
.host=${this.host}
|
||||
></chat-panel-doc-chip>`;
|
||||
}
|
||||
if (isFileChip(chip)) {
|
||||
@@ -407,13 +403,8 @@ export class ChatPanelChips extends SignalWatcher(
|
||||
if (!contextId || !AIProvider.context) {
|
||||
throw new Error('Context not found');
|
||||
}
|
||||
if (!this.host) {
|
||||
throw new Error('Host not found');
|
||||
}
|
||||
const blobId = await this.host.store.blobSync.set(chip.file);
|
||||
const contextFile = await AIProvider.context.addContextFile(chip.file, {
|
||||
contextId,
|
||||
blobId,
|
||||
});
|
||||
this._updateChip(chip, {
|
||||
state: contextFile.status,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import track from '@affine/track';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { type EditorHost, ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { Signal } from '@preact/signals-core';
|
||||
import { html, type PropertyValues } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
@@ -36,9 +36,6 @@ export class ChatPanelDocChip extends SignalWatcher(
|
||||
@property({ attribute: false })
|
||||
accessor docDisplayConfig!: DocDisplayConfig;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor host: EditorHost | null | undefined;
|
||||
|
||||
private chipName = new Signal<string>('');
|
||||
|
||||
override connectedCallback() {
|
||||
@@ -103,9 +100,6 @@ export class ChatPanelDocChip extends SignalWatcher(
|
||||
};
|
||||
|
||||
private readonly processDocChip = async () => {
|
||||
if (!this.host) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const doc = this.docDisplayConfig.getDoc(this.chip.docId);
|
||||
if (!doc) {
|
||||
@@ -114,10 +108,7 @@ export class ChatPanelDocChip extends SignalWatcher(
|
||||
if (!doc.ready) {
|
||||
doc.load();
|
||||
}
|
||||
const value = await extractMarkdownFromDoc(
|
||||
doc,
|
||||
this.host.std.store.provider
|
||||
);
|
||||
const value = await extractMarkdownFromDoc(doc);
|
||||
const tokenCount = estimateTokenCount(value);
|
||||
if (this.checkTokenLimit(this.chip, tokenCount)) {
|
||||
const markdown = this.chip.markdown ?? new Signal<string>('');
|
||||
|
||||
@@ -120,7 +120,6 @@ export class AIChatComposer extends SignalWatcher(
|
||||
override render() {
|
||||
return html`
|
||||
<chat-panel-chips
|
||||
.host=${this.host}
|
||||
.chips=${this.chips}
|
||||
.createContextId=${this._createContextId}
|
||||
.updateChips=${this.updateChips}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
||||
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import type { AppThemeService } from '@affine/core/modules/theme';
|
||||
import type {
|
||||
ContextEmbedStatus,
|
||||
CopilotChatHistoryFragment,
|
||||
@@ -8,6 +9,7 @@ import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import type { ExtensionType } from '@blocksuite/affine/store';
|
||||
import type { NotificationService } from '@blocksuite/affine-shared/services';
|
||||
import { type Signal } from '@preact/signals-core';
|
||||
import {
|
||||
css,
|
||||
@@ -160,6 +162,12 @@ export class AIChatContent extends SignalWatcher(
|
||||
@property({ attribute: false })
|
||||
accessor affineWorkspaceDialogService!: WorkspaceDialogService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor affineThemeService!: AppThemeService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onEmbeddingProgressChange!: (
|
||||
count: Record<ContextEmbedStatus, number>
|
||||
@@ -401,6 +409,8 @@ export class AIChatContent extends SignalWatcher(
|
||||
.isHistoryLoading=${this.isHistoryLoading}
|
||||
.extensions=${this.extensions}
|
||||
.affineFeatureFlagService=${this.affineFeatureFlagService}
|
||||
.affineThemeService=${this.affineThemeService}
|
||||
.notificationService=${this.notificationService}
|
||||
.networkSearchConfig=${this.networkSearchConfig}
|
||||
.reasoningConfig=${this.reasoningConfig}
|
||||
.width=${this.width}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { AppThemeService } from '@affine/core/modules/theme';
|
||||
import type { CopilotChatHistoryFragment } from '@affine/graphql';
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import {
|
||||
DocModeProvider,
|
||||
FeatureFlagService,
|
||||
type FeatureFlagService,
|
||||
type NotificationService,
|
||||
} from '@blocksuite/affine/shared/services';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
@@ -187,6 +189,12 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
accessor affineFeatureFlagService!: FeatureFlagService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor affineThemeService!: AppThemeService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor networkSearchConfig!: AINetworkSearchConfig;
|
||||
|
||||
@@ -222,8 +230,7 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
|
||||
}
|
||||
|
||||
private _renderAIOnboarding() {
|
||||
return this.isHistoryLoading ||
|
||||
!this.host?.store.get(FeatureFlagService).getFlag('enable_ai_onboarding')
|
||||
return this.isHistoryLoading
|
||||
? nothing
|
||||
: html`<div class="onboarding-wrapper" data-testid="ai-onboarding">
|
||||
${repeat(
|
||||
@@ -311,7 +318,6 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
|
||||
} else if (isChatMessage(item) && item.role === 'assistant') {
|
||||
return html`<chat-message-assistant
|
||||
.host=${this.host}
|
||||
.docId=${this.docId}
|
||||
.session=${this.session}
|
||||
.item=${item}
|
||||
.isLast=${isLast}
|
||||
@@ -319,6 +325,8 @@ export class AIChatMessages extends WithDisposable(ShadowlessElement) {
|
||||
.error=${isLast ? error : null}
|
||||
.extensions=${this.extensions}
|
||||
.affineFeatureFlagService=${this.affineFeatureFlagService}
|
||||
.affineThemeService=${this.affineThemeService}
|
||||
.notificationService=${this.notificationService}
|
||||
.retry=${() => this.retry()}
|
||||
.width=${this.width}
|
||||
></chat-message-assistant>`;
|
||||
|
||||
@@ -42,7 +42,7 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
accessor docDisplayConfig!: DocDisplayConfig;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notification: NotificationService | null | undefined;
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@query('.history-button')
|
||||
accessor historyButton!: HTMLDivElement;
|
||||
@@ -104,21 +104,19 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
private readonly unpinConfirm = async () => {
|
||||
if (this.session && this.session.pinned) {
|
||||
try {
|
||||
const confirm = this.notification
|
||||
? await this.notification.confirm({
|
||||
title: 'Switch Chat? Current chat is pinned',
|
||||
message:
|
||||
'Switching will unpinned the current chat. This will change the active chat panel, allowing you to navigate between different conversation histories.',
|
||||
confirmText: 'Switch Chat',
|
||||
cancelText: 'Cancel',
|
||||
})
|
||||
: true;
|
||||
const confirm = await this.notificationService.confirm({
|
||||
title: 'Switch Chat? Current chat is pinned',
|
||||
message:
|
||||
'Switching will unpinned the current chat. This will change the active chat panel, allowing you to navigate between different conversation histories.',
|
||||
confirmText: 'Switch Chat',
|
||||
cancelText: 'Cancel',
|
||||
});
|
||||
if (!confirm) {
|
||||
return false;
|
||||
}
|
||||
await this.onTogglePin();
|
||||
} catch {
|
||||
this.notification?.toast('Failed to unpin the chat');
|
||||
this.notificationService.toast('Failed to unpin the chat');
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -133,7 +131,7 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
|
||||
private readonly onSessionClick = async (sessionId: string) => {
|
||||
if (this.session?.sessionId === sessionId) {
|
||||
this.notification?.toast('You are already in this chat');
|
||||
this.notificationService.toast('You are already in this chat');
|
||||
return;
|
||||
}
|
||||
const confirm = await this.unpinConfirm();
|
||||
@@ -144,7 +142,7 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
|
||||
private readonly onDocClick = async (docId: string, sessionId: string) => {
|
||||
if (this.docId === docId && this.session?.sessionId === sessionId) {
|
||||
this.notification?.toast('You are already in this chat');
|
||||
this.notificationService.toast('You are already in this chat');
|
||||
return;
|
||||
}
|
||||
this.onOpenDoc(docId, sessionId);
|
||||
@@ -169,7 +167,6 @@ export class AIChatToolbar extends WithDisposable(ShadowlessElement) {
|
||||
.docDisplayConfig=${this.docDisplayConfig}
|
||||
.onSessionClick=${this.onSessionClick}
|
||||
.onDocClick=${this.onDocClick}
|
||||
.notification=${this.notification}
|
||||
></ai-session-history>
|
||||
`,
|
||||
portalStyles: {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { CopilotSessionType } from '@affine/graphql';
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import type { NotificationService } from '@blocksuite/affine/shared/services';
|
||||
import { scrollbarStyle } from '@blocksuite/affine/shared/styles';
|
||||
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
@@ -134,9 +133,6 @@ export class AISessionHistory extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
accessor onDocClick!: (docId: string, sessionId: string) => void;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notification: NotificationService | null | undefined;
|
||||
|
||||
@state()
|
||||
private accessor sessions: BlockSuitePresets.AIRecentSession[] = [];
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ export class AIHistoryClear extends WithDisposable(ShadowlessElement) {
|
||||
accessor session!: CopilotChatHistoryFragment | null | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notification: NotificationService | null | undefined;
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor doc!: Store;
|
||||
@@ -52,15 +52,13 @@ export class AIHistoryClear extends WithDisposable(ShadowlessElement) {
|
||||
}
|
||||
const sessionId = this.session.sessionId;
|
||||
try {
|
||||
const confirm = this.notification
|
||||
? await this.notification.confirm({
|
||||
title: 'Clear History',
|
||||
message:
|
||||
'Are you sure you want to clear all history? This action will permanently delete all content, including all chat logs and data, and cannot be undone.',
|
||||
confirmText: 'Confirm',
|
||||
cancelText: 'Cancel',
|
||||
})
|
||||
: true;
|
||||
const confirm = await this.notificationService.confirm({
|
||||
title: 'Clear History',
|
||||
message:
|
||||
'Are you sure you want to clear all history? This action will permanently delete all content, including all chat logs and data, and cannot be undone.',
|
||||
confirmText: 'Confirm',
|
||||
cancelText: 'Cancel',
|
||||
});
|
||||
|
||||
if (confirm) {
|
||||
const actionIds = this.chatContextValue.messages
|
||||
@@ -71,11 +69,11 @@ export class AIHistoryClear extends WithDisposable(ShadowlessElement) {
|
||||
this.doc.id,
|
||||
[...(sessionId ? [sessionId] : []), ...(actionIds || [])]
|
||||
);
|
||||
this.notification?.toast('History cleared');
|
||||
this.notificationService.toast('History cleared');
|
||||
this.onHistoryCleared?.();
|
||||
}
|
||||
} catch {
|
||||
this.notification?.toast('Failed to clear history');
|
||||
this.notificationService.toast('Failed to clear history');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import type { ColorScheme } from '@blocksuite/affine/model';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import type { ExtensionType } from '@blocksuite/affine/store';
|
||||
import type { Signal } from '@preact/signals-core';
|
||||
import { html } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import { createTextRenderer } from '../../components/text-renderer';
|
||||
|
||||
export class ChatContentRichText extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
accessor host: EditorHost | null | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor text!: string;
|
||||
|
||||
@@ -24,12 +22,16 @@ export class ChatContentRichText extends WithDisposable(ShadowlessElement) {
|
||||
@property({ attribute: false })
|
||||
accessor affineFeatureFlagService!: FeatureFlagService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor theme!: Signal<ColorScheme>;
|
||||
|
||||
protected override render() {
|
||||
const { text, host } = this;
|
||||
return html`${createTextRenderer(host, {
|
||||
const { text } = this;
|
||||
return html`${createTextRenderer({
|
||||
customHeading: true,
|
||||
extensions: this.extensions,
|
||||
affineFeatureFlagService: this.affineFeatureFlagService,
|
||||
theme: this.theme,
|
||||
})(text, this.state)}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { ImageProxyService } from '@blocksuite/affine/shared/adapters';
|
||||
import type { EditorHost } from '@blocksuite/affine/std';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import type { ColorScheme } from '@blocksuite/affine/model';
|
||||
import { type EditorHost, ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import type { ExtensionType } from '@blocksuite/affine/store';
|
||||
import type { NotificationService } from '@blocksuite/affine-shared/services';
|
||||
import type { Signal } from '@preact/signals-core';
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import { BlockDiffProvider } from '../../services/block-diff';
|
||||
import type { AffineAIPanelState } from '../../widgets/ai-panel/type';
|
||||
import type { StreamObject } from '../ai-chat-messages';
|
||||
|
||||
@@ -42,12 +41,16 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
@property({ attribute: false })
|
||||
accessor affineFeatureFlagService!: FeatureFlagService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor theme!: Signal<ColorScheme>;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
private renderToolCall(streamObject: StreamObject) {
|
||||
if (streamObject.type !== 'tool-call') {
|
||||
return nothing;
|
||||
}
|
||||
const imageProxyService = this.host?.store.get(ImageProxyService);
|
||||
const blockDiffService = this.host?.view.std.getOptional(BlockDiffProvider);
|
||||
|
||||
switch (streamObject.toolName) {
|
||||
case 'web_crawl_exa':
|
||||
@@ -55,7 +58,6 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
<web-crawl-tool
|
||||
.data=${streamObject}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
></web-crawl-tool>
|
||||
`;
|
||||
case 'web_search_exa':
|
||||
@@ -63,7 +65,6 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
<web-search-tool
|
||||
.data=${streamObject}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
></web-search-tool>
|
||||
`;
|
||||
case 'doc_compose':
|
||||
@@ -72,7 +73,8 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
.std=${this.host?.std}
|
||||
.data=${streamObject}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
.theme=${this.theme}
|
||||
.notificationService=${this.notificationService}
|
||||
></doc-compose-tool>
|
||||
`;
|
||||
case 'code_artifact':
|
||||
@@ -81,7 +83,6 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
.std=${this.host?.std}
|
||||
.data=${streamObject}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
></code-artifact-tool>
|
||||
`;
|
||||
case 'doc_edit':
|
||||
@@ -89,7 +90,7 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
<doc-edit-tool
|
||||
.data=${streamObject}
|
||||
.doc=${this.host?.store}
|
||||
.blockDiffService=${blockDiffService}
|
||||
.notificationService=${this.notificationService}
|
||||
></doc-edit-tool>
|
||||
`;
|
||||
default: {
|
||||
@@ -105,8 +106,6 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
if (streamObject.type !== 'tool-result') {
|
||||
return nothing;
|
||||
}
|
||||
const imageProxyService = this.host?.store.get(ImageProxyService);
|
||||
const blockDiffService = this.host?.view.std.getOptional(BlockDiffProvider);
|
||||
|
||||
switch (streamObject.toolName) {
|
||||
case 'web_crawl_exa':
|
||||
@@ -114,7 +113,6 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
<web-crawl-tool
|
||||
.data=${streamObject}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
></web-crawl-tool>
|
||||
`;
|
||||
case 'web_search_exa':
|
||||
@@ -122,7 +120,6 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
<web-search-tool
|
||||
.data=${streamObject}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
></web-search-tool>
|
||||
`;
|
||||
case 'doc_compose':
|
||||
@@ -131,7 +128,8 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
.std=${this.host?.std}
|
||||
.data=${streamObject}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
.theme=${this.theme}
|
||||
.notificationService=${this.notificationService}
|
||||
></doc-compose-tool>
|
||||
`;
|
||||
case 'code_artifact':
|
||||
@@ -140,7 +138,8 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
.std=${this.host?.std}
|
||||
.data=${streamObject}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
.theme=${this.theme}
|
||||
.notificationService=${this.notificationService}
|
||||
></code-artifact-tool>
|
||||
`;
|
||||
case 'doc_edit':
|
||||
@@ -148,8 +147,8 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
<doc-edit-tool
|
||||
.data=${streamObject}
|
||||
.host=${this.host}
|
||||
.blockDiffService=${blockDiffService}
|
||||
.renderRichText=${this.renderRichText.bind(this)}
|
||||
.notificationService=${this.notificationService}
|
||||
></doc-edit-tool>
|
||||
`;
|
||||
default: {
|
||||
@@ -158,7 +157,6 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
<tool-result-card
|
||||
.name=${name}
|
||||
.width=${this.width}
|
||||
.imageProxyService=${imageProxyService}
|
||||
></tool-result-card>
|
||||
`;
|
||||
}
|
||||
@@ -167,11 +165,11 @@ export class ChatContentStreamObjects extends WithDisposable(
|
||||
|
||||
private renderRichText(text: string) {
|
||||
return html`<chat-content-rich-text
|
||||
.host=${this.host}
|
||||
.text=${text}
|
||||
.state=${this.state}
|
||||
.extensions=${this.extensions}
|
||||
.affineFeatureFlagService=${this.affineFeatureFlagService}
|
||||
.theme=${this.theme}
|
||||
></chat-content-rich-text>`;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ export class AIScrollableTextRenderer extends WithDisposable(
|
||||
}
|
||||
|
||||
override render() {
|
||||
const { host, answer, state, textRendererOptions } = this;
|
||||
const { answer, state, textRendererOptions } = this;
|
||||
|
||||
return html` <style>
|
||||
.ai-scrollable-text-renderer {
|
||||
@@ -71,7 +71,6 @@ export class AIScrollableTextRenderer extends WithDisposable(
|
||||
</style>
|
||||
<div class="ai-scrollable-text-renderer" @wheel=${this._onWheel}>
|
||||
<text-renderer
|
||||
.host=${host}
|
||||
.answer=${answer}
|
||||
.state=${state}
|
||||
.options=${textRendererOptions}
|
||||
@@ -83,7 +82,7 @@ export class AIScrollableTextRenderer extends WithDisposable(
|
||||
accessor answer!: string;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor host: EditorHost | null | undefined;
|
||||
accessor host!: EditorHost;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor state: AffineAIPanelState | undefined;
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
import { LoadingIcon } from '@blocksuite/affine/components/icons';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import type { ColorScheme } from '@blocksuite/affine/model';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { type NotificationService } from '@blocksuite/affine-shared/services';
|
||||
import type { Signal } from '@preact/signals-core';
|
||||
import {
|
||||
css,
|
||||
html,
|
||||
nothing,
|
||||
type PropertyValues,
|
||||
type TemplateResult,
|
||||
} from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import {
|
||||
isPreviewPanelOpen,
|
||||
renderPreviewPanel,
|
||||
} from './artifacts-preview-panel';
|
||||
|
||||
/**
|
||||
* Base web-component for AI artifact tools.
|
||||
* It encapsulates common reactive properties (data/std/width/…)
|
||||
* and automatically calls `updatePreviewPanel()` when the `data`
|
||||
* property changes while the preview panel is open.
|
||||
*/
|
||||
export abstract class ArtifactTool<
|
||||
TData extends { type: 'tool-result' | 'tool-call' },
|
||||
> extends SignalWatcher(WithDisposable(ShadowlessElement)) {
|
||||
static override styles = css`
|
||||
.artifact-tool-card {
|
||||
cursor: pointer;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.artifact-tool-card:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
`;
|
||||
|
||||
/** Tool data coming from ChatGPT (tool-call / tool-result). */
|
||||
@property({ attribute: false })
|
||||
accessor data!: TData;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor width: Signal<number | undefined> | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor theme!: Signal<ColorScheme>;
|
||||
|
||||
/* -------------------------- Card meta hooks -------------------------- */
|
||||
|
||||
/**
|
||||
* Sub-class must provide primary information for the card.
|
||||
*/
|
||||
protected abstract getCardMeta(): {
|
||||
title: string;
|
||||
/** Page / file icon shown when not loading */
|
||||
icon: TemplateResult | HTMLElement | string | null;
|
||||
/** Whether the spinner should be displayed */
|
||||
loading: boolean;
|
||||
/** Extra css class appended to card root */
|
||||
className?: string;
|
||||
};
|
||||
|
||||
/** Banner shown on the right side of the card (can be undefined). */
|
||||
protected abstract getBanner(
|
||||
theme: ColorScheme
|
||||
): TemplateResult | HTMLElement | string | null | undefined;
|
||||
|
||||
/**
|
||||
* Provide the main TemplateResult shown in the preview panel.
|
||||
* Called each time the panel opens or the tool data updates.
|
||||
*/
|
||||
protected abstract getPreviewContent(): TemplateResult<1>;
|
||||
|
||||
/** Provide the action controls (right-side buttons) for the panel. */
|
||||
protected getPreviewControls(): TemplateResult<1> | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Open or refresh the preview panel. */
|
||||
private openOrUpdatePreviewPanel() {
|
||||
renderPreviewPanel(
|
||||
this,
|
||||
this.getPreviewContent(),
|
||||
this.getPreviewControls()
|
||||
);
|
||||
}
|
||||
|
||||
protected refreshPreviewPanel() {
|
||||
if (isPreviewPanelOpen(this)) {
|
||||
this.openOrUpdatePreviewPanel();
|
||||
}
|
||||
}
|
||||
|
||||
/** Optionally override to show an error card. Return null if no error. */
|
||||
protected getErrorTemplate(): TemplateResult | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
private readonly onCardClick = (_e: Event) => {
|
||||
this.openOrUpdatePreviewPanel();
|
||||
};
|
||||
|
||||
protected renderCard() {
|
||||
const { title, icon, loading, className } = this.getCardMeta();
|
||||
|
||||
const resolvedIcon = loading
|
||||
? LoadingIcon({
|
||||
size: '20px',
|
||||
})
|
||||
: icon;
|
||||
|
||||
const banner = this.getBanner(this.theme.value);
|
||||
|
||||
return html`
|
||||
<div
|
||||
class="affine-embed-linked-doc-block artifact-tool-card ${className ??
|
||||
''} horizontal"
|
||||
@click=${this.onCardClick}
|
||||
>
|
||||
<div class="affine-embed-linked-doc-content">
|
||||
<div class="affine-embed-linked-doc-content-title">
|
||||
<div class="affine-embed-linked-doc-content-title-icon">
|
||||
${resolvedIcon}
|
||||
</div>
|
||||
<div class="affine-embed-linked-doc-content-title-text">
|
||||
${title}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${banner
|
||||
? html`<div class="affine-embed-linked-doc-banner">${banner}</div>`
|
||||
: nothing}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
override render() {
|
||||
const err = this.getErrorTemplate();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
return this.renderCard();
|
||||
}
|
||||
|
||||
override updated(changed: PropertyValues<this>) {
|
||||
super.updated(changed);
|
||||
if (changed.has('data') && isPreviewPanelOpen(this)) {
|
||||
this.openOrUpdatePreviewPanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
import { CodeBlockHighlighter } from '@blocksuite/affine/blocks/code';
|
||||
import { toast } from '@blocksuite/affine/components/toast';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import type { ImageProxyService } from '@blocksuite/affine/shared/adapters';
|
||||
import { ColorScheme } from '@blocksuite/affine/model';
|
||||
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import { type BlockStdScope, ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { CopyIcon, PageIcon, ToolIcon } from '@blocksuite/icons/lit';
|
||||
import { type BlockStdScope } from '@blocksuite/affine/std';
|
||||
import {
|
||||
CodeBlockIcon,
|
||||
CopyIcon,
|
||||
PageIcon,
|
||||
ToolIcon,
|
||||
} from '@blocksuite/icons/lit';
|
||||
import type { Signal } from '@preact/signals-core';
|
||||
import { effect, signal } from '@preact/signals-core';
|
||||
import { css, html, LitElement, nothing } from 'lit';
|
||||
@@ -12,7 +16,7 @@ import { property, state } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { bundledLanguagesInfo, type ThemedToken } from 'shiki';
|
||||
|
||||
import { renderPreviewPanel } from './artifacts-preview-panel';
|
||||
import { ArtifactTool } from './artifact-tool';
|
||||
import type { ToolError } from './type';
|
||||
|
||||
interface CodeArtifactToolCall {
|
||||
@@ -104,6 +108,8 @@ export class CodeHighlighter extends SignalWatcher(WithDisposable(LitElement)) {
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.highlighter.mounted();
|
||||
|
||||
// recompute highlight when code / language changes
|
||||
this.disposables.add(
|
||||
effect(() => {
|
||||
@@ -112,17 +118,25 @@ export class CodeHighlighter extends SignalWatcher(WithDisposable(LitElement)) {
|
||||
);
|
||||
}
|
||||
|
||||
override disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this.highlighter.unmounted();
|
||||
}
|
||||
|
||||
private _updateHighlightTokens() {
|
||||
let cancelled = false;
|
||||
const language = this.language;
|
||||
const highlighter = this.highlighter.highlighter$.value;
|
||||
|
||||
if (!highlighter) return;
|
||||
|
||||
const updateTokens = () => {
|
||||
if (cancelled) return;
|
||||
this.highlightTokens.value = highlighter.codeToTokensBase(this.code, {
|
||||
lang: language,
|
||||
theme: this.highlighter.themeKey,
|
||||
requestIdleCallback(() => {
|
||||
this.highlightTokens.value = highlighter.codeToTokensBase(this.code, {
|
||||
lang: language,
|
||||
theme: this.highlighter.themeKey,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -200,20 +214,143 @@ export class CodeHighlighter extends SignalWatcher(WithDisposable(LitElement)) {
|
||||
}
|
||||
}
|
||||
|
||||
const CodeBlockBanner = html`<svg
|
||||
width="204"
|
||||
height="102"
|
||||
viewBox="0 0 204 102"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_3371_100809)">
|
||||
<g filter="url(#filter0_d_3371_100809)">
|
||||
<rect
|
||||
x="53.5054"
|
||||
width="111.999"
|
||||
height="99.5543"
|
||||
rx="12.4443"
|
||||
transform="rotate(8.37805 53.5054 0)"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M89.7547 40.6581C90.8629 39.8345 92.4285 40.065 93.2522 41.1732C94.0758 42.2813 93.8452 43.847 92.7371 44.6706L79.7618 54.3146L89.4058 67.2899L89.5482 67.5024C90.1977 68.5905 89.9295 70.0161 88.8906 70.7883C87.8516 71.56 86.4104 71.4044 85.5558 70.4689L85.3932 70.2732L74.2581 55.2907C73.4345 54.1826 73.6653 52.617 74.7732 51.7933L89.7547 40.6581ZM114.378 44.2845C115.486 43.4608 117.052 43.6914 117.875 44.7996L129.011 59.7812C129.834 60.8892 129.604 62.4551 128.496 63.2787L113.514 74.4147L113.301 74.5552C112.213 75.2046 110.789 74.9382 110.016 73.8996C109.244 72.8606 109.399 71.4184 110.335 70.5637L110.531 70.4012L123.507 60.7572L113.863 47.7819C113.039 46.6738 113.27 45.1081 114.378 44.2845Z"
|
||||
fill="#F3F3F3"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_d_3371_100809"
|
||||
x="35.6787"
|
||||
y="-3.32129"
|
||||
width="131.951"
|
||||
height="121.453"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset />
|
||||
<feGaussianBlur stdDeviation="2.5" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0.258824 0 0 0 0 0.254902 0 0 0 0 0.286275 0 0 0 0.17 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3371_100809"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3371_100809"
|
||||
result="shape"
|
||||
/>
|
||||
</filter>
|
||||
<clipPath id="clip0_3371_100809">
|
||||
<rect width="204" height="102" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>`;
|
||||
|
||||
const CodeBlockBannerDark = html`<svg
|
||||
width="204"
|
||||
height="102"
|
||||
viewBox="0 0 204 102"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_3371_101118)">
|
||||
<g filter="url(#filter0_d_3371_101118)">
|
||||
<rect
|
||||
x="53.5055"
|
||||
width="111.999"
|
||||
height="99.5543"
|
||||
rx="12.4443"
|
||||
transform="rotate(8.37805 53.5055 0)"
|
||||
fill="#252525"
|
||||
/>
|
||||
</g>
|
||||
<path
|
||||
d="M89.7551 40.6574C90.8631 39.8342 92.429 40.0647 93.2525 41.1725C94.0762 42.2806 93.8455 43.8472 92.7373 44.6709L79.762 54.3149L89.406 67.2902L89.5475 67.5025C90.197 68.5907 89.9298 70.0163 88.8908 70.7886C87.8519 71.5603 86.4106 71.4047 85.5561 70.4692L85.3934 70.2735L74.2574 55.2908C73.4341 54.1829 73.6649 52.6171 74.7725 51.7934L89.7551 40.6574ZM114.378 44.2838C115.486 43.4606 117.052 43.6911 117.876 44.7988L129.011 59.7814C129.834 60.8895 129.604 62.4552 128.496 63.2788L113.514 74.4149L113.301 74.5553C112.213 75.2045 110.789 74.9381 110.016 73.8998C109.244 72.8609 109.398 71.4186 110.334 70.5638L110.532 70.4014L123.507 60.7574L113.863 47.7822C113.039 46.674 113.27 45.1074 114.378 44.2838Z"
|
||||
fill="#565656"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_d_3371_101118"
|
||||
x="35.6787"
|
||||
y="-3.32129"
|
||||
width="131.951"
|
||||
height="121.453"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset />
|
||||
<feGaussianBlur stdDeviation="2.5" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0.258824 0 0 0 0 0.254902 0 0 0 0 0.286275 0 0 0 0.17 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_3371_101118"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_3371_101118"
|
||||
result="shape"
|
||||
/>
|
||||
</filter>
|
||||
<clipPath id="clip0_3371_101118">
|
||||
<rect width="204" height="102" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg> `;
|
||||
|
||||
/**
|
||||
* Component to render code artifact tool call/result inside chat.
|
||||
*/
|
||||
export class CodeArtifactTool extends WithDisposable(ShadowlessElement) {
|
||||
export class CodeArtifactTool extends ArtifactTool<
|
||||
CodeArtifactToolCall | CodeArtifactToolResult
|
||||
> {
|
||||
static override styles = css`
|
||||
.code-artifact-result {
|
||||
cursor: pointer;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.code-artifact-result:hover {
|
||||
background-color: var(--affine-hover-color);
|
||||
}
|
||||
|
||||
.code-artifact-preview {
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
@@ -290,168 +427,148 @@ export class CodeArtifactTool extends WithDisposable(ShadowlessElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor data!: CodeArtifactToolCall | CodeArtifactToolResult;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor width: Signal<number | undefined> | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor imageProxyService: ImageProxyService | null | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor std: BlockStdScope | undefined;
|
||||
|
||||
@state()
|
||||
private accessor mode: 'preview' | 'code' = 'code';
|
||||
|
||||
private renderToolCall() {
|
||||
const { args } = this.data as CodeArtifactToolCall;
|
||||
const name = `Generating HTML artifact "${args.title}"`;
|
||||
return html`<tool-call-card
|
||||
.name=${name}
|
||||
.icon=${ToolIcon()}
|
||||
></tool-call-card>`;
|
||||
/* ---------------- ArtifactTool hooks ---------------- */
|
||||
|
||||
protected getBanner(theme: ColorScheme) {
|
||||
return theme === ColorScheme.Dark ? CodeBlockBannerDark : CodeBlockBanner;
|
||||
}
|
||||
|
||||
private renderToolResult() {
|
||||
if (!this.std) return nothing;
|
||||
if (this.data.type !== 'tool-result') return nothing;
|
||||
const resultData = this.data as CodeArtifactToolResult;
|
||||
const result = resultData.result;
|
||||
protected getCardMeta() {
|
||||
const loading = this.data.type === 'tool-call';
|
||||
return {
|
||||
title: this.data.args.title,
|
||||
icon: CodeBlockIcon({ width: '20', height: '20' }),
|
||||
loading,
|
||||
className: 'code-artifact-result',
|
||||
};
|
||||
}
|
||||
|
||||
if (result && typeof result === 'object' && 'title' in result) {
|
||||
const { title, html: htmlContent } = result as {
|
||||
title: string;
|
||||
html: string;
|
||||
};
|
||||
|
||||
const onClick = () => {
|
||||
const copyHTML = async () => {
|
||||
if (this.std) {
|
||||
await navigator.clipboard
|
||||
.writeText(htmlContent)
|
||||
.catch(console.error);
|
||||
toast(this.std.host, 'Copied HTML to clipboard');
|
||||
}
|
||||
};
|
||||
|
||||
const downloadHTML = () => {
|
||||
try {
|
||||
const blob = new Blob([htmlContent], { type: 'text/html' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `${title || 'artifact'}.html`;
|
||||
document.body.append(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const setCodeMode = () => {
|
||||
if (this.mode !== 'code') {
|
||||
this.mode = 'code';
|
||||
renderPreview();
|
||||
}
|
||||
};
|
||||
|
||||
const setPreviewMode = () => {
|
||||
if (this.mode !== 'preview') {
|
||||
this.mode = 'preview';
|
||||
renderPreview();
|
||||
}
|
||||
};
|
||||
|
||||
const renderPreview = () => {
|
||||
const controls = html`
|
||||
<div class="code-artifact-toggle-container">
|
||||
<div
|
||||
class=${classMap({
|
||||
'toggle-button': true,
|
||||
active: this.mode === 'code',
|
||||
})}
|
||||
@click=${setCodeMode}
|
||||
>
|
||||
Code
|
||||
</div>
|
||||
<div
|
||||
class=${classMap({
|
||||
'toggle-button': true,
|
||||
active: this.mode === 'preview',
|
||||
})}
|
||||
@click=${setPreviewMode}
|
||||
>
|
||||
Preview
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex: 1"></div>
|
||||
<button class="code-artifact-control-btn" @click=${downloadHTML}>
|
||||
${PageIcon({
|
||||
width: '20',
|
||||
height: '20',
|
||||
style: `color: ${unsafeCSSVarV2('icon/primary')}`,
|
||||
})}
|
||||
Download
|
||||
</button>
|
||||
<icon-button @click=${copyHTML} title="Copy HTML">
|
||||
${CopyIcon({ width: '20', height: '20' })}
|
||||
</icon-button>
|
||||
`;
|
||||
renderPreviewPanel(
|
||||
this,
|
||||
html`<div class="code-artifact-preview">
|
||||
${this.mode === 'preview'
|
||||
? html`<html-preview .html=${htmlContent}></html-preview>`
|
||||
: html`<code-highlighter
|
||||
.std=${this.std}
|
||||
.code=${htmlContent}
|
||||
.language=${'html'}
|
||||
.showLineNumbers=${true}
|
||||
></code-highlighter>`}
|
||||
</div>`,
|
||||
controls
|
||||
);
|
||||
};
|
||||
|
||||
renderPreview();
|
||||
};
|
||||
|
||||
return html`
|
||||
protected override getPreviewContent() {
|
||||
if (this.data.type !== 'tool-result' || !this.data.result) {
|
||||
// loading state
|
||||
return html`<div class="code-artifact-preview">
|
||||
<div
|
||||
class="affine-embed-linked-doc-block code-artifact-result horizontal"
|
||||
@click=${onClick}
|
||||
style="display:flex;justify-content:center;align-items:center;height:100%"
|
||||
>
|
||||
<div class="affine-embed-linked-doc-content">
|
||||
<div class="affine-embed-linked-doc-content-title">
|
||||
<div class="affine-embed-linked-doc-content-title-icon">
|
||||
${PageIcon({ width: '20', height: '20' })}
|
||||
</div>
|
||||
<div class="affine-embed-linked-doc-content-title-text">
|
||||
${title}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
${CodeBlockIcon({ width: '24', height: '24' })}
|
||||
</div>
|
||||
`;
|
||||
</div>`;
|
||||
}
|
||||
|
||||
return html`<tool-call-failed
|
||||
.name=${'Code artifact failed'}
|
||||
.icon=${ToolIcon()}
|
||||
></tool-call-failed>`;
|
||||
const result = this.data.result;
|
||||
if (typeof result !== 'object' || !('html' in result)) return html``;
|
||||
|
||||
const { html: htmlContent } = result as { html: string };
|
||||
|
||||
return html`<div class="code-artifact-preview">
|
||||
${this.mode === 'preview'
|
||||
? html`<html-preview .html=${htmlContent}></html-preview>`
|
||||
: html`<code-highlighter
|
||||
.std=${this.std}
|
||||
.code=${htmlContent}
|
||||
.language=${'html'}
|
||||
.showLineNumbers=${true}
|
||||
></code-highlighter>`}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
protected override render() {
|
||||
if (this.data.type === 'tool-call') {
|
||||
return this.renderToolCall();
|
||||
protected override getPreviewControls() {
|
||||
if (this.data.type !== 'tool-result' || !this.std || !this.data.result) {
|
||||
return undefined;
|
||||
}
|
||||
if (this.data.type === 'tool-result') {
|
||||
return this.renderToolResult();
|
||||
|
||||
const result = this.data.result as { html: string; title: string };
|
||||
const htmlContent = result.html;
|
||||
const title = result.title;
|
||||
|
||||
const copyHTML = async () => {
|
||||
await navigator.clipboard.writeText(htmlContent).catch(console.error);
|
||||
this.notificationService.toast('Copied HTML to clipboard');
|
||||
};
|
||||
|
||||
const downloadHTML = () => {
|
||||
try {
|
||||
const blob = new Blob([htmlContent], { type: 'text/html' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `${title || 'artifact'}.html`;
|
||||
document.body.append(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const setCodeMode = () => {
|
||||
if (this.mode !== 'code') {
|
||||
this.mode = 'code';
|
||||
this.refreshPreviewPanel();
|
||||
}
|
||||
};
|
||||
|
||||
const setPreviewMode = () => {
|
||||
if (this.mode !== 'preview') {
|
||||
this.mode = 'preview';
|
||||
this.refreshPreviewPanel();
|
||||
}
|
||||
};
|
||||
|
||||
return html`
|
||||
<div class="code-artifact-toggle-container">
|
||||
<div
|
||||
class=${classMap({
|
||||
'toggle-button': true,
|
||||
active: this.mode === 'code',
|
||||
})}
|
||||
@click=${setCodeMode}
|
||||
>
|
||||
Code
|
||||
</div>
|
||||
<div
|
||||
class=${classMap({
|
||||
'toggle-button': true,
|
||||
active: this.mode === 'preview',
|
||||
})}
|
||||
@click=${setPreviewMode}
|
||||
>
|
||||
Preview
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex: 1"></div>
|
||||
<button class="code-artifact-control-btn" @click=${downloadHTML}>
|
||||
${PageIcon({
|
||||
width: '20',
|
||||
height: '20',
|
||||
style: `color: ${unsafeCSSVarV2('icon/primary')}`,
|
||||
})}
|
||||
Download
|
||||
</button>
|
||||
<icon-button @click=${copyHTML} title="Copy HTML">
|
||||
${CopyIcon({ width: '20', height: '20' })}
|
||||
</icon-button>
|
||||
`;
|
||||
}
|
||||
|
||||
protected override getErrorTemplate() {
|
||||
if (
|
||||
this.data.type === 'tool-result' &&
|
||||
this.data.result &&
|
||||
(this.data.result as any).type === 'error'
|
||||
) {
|
||||
return html`<tool-call-failed
|
||||
.name=${'Code artifact failed'}
|
||||
.icon=${ToolIcon()}
|
||||
></tool-call-failed>`;
|
||||
}
|
||||
return nothing;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,27 +2,18 @@ import { getStoreManager } from '@affine/core/blocksuite/manager/store';
|
||||
import { getAFFiNEWorkspaceSchema } from '@affine/core/modules/workspace';
|
||||
import { getEmbedLinkedDocIcons } from '@blocksuite/affine/blocks/embed-doc';
|
||||
import { LoadingIcon } from '@blocksuite/affine/components/icons';
|
||||
import { toast } from '@blocksuite/affine/components/toast';
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { RefNodeSlotsProvider } from '@blocksuite/affine/inlines/reference';
|
||||
import type { ImageProxyService } from '@blocksuite/affine/shared/adapters';
|
||||
import {
|
||||
NotificationProvider,
|
||||
ThemeProvider,
|
||||
} from '@blocksuite/affine/shared/services';
|
||||
import type { ColorScheme } from '@blocksuite/affine/model';
|
||||
import { NotificationProvider } from '@blocksuite/affine/shared/services';
|
||||
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import { type BlockStdScope, ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { MarkdownTransformer } from '@blocksuite/affine/widgets/linked-doc';
|
||||
import { CopyIcon, PageIcon, ToolIcon } from '@blocksuite/icons/lit';
|
||||
import { type Signal } from '@preact/signals-core';
|
||||
import { css, html, nothing, type PropertyValues } from 'lit';
|
||||
import type { BlockStdScope } from '@blocksuite/std';
|
||||
import { css, html } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
|
||||
import { getCustomPageEditorBlockSpecs } from '../text-renderer';
|
||||
import {
|
||||
isPreviewPanelOpen,
|
||||
renderPreviewPanel,
|
||||
} from './artifacts-preview-panel';
|
||||
import { ArtifactTool } from './artifact-tool';
|
||||
import type { ToolError } from './type';
|
||||
|
||||
interface DocComposeToolCall {
|
||||
@@ -50,17 +41,10 @@ interface DocComposeToolResult {
|
||||
/**
|
||||
* Component to render doc compose tool call/result inside chat.
|
||||
*/
|
||||
export class DocComposeTool extends WithDisposable(ShadowlessElement) {
|
||||
export class DocComposeTool extends ArtifactTool<
|
||||
DocComposeToolCall | DocComposeToolResult
|
||||
> {
|
||||
static override styles = css`
|
||||
.doc-compose-result {
|
||||
cursor: pointer;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.doc-compose-result:hover {
|
||||
background-color: var(--affine-hover-color);
|
||||
}
|
||||
|
||||
.doc-compose-result-preview {
|
||||
padding: 24px;
|
||||
height: 100%;
|
||||
@@ -103,30 +87,60 @@ export class DocComposeTool extends WithDisposable(ShadowlessElement) {
|
||||
}
|
||||
`;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor data!: DocComposeToolCall | DocComposeToolResult;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor width: Signal<number | undefined> | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor imageProxyService: ImageProxyService | null | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor std: BlockStdScope | undefined;
|
||||
|
||||
override updated(changedProperties: PropertyValues) {
|
||||
super.updated(changedProperties);
|
||||
if (changedProperties.has('data') && isPreviewPanelOpen(this)) {
|
||||
this.updatePreviewPanel();
|
||||
}
|
||||
protected getBanner(theme: ColorScheme) {
|
||||
const { LinkedDocEmptyBanner } = getEmbedLinkedDocIcons(
|
||||
theme,
|
||||
'page',
|
||||
'horizontal'
|
||||
);
|
||||
return LinkedDocEmptyBanner;
|
||||
}
|
||||
|
||||
private updatePreviewPanel() {
|
||||
protected getCardMeta() {
|
||||
const composing = this.data.type === 'tool-call';
|
||||
return {
|
||||
title: this.data.args.title,
|
||||
icon: PageIcon(),
|
||||
loading: composing,
|
||||
className: 'doc-compose-result',
|
||||
};
|
||||
}
|
||||
|
||||
protected override getPreviewContent() {
|
||||
if (!this.std) return html``;
|
||||
const std = this.std;
|
||||
const resultData = this.data;
|
||||
const title = this.data.args.title;
|
||||
const result = resultData.type === 'tool-result' ? resultData.result : null;
|
||||
const successResult = result && 'markdown' in result ? result : null;
|
||||
|
||||
return html`<div class="doc-compose-result-preview">
|
||||
<div class="doc-compose-result-preview-title">${title}</div>
|
||||
${successResult
|
||||
? html`<text-renderer
|
||||
.answer=${successResult.markdown}
|
||||
.host=${std.host}
|
||||
.schema=${std.store.schema}
|
||||
.options=${{
|
||||
customHeading: true,
|
||||
extensions: getCustomPageEditorBlockSpecs(),
|
||||
}}
|
||||
></text-renderer>`
|
||||
: html`<div class="doc-compose-result-preview-loading">
|
||||
${LoadingIcon({
|
||||
size: '32px',
|
||||
})}
|
||||
</div>`}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
protected override getPreviewControls() {
|
||||
if (!this.std) return;
|
||||
const std = this.std;
|
||||
const resultData = this.data;
|
||||
const composing = resultData.type === 'tool-call';
|
||||
const title = this.data.args.title;
|
||||
const result = resultData.type === 'tool-result' ? resultData.result : null;
|
||||
const successResult = result && 'markdown' in result ? result : null;
|
||||
@@ -138,7 +152,7 @@ export class DocComposeTool extends WithDisposable(ShadowlessElement) {
|
||||
await navigator.clipboard
|
||||
.writeText(successResult.markdown)
|
||||
.catch(console.error);
|
||||
toast(std.host, 'Copied markdown to clipboard');
|
||||
this.notificationService.toast('Copied markdown to clipboard');
|
||||
};
|
||||
|
||||
const saveAsDoc = async () => {
|
||||
@@ -171,103 +185,43 @@ export class DocComposeTool extends WithDisposable(ShadowlessElement) {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
toast(std.host, 'Failed to create document');
|
||||
this.notificationService.toast('Failed to create document');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
toast(std.host, 'Failed to create document');
|
||||
this.notificationService.toast('Failed to create document');
|
||||
}
|
||||
};
|
||||
|
||||
const controls = html`
|
||||
<button class="doc-compose-result-save-as-doc" @click=${saveAsDoc}>
|
||||
${PageIcon({
|
||||
width: '20',
|
||||
height: '20',
|
||||
style: `color: ${unsafeCSSVarV2('icon/primary')}`,
|
||||
})}
|
||||
Save as doc
|
||||
</button>
|
||||
<icon-button @click=${copyMarkdown} title="Copy markdown">
|
||||
${CopyIcon({ width: '20', height: '20' })}
|
||||
</icon-button>
|
||||
`;
|
||||
|
||||
renderPreviewPanel(
|
||||
this,
|
||||
html`<div class="doc-compose-result-preview">
|
||||
<div class="doc-compose-result-preview-title">${title}</div>
|
||||
${successResult
|
||||
? html`<text-renderer
|
||||
.answer=${successResult.markdown}
|
||||
.host=${std.host}
|
||||
.schema=${std.store.schema}
|
||||
.options=${{
|
||||
customHeading: true,
|
||||
extensions: getCustomPageEditorBlockSpecs(),
|
||||
}}
|
||||
></text-renderer>`
|
||||
: html`<div class="doc-compose-result-preview-loading">
|
||||
${LoadingIcon({
|
||||
size: '32px',
|
||||
})}
|
||||
</div>`}
|
||||
</div>`,
|
||||
composing ? undefined : controls
|
||||
);
|
||||
return this.data.type === 'tool-call'
|
||||
? undefined
|
||||
: html`
|
||||
<button class="doc-compose-result-save-as-doc" @click=${saveAsDoc}>
|
||||
${PageIcon({
|
||||
width: '20',
|
||||
height: '20',
|
||||
style: `color: ${unsafeCSSVarV2('icon/primary')}`,
|
||||
})}
|
||||
Save as doc
|
||||
</button>
|
||||
<icon-button @click=${copyMarkdown} title="Copy markdown">
|
||||
${CopyIcon({ width: '20', height: '20' })}
|
||||
</icon-button>
|
||||
`;
|
||||
}
|
||||
|
||||
protected override render() {
|
||||
if (!this.std) return nothing;
|
||||
const resultData = this.data;
|
||||
const composing = resultData.type === 'tool-call';
|
||||
|
||||
const title = this.data.args.title;
|
||||
|
||||
protected override getErrorTemplate() {
|
||||
if (
|
||||
resultData.type === 'tool-result' &&
|
||||
resultData.result &&
|
||||
'type' in resultData.result &&
|
||||
resultData.result.type === 'error'
|
||||
this.data.type === 'tool-result' &&
|
||||
this.data.result &&
|
||||
'type' in this.data.result &&
|
||||
(this.data.result as any).type === 'error'
|
||||
) {
|
||||
// failed
|
||||
return html`<tool-call-failed
|
||||
.name=${'Doc compose failed'}
|
||||
.icon=${ToolIcon()}
|
||||
></tool-call-failed>`;
|
||||
}
|
||||
|
||||
const theme = this.std.get(ThemeProvider).theme;
|
||||
|
||||
const { LinkedDocEmptyBanner } = getEmbedLinkedDocIcons(
|
||||
theme,
|
||||
'page',
|
||||
'horizontal'
|
||||
);
|
||||
|
||||
return html`
|
||||
<div
|
||||
class="affine-embed-linked-doc-block doc-compose-result horizontal"
|
||||
@click=${this.updatePreviewPanel}
|
||||
>
|
||||
<div class="affine-embed-linked-doc-content">
|
||||
<div class="affine-embed-linked-doc-content-title">
|
||||
<div class="affine-embed-linked-doc-content-title-icon">
|
||||
${composing
|
||||
? LoadingIcon({
|
||||
size: '20px',
|
||||
})
|
||||
: PageIcon()}
|
||||
</div>
|
||||
<div class="affine-embed-linked-doc-content-title-text">
|
||||
${title}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="affine-embed-linked-doc-banner">
|
||||
${LinkedDocEmptyBanner}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { NotificationProvider } from '@blocksuite/affine/shared/services';
|
||||
import { unsafeCSSVar, unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import { type EditorHost, ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import type { NotificationService } from '@blocksuite/affine-shared/services';
|
||||
import {
|
||||
CloseIcon,
|
||||
CopyIcon,
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { property, state } from 'lit/decorators.js';
|
||||
|
||||
import type { BlockDiffService } from '../../services/block-diff';
|
||||
import { BlockDiffProvider } from '../../services/block-diff';
|
||||
import { diffMarkdown } from '../../utils/apply-model/markdown-diff';
|
||||
import { copyText } from '../../utils/editor-actions';
|
||||
import type { ToolError } from './type';
|
||||
@@ -190,14 +190,18 @@ export class DocEditTool extends WithDisposable(ShadowlessElement) {
|
||||
accessor data!: DocEditToolCall | DocEditToolResult;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor blockDiffService: BlockDiffService | undefined;
|
||||
accessor renderRichText!: (text: string) => string;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor renderRichText!: (text: string) => string;
|
||||
accessor notificationService!: NotificationService;
|
||||
|
||||
@state()
|
||||
accessor isCollapsed = false;
|
||||
|
||||
get blockDiffService() {
|
||||
return this.host?.std.getOptional(BlockDiffProvider);
|
||||
}
|
||||
|
||||
private async _handleApply(markdown: string) {
|
||||
if (!this.host) {
|
||||
return;
|
||||
@@ -229,14 +233,9 @@ export class DocEditTool extends WithDisposable(ShadowlessElement) {
|
||||
if (!this.host) {
|
||||
return;
|
||||
}
|
||||
const success = await copyText(
|
||||
this.host,
|
||||
removeMarkdownComments(changedMarkdown)
|
||||
);
|
||||
const success = await copyText(removeMarkdownComments(changedMarkdown));
|
||||
if (success) {
|
||||
const notificationService =
|
||||
this.host?.std.getOptional(NotificationProvider);
|
||||
notificationService?.notify({
|
||||
this.notificationService.notify({
|
||||
title: 'Copied to clipboard',
|
||||
accent: 'success',
|
||||
onClose: function (): void {},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
||||
import { type ImageProxyService } from '@blocksuite/affine/shared/adapters';
|
||||
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||
import { DEFAULT_IMAGE_PROXY_ENDPOINT } from '@blocksuite/affine-shared/consts';
|
||||
import { ToggleDownIcon, ToolIcon } from '@blocksuite/icons/lit';
|
||||
import { type Signal } from '@preact/signals-core';
|
||||
import { css, html, nothing, type TemplateResult } from 'lit';
|
||||
@@ -205,12 +205,11 @@ export class ToolResultCard extends SignalWatcher(
|
||||
@property({ attribute: false })
|
||||
accessor width: Signal<number | undefined> | undefined;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor imageProxyService: ImageProxyService | null | undefined;
|
||||
|
||||
@state()
|
||||
private accessor isCollapsed = true;
|
||||
|
||||
private readonly imageProxyURL = DEFAULT_IMAGE_PROXY_ENDPOINT;
|
||||
|
||||
protected override render() {
|
||||
return html`
|
||||
<div class="ai-tool-result-wrapper">
|
||||
@@ -272,15 +271,20 @@ export class ToolResultCard extends SignalWatcher(
|
||||
`;
|
||||
}
|
||||
|
||||
buildUrl(imageUrl: string) {
|
||||
if (imageUrl.startsWith(this.imageProxyURL)) {
|
||||
return imageUrl;
|
||||
}
|
||||
return `${this.imageProxyURL}?url=${encodeURIComponent(imageUrl)}`;
|
||||
}
|
||||
|
||||
private renderIcon(icon: string | TemplateResult<1> | undefined) {
|
||||
if (!icon) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
if (typeof icon === 'string') {
|
||||
if (this.imageProxyService) {
|
||||
return html`<img src=${this.imageProxyService.buildUrl(icon)} />`;
|
||||
}
|
||||
return html`<img src=${icon} />`;
|
||||
return html`<img src=${this.buildUrl(icon)} />`;
|
||||
}
|
||||
return html`${icon}`;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user