Compare commits
6 Commits
catsjuice/
...
canary
Author | SHA1 | Date | |
---|---|---|---|
|
a7185e419c | ||
|
2171d1bfe2 | ||
|
5e193b58c0 | ||
|
eef2e05d83 | ||
|
f3a2a75743 | ||
|
a6edb6192f |
7
.github/workflows/release-mobile.yml
vendored
7
.github/workflows/release-mobile.yml
vendored
@ -83,6 +83,13 @@ jobs:
|
|||||||
- build-ios-web
|
- build-ios-web
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup Version
|
||||||
|
uses: ./.github/actions/setup-version
|
||||||
|
with:
|
||||||
|
app-version: ${{ inputs.app-version }}
|
||||||
|
- name: 'Update Code Sign Identity'
|
||||||
|
shell: bash
|
||||||
|
run: ./packages/frontend/apps/ios/update_code_sign_identity.sh
|
||||||
- name: Download mobile artifact
|
- name: Download mobile artifact
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
@ -495,14 +495,6 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
|
|||||||
|
|
||||||
const linkedDoc = this.linkedDoc;
|
const linkedDoc = this.linkedDoc;
|
||||||
if (linkedDoc) {
|
if (linkedDoc) {
|
||||||
this.disposables.add(
|
|
||||||
linkedDoc.workspace.slots.docListUpdated.subscribe(() => {
|
|
||||||
this._load().catch(e => {
|
|
||||||
console.error(e);
|
|
||||||
this.isError = true;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// Should throttle the blockUpdated event to avoid too many re-renders
|
// Should throttle the blockUpdated event to avoid too many re-renders
|
||||||
// Because the blockUpdated event is triggered too frequently at some cases
|
// Because the blockUpdated event is triggered too frequently at some cases
|
||||||
this.disposables.add(
|
this.disposables.add(
|
||||||
|
@ -188,11 +188,6 @@ export class CopilotSessionModel extends BaseModel {
|
|||||||
|
|
||||||
@Transactional()
|
@Transactional()
|
||||||
async fork(options: ForkSessionOptions): Promise<string> {
|
async fork(options: ForkSessionOptions): Promise<string> {
|
||||||
if (!options.messages?.length) {
|
|
||||||
throw new CopilotSessionInvalidInput(
|
|
||||||
'Cannot fork session without messages'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (options.pinned) {
|
if (options.pinned) {
|
||||||
await this.unpin(options.workspaceId, options.userId);
|
await this.unpin(options.workspaceId, options.userId);
|
||||||
}
|
}
|
||||||
@ -203,12 +198,15 @@ export class CopilotSessionModel extends BaseModel {
|
|||||||
...forkedState,
|
...forkedState,
|
||||||
messages: [],
|
messages: [],
|
||||||
});
|
});
|
||||||
|
if (options.messages.length) {
|
||||||
// save message
|
// save message
|
||||||
await this.models.copilotSession.updateMessages({
|
await this.models.copilotSession.updateMessages({
|
||||||
...forkedState,
|
...forkedState,
|
||||||
sessionId,
|
sessionId,
|
||||||
messages,
|
messages,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return sessionId;
|
return sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1650,10 +1650,6 @@ const CHAT_PROMPT: Omit<Prompt, 'name'> = {
|
|||||||
'gpt-4.1',
|
'gpt-4.1',
|
||||||
'o3',
|
'o3',
|
||||||
'o4-mini',
|
'o4-mini',
|
||||||
'claude-opus-4-20250514',
|
|
||||||
'claude-sonnet-4-20250514',
|
|
||||||
'claude-3-7-sonnet-20250219',
|
|
||||||
'claude-3-5-sonnet-20241022',
|
|
||||||
'gemini-2.5-flash',
|
'gemini-2.5-flash',
|
||||||
'gemini-2.5-pro',
|
'gemini-2.5-pro',
|
||||||
'claude-opus-4@20250514',
|
'claude-opus-4@20250514',
|
||||||
|
@ -390,19 +390,19 @@ export interface CustomAITools extends ToolSet {
|
|||||||
|
|
||||||
type ChunkType = TextStreamPart<CustomAITools>['type'];
|
type ChunkType = TextStreamPart<CustomAITools>['type'];
|
||||||
|
|
||||||
export function parseUnknownError(error: unknown) {
|
export function toError(error: unknown): Error {
|
||||||
if (typeof error === 'string') {
|
if (typeof error === 'string') {
|
||||||
throw new Error(error);
|
return new Error(error);
|
||||||
} else if (error instanceof Error) {
|
} else if (error instanceof Error) {
|
||||||
throw error;
|
return error;
|
||||||
} else if (
|
} else if (
|
||||||
typeof error === 'object' &&
|
typeof error === 'object' &&
|
||||||
error !== null &&
|
error !== null &&
|
||||||
'message' in error
|
'message' in error
|
||||||
) {
|
) {
|
||||||
throw new Error(String(error.message));
|
return new Error(String(error.message));
|
||||||
} else {
|
} else {
|
||||||
throw new Error(JSON.stringify(error));
|
return new Error(JSON.stringify(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,8 +483,7 @@ export class TextStreamParser {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'error': {
|
case 'error': {
|
||||||
parseUnknownError(chunk.error);
|
throw toError(chunk.error);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.lastType = chunk.type;
|
this.lastType = chunk.type;
|
||||||
@ -550,8 +549,7 @@ export class StreamObjectParser {
|
|||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
case 'error': {
|
case 'error': {
|
||||||
parseUnknownError(chunk.error);
|
throw toError(chunk.error);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return null;
|
return null;
|
||||||
|
@ -4,6 +4,7 @@ import { z } from 'zod';
|
|||||||
import type { AccessController } from '../../../core/permission';
|
import type { AccessController } from '../../../core/permission';
|
||||||
import type { IndexerService, SearchDoc } from '../../indexer';
|
import type { IndexerService, SearchDoc } from '../../indexer';
|
||||||
import type { CopilotChatOptions } from '../providers';
|
import type { CopilotChatOptions } from '../providers';
|
||||||
|
import { toolError } from './error';
|
||||||
|
|
||||||
export const buildDocKeywordSearchGetter = (
|
export const buildDocKeywordSearchGetter = (
|
||||||
ac: AccessController,
|
ac: AccessController,
|
||||||
@ -56,8 +57,8 @@ export const createDocKeywordSearchTool = (
|
|||||||
createdByUser: doc.createdByUser,
|
createdByUser: doc.createdByUser,
|
||||||
updatedByUser: doc.updatedByUser,
|
updatedByUser: doc.updatedByUser,
|
||||||
}));
|
}));
|
||||||
} catch {
|
} catch (e: any) {
|
||||||
return 'Failed to search documents.';
|
return toolError('Doc Keyword Search Failed', e.message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -5,6 +5,7 @@ import type { AccessController } from '../../../core/permission';
|
|||||||
import type { ChunkSimilarity } from '../../../models';
|
import type { ChunkSimilarity } from '../../../models';
|
||||||
import type { CopilotContextService } from '../context';
|
import type { CopilotContextService } from '../context';
|
||||||
import type { CopilotChatOptions } from '../providers';
|
import type { CopilotChatOptions } from '../providers';
|
||||||
|
import { toolError } from './error';
|
||||||
|
|
||||||
export const buildDocSearchGetter = (
|
export const buildDocSearchGetter = (
|
||||||
ac: AccessController,
|
ac: AccessController,
|
||||||
@ -46,8 +47,8 @@ export const createDocSemanticSearchTool = (
|
|||||||
execute: async ({ query }) => {
|
execute: async ({ query }) => {
|
||||||
try {
|
try {
|
||||||
return await searchDocs(query);
|
return await searchDocs(query);
|
||||||
} catch {
|
} catch (e: any) {
|
||||||
return 'Failed to search documents.';
|
return toolError('Doc Semantic Search Failed', e.message);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
11
packages/backend/server/src/plugins/copilot/tools/error.ts
Normal file
11
packages/backend/server/src/plugins/copilot/tools/error.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
export interface ToolError {
|
||||||
|
type: 'error';
|
||||||
|
name: string;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const toolError = (name: string, message: string): ToolError => ({
|
||||||
|
type: 'error',
|
||||||
|
name,
|
||||||
|
message,
|
||||||
|
});
|
@ -0,0 +1,39 @@
|
|||||||
|
import { tool } from 'ai';
|
||||||
|
import Exa from 'exa-js';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
import { Config } from '../../../base';
|
||||||
|
import { toolError } from './error';
|
||||||
|
|
||||||
|
export const createExaCrawlTool = (config: Config) => {
|
||||||
|
return tool({
|
||||||
|
description: 'Crawl the web url for information',
|
||||||
|
parameters: z.object({
|
||||||
|
url: z
|
||||||
|
.string()
|
||||||
|
.describe('The URL to crawl (including http:// or https://)'),
|
||||||
|
}),
|
||||||
|
execute: async ({ url }) => {
|
||||||
|
try {
|
||||||
|
const { key } = config.copilot.exa;
|
||||||
|
const exa = new Exa(key);
|
||||||
|
const result = await exa.getContents([url], {
|
||||||
|
livecrawl: 'always',
|
||||||
|
text: {
|
||||||
|
maxCharacters: 100000,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return result.results.map(data => ({
|
||||||
|
title: data.title,
|
||||||
|
url: data.url,
|
||||||
|
content: data.text,
|
||||||
|
favicon: data.favicon,
|
||||||
|
publishedDate: data.publishedDate,
|
||||||
|
author: data.author,
|
||||||
|
}));
|
||||||
|
} catch (e: any) {
|
||||||
|
return toolError('Exa Crawl Failed', e.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
@ -3,6 +3,7 @@ import Exa from 'exa-js';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { Config } from '../../../base';
|
import { Config } from '../../../base';
|
||||||
|
import { toolError } from './error';
|
||||||
|
|
||||||
export const createExaSearchTool = (config: Config) => {
|
export const createExaSearchTool = (config: Config) => {
|
||||||
return tool({
|
return tool({
|
||||||
@ -30,41 +31,8 @@ export const createExaSearchTool = (config: Config) => {
|
|||||||
publishedDate: data.publishedDate,
|
publishedDate: data.publishedDate,
|
||||||
author: data.author,
|
author: data.author,
|
||||||
}));
|
}));
|
||||||
} catch {
|
} catch (e: any) {
|
||||||
return 'Failed to search the web';
|
return toolError('Exa Search Failed', e.message);
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createExaCrawlTool = (config: Config) => {
|
|
||||||
return tool({
|
|
||||||
description: 'Crawl the web url for information',
|
|
||||||
parameters: z.object({
|
|
||||||
url: z
|
|
||||||
.string()
|
|
||||||
.describe('The URL to crawl (including http:// or https://)'),
|
|
||||||
}),
|
|
||||||
execute: async ({ url }) => {
|
|
||||||
try {
|
|
||||||
const { key } = config.copilot.exa;
|
|
||||||
const exa = new Exa(key);
|
|
||||||
const result = await exa.getContents([url], {
|
|
||||||
livecrawl: 'always',
|
|
||||||
text: {
|
|
||||||
maxCharacters: 100000,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
return result.results.map(data => ({
|
|
||||||
title: data.title,
|
|
||||||
url: data.url,
|
|
||||||
content: data.text,
|
|
||||||
favicon: data.favicon,
|
|
||||||
publishedDate: data.publishedDate,
|
|
||||||
author: data.author,
|
|
||||||
}));
|
|
||||||
} catch {
|
|
||||||
return 'Failed to crawl the web url';
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
@ -1,3 +1,5 @@
|
|||||||
export * from './doc-keyword-search';
|
export * from './doc-keyword-search';
|
||||||
export * from './doc-semantic-search';
|
export * from './doc-semantic-search';
|
||||||
export * from './web-search';
|
export * from './error';
|
||||||
|
export * from './exa-crawl';
|
||||||
|
export * from './exa-search';
|
||||||
|
83
packages/frontend/apps/ios/update_code_sign_identity.sh
Executable file
83
packages/frontend/apps/ios/update_code_sign_identity.sh
Executable file
@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script to update code signing settings in iOS project for CI environment
|
||||||
|
# Updates project.pbxproj to use Apple Distribution certificate and team settings
|
||||||
|
|
||||||
|
set -e # Exit immediately if a command exits with a non-zero status
|
||||||
|
|
||||||
|
# Define target values
|
||||||
|
TARGET_IDENTITY="Apple Distribution: TOEVERYTHING PTE. LTD. (73YMMDVT2M)"
|
||||||
|
TARGET_SIGN_STYLE="Manual"
|
||||||
|
TARGET_TEAM="73YMMDVT2M"
|
||||||
|
TARGET_PROVISIONING_PROFILE="AppStore app.affine.pro"
|
||||||
|
|
||||||
|
# Get script directory and build absolute path to project file
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
PBXPROJ_FILE="$SCRIPT_DIR/App/App.xcodeproj/project.pbxproj"
|
||||||
|
|
||||||
|
# Check if file exists
|
||||||
|
if [ ! -f "$PBXPROJ_FILE" ]; then
|
||||||
|
echo "❌ Error: project.pbxproj file not found: $PBXPROJ_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🔍 Found project file: $PBXPROJ_FILE"
|
||||||
|
|
||||||
|
# Display current settings
|
||||||
|
echo "📋 Current code signing settings:"
|
||||||
|
echo "--- CODE_SIGN_IDENTITY ---"
|
||||||
|
grep -n "CODE_SIGN_IDENTITY" "$PBXPROJ_FILE" || echo "No CODE_SIGN_IDENTITY settings found"
|
||||||
|
echo "--- CODE_SIGN_STYLE ---"
|
||||||
|
grep -n "CODE_SIGN_STYLE" "$PBXPROJ_FILE" || echo "No CODE_SIGN_STYLE settings found"
|
||||||
|
echo "--- DEVELOPMENT_TEAM ---"
|
||||||
|
grep -n "DEVELOPMENT_TEAM" "$PBXPROJ_FILE" || echo "No DEVELOPMENT_TEAM settings found"
|
||||||
|
echo "--- PROVISIONING_PROFILE_SPECIFIER ---"
|
||||||
|
grep -n "PROVISIONING_PROFILE_SPECIFIER" "$PBXPROJ_FILE" || echo "No PROVISIONING_PROFILE_SPECIFIER settings found"
|
||||||
|
|
||||||
|
# Replace CODE_SIGN_IDENTITY settings
|
||||||
|
echo ""
|
||||||
|
echo "🔄 Replacing CODE_SIGN_IDENTITY..."
|
||||||
|
sed -i.tmp 's/CODE_SIGN_IDENTITY = "[^"]*";/CODE_SIGN_IDENTITY = "'"$TARGET_IDENTITY"'";/g' "$PBXPROJ_FILE"
|
||||||
|
|
||||||
|
# Replace CODE_SIGN_STYLE settings
|
||||||
|
echo "🔄 Replacing CODE_SIGN_STYLE..."
|
||||||
|
sed -i.tmp 's/CODE_SIGN_STYLE = [^;]*;/CODE_SIGN_STYLE = '"$TARGET_SIGN_STYLE"';/g' "$PBXPROJ_FILE"
|
||||||
|
|
||||||
|
# Replace DEVELOPMENT_TEAM settings
|
||||||
|
echo "🔄 Replacing DEVELOPMENT_TEAM..."
|
||||||
|
sed -i.tmp 's/DEVELOPMENT_TEAM = [^;]*;/DEVELOPMENT_TEAM = '"$TARGET_TEAM"';/g' "$PBXPROJ_FILE"
|
||||||
|
|
||||||
|
# Replace PROVISIONING_PROFILE_SPECIFIER settings
|
||||||
|
echo "🔄 Replacing PROVISIONING_PROFILE_SPECIFIER..."
|
||||||
|
sed -i.tmp 's/PROVISIONING_PROFILE_SPECIFIER = "[^"]*";/PROVISIONING_PROFILE_SPECIFIER = "'"$TARGET_PROVISIONING_PROFILE"'";/g' "$PBXPROJ_FILE"
|
||||||
|
|
||||||
|
# Remove temporary file
|
||||||
|
rm -f "${PBXPROJ_FILE}.tmp"
|
||||||
|
|
||||||
|
# Verify replacement results
|
||||||
|
echo ""
|
||||||
|
echo "✅ Replacement completed! New code signing settings:"
|
||||||
|
echo "--- CODE_SIGN_IDENTITY ---"
|
||||||
|
grep -n "CODE_SIGN_IDENTITY" "$PBXPROJ_FILE"
|
||||||
|
echo "--- CODE_SIGN_STYLE ---"
|
||||||
|
grep -n "CODE_SIGN_STYLE" "$PBXPROJ_FILE"
|
||||||
|
echo "--- DEVELOPMENT_TEAM ---"
|
||||||
|
grep -n "DEVELOPMENT_TEAM" "$PBXPROJ_FILE"
|
||||||
|
echo "--- PROVISIONING_PROFILE_SPECIFIER ---"
|
||||||
|
grep -n "PROVISIONING_PROFILE_SPECIFIER" "$PBXPROJ_FILE"
|
||||||
|
|
||||||
|
# Count replacements
|
||||||
|
IDENTITY_COUNT=$(grep -c "CODE_SIGN_IDENTITY.*$TARGET_IDENTITY" "$PBXPROJ_FILE")
|
||||||
|
STYLE_COUNT=$(grep -c "CODE_SIGN_STYLE.*$TARGET_SIGN_STYLE" "$PBXPROJ_FILE")
|
||||||
|
TEAM_COUNT=$(grep -c "DEVELOPMENT_TEAM.*$TARGET_TEAM" "$PBXPROJ_FILE")
|
||||||
|
PROVISIONING_COUNT=$(grep -c "PROVISIONING_PROFILE_SPECIFIER.*$TARGET_PROVISIONING_PROFILE" "$PBXPROJ_FILE")
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "📊 Replacement summary:"
|
||||||
|
echo " - CODE_SIGN_IDENTITY: $IDENTITY_COUNT replacements"
|
||||||
|
echo " - CODE_SIGN_STYLE: $STYLE_COUNT replacements"
|
||||||
|
echo " - DEVELOPMENT_TEAM: $TEAM_COUNT replacements"
|
||||||
|
echo " - PROVISIONING_PROFILE_SPECIFIER: $PROVISIONING_COUNT replacements"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🎉 Script execution completed successfully!"
|
@ -20,8 +20,8 @@ import type {
|
|||||||
SearchMenuConfig,
|
SearchMenuConfig,
|
||||||
} from '../components/ai-chat-chips';
|
} from '../components/ai-chat-chips';
|
||||||
import type {
|
import type {
|
||||||
AIModelSwitchConfig,
|
|
||||||
AINetworkSearchConfig,
|
AINetworkSearchConfig,
|
||||||
|
AIPlaygroundConfig,
|
||||||
AIReasoningConfig,
|
AIReasoningConfig,
|
||||||
} from '../components/ai-chat-input';
|
} from '../components/ai-chat-input';
|
||||||
import {
|
import {
|
||||||
@ -224,7 +224,7 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
accessor reasoningConfig!: AIReasoningConfig;
|
accessor reasoningConfig!: AIReasoningConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor modelSwitchConfig!: AIModelSwitchConfig;
|
accessor playgroundConfig!: AIPlaygroundConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor appSidebarConfig!: AppSidebarConfig;
|
accessor appSidebarConfig!: AppSidebarConfig;
|
||||||
@ -298,7 +298,7 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
.doc=${this.doc}
|
.doc=${this.doc}
|
||||||
.networkSearchConfig=${this.networkSearchConfig}
|
.networkSearchConfig=${this.networkSearchConfig}
|
||||||
.reasoningConfig=${this.reasoningConfig}
|
.reasoningConfig=${this.reasoningConfig}
|
||||||
.modelSwitchConfig=${this.modelSwitchConfig}
|
.playgroundConfig=${this.playgroundConfig}
|
||||||
.appSidebarConfig=${this.appSidebarConfig}
|
.appSidebarConfig=${this.appSidebarConfig}
|
||||||
.searchMenuConfig=${this.searchMenuConfig}
|
.searchMenuConfig=${this.searchMenuConfig}
|
||||||
.docDisplayConfig=${this.docDisplayConfig}
|
.docDisplayConfig=${this.docDisplayConfig}
|
||||||
@ -437,7 +437,7 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
>`
|
>`
|
||||||
: 'AFFiNE AI'}
|
: 'AFFiNE AI'}
|
||||||
</div>
|
</div>
|
||||||
${this.modelSwitchConfig.visible.value
|
${this.playgroundConfig.visible.value
|
||||||
? html`
|
? html`
|
||||||
<div class="chat-panel-playground" @click=${this._openPlayground}>
|
<div class="chat-panel-playground" @click=${this._openPlayground}>
|
||||||
${CenterPeekIcon()}
|
${CenterPeekIcon()}
|
||||||
@ -478,7 +478,7 @@ export class ChatPanel extends SignalWatcher(
|
|||||||
.isVisible=${this._isSidebarOpen}
|
.isVisible=${this._isSidebarOpen}
|
||||||
.networkSearchConfig=${this.networkSearchConfig}
|
.networkSearchConfig=${this.networkSearchConfig}
|
||||||
.reasoningConfig=${this.reasoningConfig}
|
.reasoningConfig=${this.reasoningConfig}
|
||||||
.modelSwitchConfig=${this.modelSwitchConfig}
|
.playgroundConfig=${this.playgroundConfig}
|
||||||
.docDisplayConfig=${this.docDisplayConfig}
|
.docDisplayConfig=${this.docDisplayConfig}
|
||||||
.searchMenuConfig=${this.searchMenuConfig}
|
.searchMenuConfig=${this.searchMenuConfig}
|
||||||
.trackOptions=${{
|
.trackOptions=${{
|
||||||
|
@ -29,7 +29,6 @@ import type {
|
|||||||
import { isCollectionChip, isDocChip, isTagChip } from '../ai-chat-chips';
|
import { isCollectionChip, isDocChip, isTagChip } from '../ai-chat-chips';
|
||||||
import type {
|
import type {
|
||||||
AIChatInputContext,
|
AIChatInputContext,
|
||||||
AIModelSwitchConfig,
|
|
||||||
AINetworkSearchConfig,
|
AINetworkSearchConfig,
|
||||||
AIReasoningConfig,
|
AIReasoningConfig,
|
||||||
} from '../ai-chat-input';
|
} from '../ai-chat-input';
|
||||||
@ -93,9 +92,6 @@ export class AIChatComposer extends SignalWatcher(
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor searchMenuConfig!: SearchMenuConfig;
|
accessor searchMenuConfig!: SearchMenuConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
accessor modelSwitchConfig!: AIModelSwitchConfig;
|
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor onChatSuccess: (() => void) | undefined;
|
accessor onChatSuccess: (() => void) | undefined;
|
||||||
|
|
||||||
@ -151,7 +147,6 @@ export class AIChatComposer extends SignalWatcher(
|
|||||||
.updateContext=${this.updateContext}
|
.updateContext=${this.updateContext}
|
||||||
.networkSearchConfig=${this.networkSearchConfig}
|
.networkSearchConfig=${this.networkSearchConfig}
|
||||||
.reasoningConfig=${this.reasoningConfig}
|
.reasoningConfig=${this.reasoningConfig}
|
||||||
.modelSwitchConfig=${this.modelSwitchConfig}
|
|
||||||
.docDisplayConfig=${this.docDisplayConfig}
|
.docDisplayConfig=${this.docDisplayConfig}
|
||||||
.onChatSuccess=${this.onChatSuccess}
|
.onChatSuccess=${this.onChatSuccess}
|
||||||
.trackOptions=${this.trackOptions}
|
.trackOptions=${this.trackOptions}
|
||||||
|
@ -27,7 +27,6 @@ import {
|
|||||||
import { MAX_IMAGE_COUNT } from './const';
|
import { MAX_IMAGE_COUNT } from './const';
|
||||||
import type {
|
import type {
|
||||||
AIChatInputContext,
|
AIChatInputContext,
|
||||||
AIModelSwitchConfig,
|
|
||||||
AINetworkSearchConfig,
|
AINetworkSearchConfig,
|
||||||
AIReasoningConfig,
|
AIReasoningConfig,
|
||||||
} from './type';
|
} from './type';
|
||||||
@ -320,9 +319,6 @@ export class AIChatInput extends SignalWatcher(
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor reasoningConfig!: AIReasoningConfig;
|
accessor reasoningConfig!: AIReasoningConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
|
||||||
accessor modelSwitchConfig: AIModelSwitchConfig | undefined = undefined;
|
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor docDisplayConfig!: DocDisplayConfig;
|
accessor docDisplayConfig!: DocDisplayConfig;
|
||||||
|
|
||||||
@ -442,7 +438,6 @@ export class AIChatInput extends SignalWatcher(
|
|||||||
</div>
|
</div>
|
||||||
<div class="chat-input-footer-spacer"></div>
|
<div class="chat-input-footer-spacer"></div>
|
||||||
<chat-input-preference
|
<chat-input-preference
|
||||||
.modelSwitchConfig=${this.modelSwitchConfig}
|
|
||||||
.session=${this.session}
|
.session=${this.session}
|
||||||
.onModelChange=${this._handleModelChange}
|
.onModelChange=${this._handleModelChange}
|
||||||
.modelId=${this.modelId}
|
.modelId=${this.modelId}
|
||||||
|
@ -15,8 +15,6 @@ import { ShadowlessElement } from '@blocksuite/std';
|
|||||||
import { css, html } from 'lit';
|
import { css, html } from 'lit';
|
||||||
import { property } from 'lit/decorators.js';
|
import { property } from 'lit/decorators.js';
|
||||||
|
|
||||||
import type { AIModelSwitchConfig } from './type';
|
|
||||||
|
|
||||||
export class ChatInputPreference extends SignalWatcher(
|
export class ChatInputPreference extends SignalWatcher(
|
||||||
WithDisposable(ShadowlessElement)
|
WithDisposable(ShadowlessElement)
|
||||||
) {
|
) {
|
||||||
@ -51,10 +49,6 @@ export class ChatInputPreference extends SignalWatcher(
|
|||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor session!: CopilotSessionType | undefined;
|
accessor session!: CopilotSessionType | undefined;
|
||||||
|
|
||||||
// --------- model props start ---------
|
|
||||||
@property({ attribute: false })
|
|
||||||
accessor modelSwitchConfig: AIModelSwitchConfig | undefined = undefined;
|
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor onModelChange: ((modelId: string) => void) | undefined;
|
accessor onModelChange: ((modelId: string) => void) | undefined;
|
||||||
|
|
||||||
@ -96,7 +90,6 @@ export class ChatInputPreference extends SignalWatcher(
|
|||||||
const searchItems = [];
|
const searchItems = [];
|
||||||
|
|
||||||
// model switch
|
// model switch
|
||||||
if (this.modelSwitchConfig?.visible.value) {
|
|
||||||
modelItems.push(
|
modelItems.push(
|
||||||
menu.subMenu({
|
menu.subMenu({
|
||||||
name: 'Model',
|
name: 'Model',
|
||||||
@ -111,7 +104,6 @@ export class ChatInputPreference extends SignalWatcher(
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
modelItems.push(
|
modelItems.push(
|
||||||
menu.toggleSwitch({
|
menu.toggleSwitch({
|
||||||
|
@ -14,7 +14,7 @@ export interface AIReasoningConfig {
|
|||||||
setEnabled: (state: boolean) => void;
|
setEnabled: (state: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AIModelSwitchConfig {
|
export interface AIPlaygroundConfig {
|
||||||
visible: Signal<boolean | undefined>;
|
visible: Signal<boolean | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||||
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
|
||||||
import type { EditorHost } from '@blocksuite/affine/std';
|
import type { EditorHost } from '@blocksuite/affine/std';
|
||||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||||
import type { ExtensionType } from '@blocksuite/affine/store';
|
import type { ExtensionType } from '@blocksuite/affine/store';
|
||||||
@ -21,13 +20,6 @@ export class ChatContentStreamObjects extends WithDisposable(
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background-color: rgba(0, 0, 0, 0.05);
|
background-color: rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-wrapper {
|
|
||||||
padding: 12px;
|
|
||||||
margin: 8px 0;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 0.5px solid ${unsafeCSSVarV2('layer/insideBorder/border')};
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
@ -70,14 +62,18 @@ export class ChatContentStreamObjects extends WithDisposable(
|
|||||||
.width=${this.width}
|
.width=${this.width}
|
||||||
></web-search-tool>
|
></web-search-tool>
|
||||||
`;
|
`;
|
||||||
default:
|
default: {
|
||||||
|
const name = streamObject.toolName + ' tool calling';
|
||||||
return html`
|
return html`
|
||||||
<div class="tool-wrapper">
|
<tool-call-card
|
||||||
${streamObject.toolName} tool calling...
|
.name=${name}
|
||||||
</div>
|
.host=${this.host}
|
||||||
|
.width=${this.width}
|
||||||
|
></tool-call-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private renderToolResult(streamObject: StreamObject) {
|
private renderToolResult(streamObject: StreamObject) {
|
||||||
if (streamObject.type !== 'tool-result') {
|
if (streamObject.type !== 'tool-result') {
|
||||||
@ -101,14 +97,18 @@ export class ChatContentStreamObjects extends WithDisposable(
|
|||||||
.width=${this.width}
|
.width=${this.width}
|
||||||
></web-search-tool>
|
></web-search-tool>
|
||||||
`;
|
`;
|
||||||
default:
|
default: {
|
||||||
|
const name = streamObject.toolName + ' tool result';
|
||||||
return html`
|
return html`
|
||||||
<div class="tool-wrapper">
|
<tool-result-card
|
||||||
${streamObject.toolName} tool result...
|
.name=${name}
|
||||||
</div>
|
.host=${this.host}
|
||||||
|
.width=${this.width}
|
||||||
|
></tool-result-card>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private renderRichText(text: string) {
|
private renderRichText(text: string) {
|
||||||
return html`<chat-content-rich-text
|
return html`<chat-content-rich-text
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||||
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||||
import { ShadowlessElement } from '@blocksuite/affine/std';
|
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||||
|
import { ToolIcon } from '@blocksuite/icons/lit';
|
||||||
import { css, html, type TemplateResult } from 'lit';
|
import { css, html, type TemplateResult } from 'lit';
|
||||||
import { property, state } from 'lit/decorators.js';
|
import { property, state } from 'lit/decorators.js';
|
||||||
|
|
||||||
@ -51,10 +52,10 @@ export class ToolCallCard extends WithDisposable(ShadowlessElement) {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor name!: string;
|
accessor name: string = 'Tool calling';
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor icon!: TemplateResult<1>;
|
accessor icon: TemplateResult<1> = ToolIcon();
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
private accessor dotsText = '.';
|
private accessor dotsText = '.';
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
import { WithDisposable } from '@blocksuite/affine/global/lit';
|
||||||
|
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||||
|
import { ShadowlessElement } from '@blocksuite/affine/std';
|
||||||
|
import { ToolIcon } from '@blocksuite/icons/lit';
|
||||||
|
import { css, html, type TemplateResult } from 'lit';
|
||||||
|
import { property } from 'lit/decorators.js';
|
||||||
|
|
||||||
|
export class ToolFailedCard extends WithDisposable(ShadowlessElement) {
|
||||||
|
static override styles = css`
|
||||||
|
.ai-tool-failed-wrapper {
|
||||||
|
padding: 12px;
|
||||||
|
margin: 8px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 0.5px solid ${unsafeCSSVarV2('layer/insideBorder/border')};
|
||||||
|
|
||||||
|
.ai-tool-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
color: ${unsafeCSSVarV2('button/error')};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-error-name {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 24px;
|
||||||
|
margin-left: 0px;
|
||||||
|
margin-right: auto;
|
||||||
|
color: ${unsafeCSSVarV2('button/error')};
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
accessor name: string = 'Tool calling failed';
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
accessor icon: TemplateResult<1> = ToolIcon();
|
||||||
|
|
||||||
|
protected override render() {
|
||||||
|
return html`
|
||||||
|
<div class="ai-tool-failed-wrapper">
|
||||||
|
<div class="ai-tool-header">
|
||||||
|
<div class="ai-icon">${this.icon}</div>
|
||||||
|
<div class="ai-error-name">${this.name}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ import { SignalWatcher, WithDisposable } from '@blocksuite/affine/global/lit';
|
|||||||
import { ImageProxyService } from '@blocksuite/affine/shared/adapters';
|
import { ImageProxyService } from '@blocksuite/affine/shared/adapters';
|
||||||
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
import { unsafeCSSVarV2 } from '@blocksuite/affine/shared/theme';
|
||||||
import { type EditorHost, ShadowlessElement } from '@blocksuite/affine/std';
|
import { type EditorHost, ShadowlessElement } from '@blocksuite/affine/std';
|
||||||
import { ToggleDownIcon } from '@blocksuite/icons/lit';
|
import { ToggleDownIcon, ToolIcon } from '@blocksuite/icons/lit';
|
||||||
import { type Signal } from '@preact/signals-core';
|
import { type Signal } from '@preact/signals-core';
|
||||||
import { css, html, nothing, type TemplateResult } from 'lit';
|
import { css, html, nothing, type TemplateResult } from 'lit';
|
||||||
import { property, state } from 'lit/decorators.js';
|
import { property, state } from 'lit/decorators.js';
|
||||||
@ -17,7 +17,7 @@ export class ToolResultCard extends SignalWatcher(
|
|||||||
WithDisposable(ShadowlessElement)
|
WithDisposable(ShadowlessElement)
|
||||||
) {
|
) {
|
||||||
static override styles = css`
|
static override styles = css`
|
||||||
.ai-tool-wrapper {
|
.ai-tool-result-wrapper {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@ -158,16 +158,16 @@ export class ToolResultCard extends SignalWatcher(
|
|||||||
accessor host!: EditorHost;
|
accessor host!: EditorHost;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor name!: string;
|
accessor name: string = 'Tool result';
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor icon!: TemplateResult<1> | string;
|
accessor icon: TemplateResult<1> | string = ToolIcon();
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor footerIcons: TemplateResult<1>[] | string[] = [];
|
accessor footerIcons: TemplateResult<1>[] | string[] = [];
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor results!: ToolResult[];
|
accessor results: ToolResult[] = [];
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor width: Signal<number | undefined> | undefined;
|
accessor width: Signal<number | undefined> | undefined;
|
||||||
@ -177,7 +177,7 @@ export class ToolResultCard extends SignalWatcher(
|
|||||||
|
|
||||||
protected override render() {
|
protected override render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="ai-tool-wrapper">
|
<div class="ai-tool-result-wrapper">
|
||||||
<div class="ai-tool-header" @click=${this.toggleCard}>
|
<div class="ai-tool-header" @click=${this.toggleCard}>
|
||||||
<div class="ai-icon">${this.renderIcon(this.icon)}</div>
|
<div class="ai-icon">${this.renderIcon(this.icon)}</div>
|
||||||
<div class="ai-tool-name">${this.name}</div>
|
<div class="ai-tool-name">${this.name}</div>
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
export interface ToolError {
|
||||||
|
type: 'error';
|
||||||
|
name: string;
|
||||||
|
message: string;
|
||||||
|
}
|
@ -5,6 +5,8 @@ import type { Signal } from '@preact/signals-core';
|
|||||||
import { html, nothing } from 'lit';
|
import { html, nothing } from 'lit';
|
||||||
import { property } from 'lit/decorators.js';
|
import { property } from 'lit/decorators.js';
|
||||||
|
|
||||||
|
import type { ToolError } from './type';
|
||||||
|
|
||||||
interface WebCrawlToolCall {
|
interface WebCrawlToolCall {
|
||||||
type: 'tool-call';
|
type: 'tool-call';
|
||||||
toolCallId: string;
|
toolCallId: string;
|
||||||
@ -17,14 +19,17 @@ interface WebCrawlToolResult {
|
|||||||
toolCallId: string;
|
toolCallId: string;
|
||||||
toolName: string;
|
toolName: string;
|
||||||
args: { url: string };
|
args: { url: string };
|
||||||
result: Array<{
|
result:
|
||||||
|
| Array<{
|
||||||
title: string;
|
title: string;
|
||||||
url: string;
|
url: string;
|
||||||
content: string;
|
content: string;
|
||||||
favicon: string;
|
favicon: string;
|
||||||
publishedDate: string;
|
publishedDate: string;
|
||||||
author: string;
|
author: string;
|
||||||
}>;
|
}>
|
||||||
|
| ToolError
|
||||||
|
| null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WebCrawlTool extends WithDisposable(ShadowlessElement) {
|
export class WebCrawlTool extends WithDisposable(ShadowlessElement) {
|
||||||
@ -51,8 +56,9 @@ export class WebCrawlTool extends WithDisposable(ShadowlessElement) {
|
|||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { favicon, title, content } = this.data.result[0];
|
const result = this.data.result;
|
||||||
|
if (result && Array.isArray(result)) {
|
||||||
|
const { favicon, title, content } = result[0];
|
||||||
return html`
|
return html`
|
||||||
<tool-result-card
|
<tool-result-card
|
||||||
.host=${this.host}
|
.host=${this.host}
|
||||||
@ -71,6 +77,14 @@ export class WebCrawlTool extends WithDisposable(ShadowlessElement) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<tool-call-failed
|
||||||
|
.name=${'Web reading failed'}
|
||||||
|
.icon=${WebIcon()}
|
||||||
|
></tool-call-failed>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
protected override render() {
|
protected override render() {
|
||||||
const { data } = this;
|
const { data } = this;
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ import type { Signal } from '@preact/signals-core';
|
|||||||
import { html, nothing } from 'lit';
|
import { html, nothing } from 'lit';
|
||||||
import { property } from 'lit/decorators.js';
|
import { property } from 'lit/decorators.js';
|
||||||
|
|
||||||
|
import type { ToolError } from './type';
|
||||||
|
|
||||||
interface WebSearchToolCall {
|
interface WebSearchToolCall {
|
||||||
type: 'tool-call';
|
type: 'tool-call';
|
||||||
toolCallId: string;
|
toolCallId: string;
|
||||||
@ -17,14 +19,17 @@ interface WebSearchToolResult {
|
|||||||
toolCallId: string;
|
toolCallId: string;
|
||||||
toolName: string;
|
toolName: string;
|
||||||
args: { url: string };
|
args: { url: string };
|
||||||
result: Array<{
|
result:
|
||||||
|
| Array<{
|
||||||
title: string;
|
title: string;
|
||||||
url: string;
|
url: string;
|
||||||
content: string;
|
content: string;
|
||||||
favicon: string;
|
favicon: string;
|
||||||
publishedDate: string;
|
publishedDate: string;
|
||||||
author: string;
|
author: string;
|
||||||
}>;
|
}>
|
||||||
|
| ToolError
|
||||||
|
| null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WebSearchTool extends WithDisposable(ShadowlessElement) {
|
export class WebSearchTool extends WithDisposable(ShadowlessElement) {
|
||||||
@ -50,7 +55,9 @@ export class WebSearchTool extends WithDisposable(ShadowlessElement) {
|
|||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
const results = this.data.result.map(item => {
|
const result = this.data.result;
|
||||||
|
if (result && Array.isArray(result)) {
|
||||||
|
const results = result.map(item => {
|
||||||
const { favicon, title, content } = item;
|
const { favicon, title, content } = item;
|
||||||
return {
|
return {
|
||||||
title: title,
|
title: title,
|
||||||
@ -58,9 +65,7 @@ export class WebSearchTool extends WithDisposable(ShadowlessElement) {
|
|||||||
content: content,
|
content: content,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
const footerIcons = this.data.result
|
const footerIcons = result.map(item => item.favicon).filter(Boolean);
|
||||||
.map(item => item.favicon)
|
|
||||||
.filter(Boolean);
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<tool-result-card
|
<tool-result-card
|
||||||
@ -74,6 +79,14 @@ export class WebSearchTool extends WithDisposable(ShadowlessElement) {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<tool-call-failed
|
||||||
|
.name=${'Web search failed'}
|
||||||
|
.icon=${WebIcon()}
|
||||||
|
></tool-call-failed>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
protected override render() {
|
protected override render() {
|
||||||
const { data } = this;
|
const { data } = this;
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@ import type { ChatPanelMessages } from '../../chat-panel/chat-panel-messages';
|
|||||||
import { AIProvider } from '../../provider';
|
import { AIProvider } from '../../provider';
|
||||||
import type { DocDisplayConfig, SearchMenuConfig } from '../ai-chat-chips';
|
import type { DocDisplayConfig, SearchMenuConfig } from '../ai-chat-chips';
|
||||||
import type {
|
import type {
|
||||||
AIModelSwitchConfig,
|
|
||||||
AINetworkSearchConfig,
|
AINetworkSearchConfig,
|
||||||
|
AIPlaygroundConfig,
|
||||||
AIReasoningConfig,
|
AIReasoningConfig,
|
||||||
} from '../ai-chat-input';
|
} from '../ai-chat-input';
|
||||||
import {
|
import {
|
||||||
@ -136,7 +136,7 @@ export class PlaygroundChat extends SignalWatcher(
|
|||||||
accessor reasoningConfig!: AIReasoningConfig;
|
accessor reasoningConfig!: AIReasoningConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor modelSwitchConfig!: AIModelSwitchConfig;
|
accessor playgroundConfig!: AIPlaygroundConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor appSidebarConfig!: AppSidebarConfig;
|
accessor appSidebarConfig!: AppSidebarConfig;
|
||||||
@ -320,7 +320,7 @@ export class PlaygroundChat extends SignalWatcher(
|
|||||||
.isVisible=${this._isVisible}
|
.isVisible=${this._isVisible}
|
||||||
.networkSearchConfig=${this.networkSearchConfig}
|
.networkSearchConfig=${this.networkSearchConfig}
|
||||||
.reasoningConfig=${this.reasoningConfig}
|
.reasoningConfig=${this.reasoningConfig}
|
||||||
.modelSwitchConfig=${this.modelSwitchConfig}
|
.playgroundConfig=${this.playgroundConfig}
|
||||||
.docDisplayConfig=${this.docDisplayConfig}
|
.docDisplayConfig=${this.docDisplayConfig}
|
||||||
.searchMenuConfig=${this.searchMenuConfig}
|
.searchMenuConfig=${this.searchMenuConfig}
|
||||||
></ai-chat-composer>
|
></ai-chat-composer>
|
||||||
|
@ -12,8 +12,8 @@ import type { AppSidebarConfig } from '../../chat-panel/chat-config';
|
|||||||
import { AIProvider } from '../../provider';
|
import { AIProvider } from '../../provider';
|
||||||
import type { DocDisplayConfig, SearchMenuConfig } from '../ai-chat-chips';
|
import type { DocDisplayConfig, SearchMenuConfig } from '../ai-chat-chips';
|
||||||
import type {
|
import type {
|
||||||
AIModelSwitchConfig,
|
|
||||||
AINetworkSearchConfig,
|
AINetworkSearchConfig,
|
||||||
|
AIPlaygroundConfig,
|
||||||
AIReasoningConfig,
|
AIReasoningConfig,
|
||||||
} from '../ai-chat-input';
|
} from '../ai-chat-input';
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ export class PlaygroundContent extends SignalWatcher(
|
|||||||
accessor reasoningConfig!: AIReasoningConfig;
|
accessor reasoningConfig!: AIReasoningConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor modelSwitchConfig!: AIModelSwitchConfig;
|
accessor playgroundConfig!: AIPlaygroundConfig;
|
||||||
|
|
||||||
@property({ attribute: false })
|
@property({ attribute: false })
|
||||||
accessor appSidebarConfig!: AppSidebarConfig;
|
accessor appSidebarConfig!: AppSidebarConfig;
|
||||||
@ -329,7 +329,7 @@ export class PlaygroundContent extends SignalWatcher(
|
|||||||
.doc=${this.doc}
|
.doc=${this.doc}
|
||||||
.networkSearchConfig=${this.networkSearchConfig}
|
.networkSearchConfig=${this.networkSearchConfig}
|
||||||
.reasoningConfig=${this.reasoningConfig}
|
.reasoningConfig=${this.reasoningConfig}
|
||||||
.modelSwitchConfig=${this.modelSwitchConfig}
|
.playgroundConfig=${this.playgroundConfig}
|
||||||
.appSidebarConfig=${this.appSidebarConfig}
|
.appSidebarConfig=${this.appSidebarConfig}
|
||||||
.searchMenuConfig=${this.searchMenuConfig}
|
.searchMenuConfig=${this.searchMenuConfig}
|
||||||
.docDisplayConfig=${this.docDisplayConfig}
|
.docDisplayConfig=${this.docDisplayConfig}
|
||||||
|
@ -45,6 +45,7 @@ import { ChatContentRichText } from './components/ai-message-content/rich-text';
|
|||||||
import { ChatContentStreamObjects } from './components/ai-message-content/stream-objects';
|
import { ChatContentStreamObjects } from './components/ai-message-content/stream-objects';
|
||||||
import { AIScrollableTextRenderer } from './components/ai-scrollable-text-renderer';
|
import { AIScrollableTextRenderer } from './components/ai-scrollable-text-renderer';
|
||||||
import { ToolCallCard } from './components/ai-tools/tool-call-card';
|
import { ToolCallCard } from './components/ai-tools/tool-call-card';
|
||||||
|
import { ToolFailedCard } from './components/ai-tools/tool-failed-card';
|
||||||
import { ToolResultCard } from './components/ai-tools/tool-result-card';
|
import { ToolResultCard } from './components/ai-tools/tool-result-card';
|
||||||
import { WebCrawlTool } from './components/ai-tools/web-crawl';
|
import { WebCrawlTool } from './components/ai-tools/web-crawl';
|
||||||
import { WebSearchTool } from './components/ai-tools/web-search';
|
import { WebSearchTool } from './components/ai-tools/web-search';
|
||||||
@ -167,6 +168,7 @@ export function registerAIEffects() {
|
|||||||
|
|
||||||
customElements.define('tool-call-card', ToolCallCard);
|
customElements.define('tool-call-card', ToolCallCard);
|
||||||
customElements.define('tool-result-card', ToolResultCard);
|
customElements.define('tool-result-card', ToolResultCard);
|
||||||
|
customElements.define('tool-call-failed', ToolFailedCard);
|
||||||
customElements.define('web-crawl-tool', WebCrawlTool);
|
customElements.define('web-crawl-tool', WebCrawlTool);
|
||||||
customElements.define('web-search-tool', WebSearchTool);
|
customElements.define('web-search-tool', WebSearchTool);
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// packages/frontend/core/src/blocksuite/ai/hooks/useChatPanelConfig.ts
|
// packages/frontend/core/src/blocksuite/ai/hooks/useChatPanelConfig.ts
|
||||||
import { AIModelSwitchService } from '@affine/core/modules/ai-button/services/model-switch';
|
|
||||||
import { AINetworkSearchService } from '@affine/core/modules/ai-button/services/network-search';
|
import { AINetworkSearchService } from '@affine/core/modules/ai-button/services/network-search';
|
||||||
|
import { AIPlaygroundService } from '@affine/core/modules/ai-button/services/playground';
|
||||||
import { AIReasoningService } from '@affine/core/modules/ai-button/services/reasoning';
|
import { AIReasoningService } from '@affine/core/modules/ai-button/services/reasoning';
|
||||||
import { CollectionService } from '@affine/core/modules/collection';
|
import { CollectionService } from '@affine/core/modules/collection';
|
||||||
import { DocsService } from '@affine/core/modules/doc';
|
import { DocsService } from '@affine/core/modules/doc';
|
||||||
@ -22,7 +22,7 @@ export function useAIChatConfig() {
|
|||||||
|
|
||||||
const searchService = framework.get(AINetworkSearchService);
|
const searchService = framework.get(AINetworkSearchService);
|
||||||
const reasoningService = framework.get(AIReasoningService);
|
const reasoningService = framework.get(AIReasoningService);
|
||||||
const modelSwitchService = framework.get(AIModelSwitchService);
|
const playgroundService = framework.get(AIPlaygroundService);
|
||||||
const docDisplayMetaService = framework.get(DocDisplayMetaService);
|
const docDisplayMetaService = framework.get(DocDisplayMetaService);
|
||||||
const workspaceService = framework.get(WorkspaceService);
|
const workspaceService = framework.get(WorkspaceService);
|
||||||
const searchMenuService = framework.get(SearchMenuService);
|
const searchMenuService = framework.get(SearchMenuService);
|
||||||
@ -42,8 +42,8 @@ export function useAIChatConfig() {
|
|||||||
setEnabled: reasoningService.setEnabled,
|
setEnabled: reasoningService.setEnabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
const modelSwitchConfig = {
|
const playgroundConfig = {
|
||||||
visible: modelSwitchService.visible,
|
visible: playgroundService.visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
const docDisplayConfig = {
|
const docDisplayConfig = {
|
||||||
@ -130,6 +130,6 @@ export function useAIChatConfig() {
|
|||||||
reasoningConfig,
|
reasoningConfig,
|
||||||
docDisplayConfig,
|
docDisplayConfig,
|
||||||
searchMenuConfig,
|
searchMenuConfig,
|
||||||
modelSwitchConfig,
|
playgroundConfig,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
|
|||||||
searchMenuConfig,
|
searchMenuConfig,
|
||||||
networkSearchConfig,
|
networkSearchConfig,
|
||||||
reasoningConfig,
|
reasoningConfig,
|
||||||
modelSwitchConfig,
|
playgroundConfig,
|
||||||
} = useAIChatConfig();
|
} = useAIChatConfig();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -74,7 +74,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
|
|||||||
chatPanelRef.current.searchMenuConfig = searchMenuConfig;
|
chatPanelRef.current.searchMenuConfig = searchMenuConfig;
|
||||||
chatPanelRef.current.networkSearchConfig = networkSearchConfig;
|
chatPanelRef.current.networkSearchConfig = networkSearchConfig;
|
||||||
chatPanelRef.current.reasoningConfig = reasoningConfig;
|
chatPanelRef.current.reasoningConfig = reasoningConfig;
|
||||||
chatPanelRef.current.modelSwitchConfig = modelSwitchConfig;
|
chatPanelRef.current.playgroundConfig = playgroundConfig;
|
||||||
chatPanelRef.current.extensions = editor.host.std
|
chatPanelRef.current.extensions = editor.host.std
|
||||||
.get(ViewExtensionManagerIdentifier)
|
.get(ViewExtensionManagerIdentifier)
|
||||||
.get('preview-page');
|
.get('preview-page');
|
||||||
@ -109,7 +109,7 @@ export const EditorChatPanel = forwardRef(function EditorChatPanel(
|
|||||||
networkSearchConfig,
|
networkSearchConfig,
|
||||||
searchMenuConfig,
|
searchMenuConfig,
|
||||||
reasoningConfig,
|
reasoningConfig,
|
||||||
modelSwitchConfig,
|
playgroundConfig,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <div className={styles.root} ref={containerRef} />;
|
return <div className={styles.root} ref={containerRef} />;
|
||||||
|
@ -7,8 +7,8 @@ import { FeatureFlagService } from '../feature-flag';
|
|||||||
import { GlobalStateService } from '../storage';
|
import { GlobalStateService } from '../storage';
|
||||||
import { AIButtonProvider } from './provider/ai-button';
|
import { AIButtonProvider } from './provider/ai-button';
|
||||||
import { AIButtonService } from './services/ai-button';
|
import { AIButtonService } from './services/ai-button';
|
||||||
import { AIModelSwitchService } from './services/model-switch';
|
|
||||||
import { AINetworkSearchService } from './services/network-search';
|
import { AINetworkSearchService } from './services/network-search';
|
||||||
|
import { AIPlaygroundService } from './services/playground';
|
||||||
import { AIReasoningService } from './services/reasoning';
|
import { AIReasoningService } from './services/reasoning';
|
||||||
|
|
||||||
export const configureAIButtonModule = (framework: Framework) => {
|
export const configureAIButtonModule = (framework: Framework) => {
|
||||||
@ -28,6 +28,6 @@ export function configureAIReasoningModule(framework: Framework) {
|
|||||||
framework.service(AIReasoningService, [GlobalStateService]);
|
framework.service(AIReasoningService, [GlobalStateService]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function configureAIModelSwitchModule(framework: Framework) {
|
export function configureAIPlaygroundModule(framework: Framework) {
|
||||||
framework.service(AIModelSwitchService, [FeatureFlagService]);
|
framework.service(AIPlaygroundService, [FeatureFlagService]);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import { Service } from '@toeverything/infra';
|
|||||||
|
|
||||||
import type { FeatureFlagService } from '../../feature-flag';
|
import type { FeatureFlagService } from '../../feature-flag';
|
||||||
|
|
||||||
export class AIModelSwitchService extends Service {
|
export class AIPlaygroundService extends Service {
|
||||||
constructor(private readonly featureFlagService: FeatureFlagService) {
|
constructor(private readonly featureFlagService: FeatureFlagService) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@ -22,5 +22,5 @@ export class AIModelSwitchService extends Service {
|
|||||||
visible: Signal<boolean | undefined>;
|
visible: Signal<boolean | undefined>;
|
||||||
|
|
||||||
private readonly _visible$ =
|
private readonly _visible$ =
|
||||||
this.featureFlagService.flags.enable_ai_model_switch.$;
|
this.featureFlagService.flags.enable_ai_playground.$;
|
||||||
}
|
}
|
@ -26,7 +26,7 @@ export const AFFINE_FLAGS = {
|
|||||||
configurable: false,
|
configurable: false,
|
||||||
defaultState: true,
|
defaultState: true,
|
||||||
},
|
},
|
||||||
enable_ai_model_switch: {
|
enable_ai_playground: {
|
||||||
category: 'affine',
|
category: 'affine',
|
||||||
displayName:
|
displayName:
|
||||||
'com.affine.settings.workspace.experimental-features.enable-ai-model-switch.name',
|
'com.affine.settings.workspace.experimental-features.enable-ai-model-switch.name',
|
||||||
|
@ -3,8 +3,8 @@ import { type Framework } from '@toeverything/infra';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
configureAIButtonModule,
|
configureAIButtonModule,
|
||||||
configureAIModelSwitchModule,
|
|
||||||
configureAINetworkSearchModule,
|
configureAINetworkSearchModule,
|
||||||
|
configureAIPlaygroundModule,
|
||||||
configureAIReasoningModule,
|
configureAIReasoningModule,
|
||||||
} from './ai-button';
|
} from './ai-button';
|
||||||
import { configureAppSidebarModule } from './app-sidebar';
|
import { configureAppSidebarModule } from './app-sidebar';
|
||||||
@ -107,7 +107,7 @@ export function configureCommonModules(framework: Framework) {
|
|||||||
configureCommonGlobalStorageImpls(framework);
|
configureCommonGlobalStorageImpls(framework);
|
||||||
configureAINetworkSearchModule(framework);
|
configureAINetworkSearchModule(framework);
|
||||||
configureAIReasoningModule(framework);
|
configureAIReasoningModule(framework);
|
||||||
configureAIModelSwitchModule(framework);
|
configureAIPlaygroundModule(framework);
|
||||||
configureAIButtonModule(framework);
|
configureAIButtonModule(framework);
|
||||||
configureTemplateDocModule(framework);
|
configureTemplateDocModule(framework);
|
||||||
configureBlobManagementModule(framework);
|
configureBlobManagementModule(framework);
|
||||||
|
@ -5692,6 +5692,14 @@ export function useAFFiNEI18N(): {
|
|||||||
* `Enable or disable AI model switch feature.`
|
* `Enable or disable AI model switch feature.`
|
||||||
*/
|
*/
|
||||||
["com.affine.settings.workspace.experimental-features.enable-ai-model-switch.description"](): string;
|
["com.affine.settings.workspace.experimental-features.enable-ai-model-switch.description"](): string;
|
||||||
|
/**
|
||||||
|
* `Enable AI Playground`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.experimental-features.enable-ai-playground.name"](): string;
|
||||||
|
/**
|
||||||
|
* `Enable or disable AI playground feature.`
|
||||||
|
*/
|
||||||
|
["com.affine.settings.workspace.experimental-features.enable-ai-playground.description"](): string;
|
||||||
/**
|
/**
|
||||||
* `Database Full Width`
|
* `Database Full Width`
|
||||||
*/
|
*/
|
||||||
|
@ -1423,6 +1423,8 @@
|
|||||||
"com.affine.settings.workspace.experimental-features.enable-ai-network-search.description": "Enable or disable AI Network Search feature.",
|
"com.affine.settings.workspace.experimental-features.enable-ai-network-search.description": "Enable or disable AI Network Search feature.",
|
||||||
"com.affine.settings.workspace.experimental-features.enable-ai-model-switch.name": "Enable AI Model Switch",
|
"com.affine.settings.workspace.experimental-features.enable-ai-model-switch.name": "Enable AI Model Switch",
|
||||||
"com.affine.settings.workspace.experimental-features.enable-ai-model-switch.description": "Enable or disable AI model switch feature.",
|
"com.affine.settings.workspace.experimental-features.enable-ai-model-switch.description": "Enable or disable AI model switch feature.",
|
||||||
|
"com.affine.settings.workspace.experimental-features.enable-ai-playground.name": "Enable AI Playground",
|
||||||
|
"com.affine.settings.workspace.experimental-features.enable-ai-playground.description": "Enable or disable AI playground feature.",
|
||||||
"com.affine.settings.workspace.experimental-features.enable-database-full-width.name": "Database Full Width",
|
"com.affine.settings.workspace.experimental-features.enable-database-full-width.name": "Database Full Width",
|
||||||
"com.affine.settings.workspace.experimental-features.enable-database-full-width.description": "The database will be displayed in full-width mode.",
|
"com.affine.settings.workspace.experimental-features.enable-database-full-width.description": "The database will be displayed in full-width mode.",
|
||||||
"com.affine.settings.workspace.experimental-features.enable-database-attachment-note.name": "Database Attachment Note",
|
"com.affine.settings.workspace.experimental-features.enable-database-attachment-note.name": "Database Attachment Note",
|
||||||
|
@ -71,6 +71,32 @@ update_app_stream_version() {
|
|||||||
rm "$file_path".bak
|
rm "$file_path".bak
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_ios_marketing_version() {
|
||||||
|
local file_path=$1
|
||||||
|
local new_version=$2
|
||||||
|
|
||||||
|
# Check if file exists
|
||||||
|
if [ ! -f "$file_path" ]; then
|
||||||
|
echo "Error: File does not exist at $file_path."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Updating $file_path with MARKETING_VERSION $new_version"
|
||||||
|
|
||||||
|
# Use sed to replace the MARKETING_VERSION value with the new version
|
||||||
|
sed -i.bak -E "s/MARKETING_VERSION = [^;]*;/MARKETING_VERSION = $new_version;/g" "$file_path"
|
||||||
|
|
||||||
|
# Check if sed command succeeded
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Error: Failed to update the MARKETING_VERSION."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "MARKETING_VERSION in $file_path updated to $new_version"
|
||||||
|
|
||||||
|
rm "$file_path".bak
|
||||||
|
}
|
||||||
|
|
||||||
new_version=$1
|
new_version=$1
|
||||||
|
|
||||||
update_app_version_in_helm_charts ".github/helm/affine/Chart.yaml" "$new_version"
|
update_app_version_in_helm_charts ".github/helm/affine/Chart.yaml" "$new_version"
|
||||||
@ -80,3 +106,5 @@ update_app_version_in_helm_charts ".github/helm/affine/charts/renderer/Chart.yam
|
|||||||
update_app_version_in_helm_charts ".github/helm/affine/charts/doc/Chart.yaml" "$new_version"
|
update_app_version_in_helm_charts ".github/helm/affine/charts/doc/Chart.yaml" "$new_version"
|
||||||
|
|
||||||
update_app_stream_version "packages/frontend/apps/electron/resources/affine.metainfo.xml" "$new_version"
|
update_app_stream_version "packages/frontend/apps/electron/resources/affine.metainfo.xml" "$new_version"
|
||||||
|
|
||||||
|
update_ios_marketing_version "packages/frontend/apps/ios/App/App.xcodeproj/project.pbxproj" "$new_version"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user