Skip to content

Commit

Permalink
Add "Add to AI chat" links to search results (Special:Search)
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardspec committed Dec 7, 2024
1 parent 043d8c9 commit b2e3eda
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 0 deletions.
25 changes: 25 additions & 0 deletions extension.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@
}
},
"AutoloadClasses": {
"MediaWiki\\AskAI\\Hooks": "includes/Hooks.php",
"MediaWiki\\AskAI\\SpecialAI": "includes/SpecialAI.php",
"MediaWiki\\AskAI\\Service\\IExternalService": "includes/Service/IExternalService.php",
"MediaWiki\\AskAI\\Service\\DebugService": "includes/Service/DebugService.php",
"MediaWiki\\AskAI\\Service\\OpenAI": "includes/Service/OpenAI.php",
"MediaWiki\\AskAI\\Service\\ServiceFactory": "includes/Service/ServiceFactory.php"
},
"HookHandlers": {
"main": {
"class": "MediaWiki\\AskAI\\Hooks"
}
},
"Hooks": {
"SpecialSearchResultsPrepend": "main"
},
"ExtensionMessagesFiles": {
"AIAlias": "AskAI.alias.php"
},
Expand Down Expand Up @@ -62,6 +71,22 @@
"dependencies": [
"mediawiki.Title"
]
},
"ext.askai.search": {
"scripts": [
"ext.askai.search.js"
],
"targets": [
"desktop",
"mobile"
],
"messages": [
"askai-search-add",
"askai-search-adding",
"askai-search-add-failed",
"askai-search-add-not-found",
"askai-search-view"
]
}
},
"ResourceFileModulePaths": {
Expand Down
5 changes: 5 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
"askai-field-response": "Response from the AI:",
"askai-openai-failed": "Failed to contact OpenAI: $1",
"askai-openai-not-configured": "Error: OpenAI not configured: apiKey, apiUrl or model are not set.",
"askai-search-add": "Add to AI chat",
"askai-search-adding": "Adding...",
"askai-search-add-failed": "Failed to load the page.",
"askai-search-add-not-found": "Failed to locate the paragraphs that are referenced in this search result.",
"askai-search-view": "View AI chat",
"askai-source": "(Source #$1) [$2]",
"askai-submit-failed": "HTTP error when submitting the form: $1",
"askai-unknown-service": "Not configured: incorrect value of $wgAskAIServiceClass.",
Expand Down
5 changes: 5 additions & 0 deletions i18n/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@
"askai-field-response": "Label of readonly field that will show the response from the AI.",
"askai-openai-failed": "Error message if HTTP request to OpenAI resulted in an error.",
"askai-openai-not-configured": "Error message if OpenAI API key, etc. are not configured.",
"askai-search-add": "Link on Special:Search that adds this result to AI chat.",
"askai-search-adding": "Temporarily shown while waiting for result to be added to AI chat.",
"askai-search-add-failed": "Error when we couldn't load the page from the search results.",
"askai-search-add-not-found": "Error when the text from search results wasn't found anywhere in the article.",
"askai-search-view": "Link on Special:Search that redirects user to Special:AI.",
"askai-source": "Name of source document (will be supplied to AI as part of instructions). $1 - index of document (1, 2, 3, etc.), $2 - page name.",
"askai-submit-failed": "Error message if HTTP POST request to Special:AI resulted in an error.",
"askai-unknown-service": "Error message if failed to create an AI service.",
Expand Down
44 changes: 44 additions & 0 deletions includes/Hooks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/**
* Implements AskAI extension for MediaWiki.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*
* @file
*/

namespace MediaWiki\AskAI;

use MediaWiki\Hook\SpecialSearchResultsPrependHook;
use OutputPage;
use SpecialSearch;

/**
* Hooks of Extension:AskAI.
*/
class Hooks implements SpecialSearchResultsPrependHook {
/**
* Add our JavaScript module to Special:Search.
* @param SpecialSearch $specialSearch
* @param OutputPage $out
* @param string $term
* @return bool|void
*/
public function onSpecialSearchResultsPrepend( $specialSearch, $out, $term ) {
$out->addModules( 'ext.askai.search' );
}
}
70 changes: 70 additions & 0 deletions modules/ext.askai.search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* Shows "Add to AI chat" link near every search result on Special:Search. */

$( function () {
const $results = $( '.mw-search-result' );
if ( !$results.length ) {
return;
}

const addedSources = [];

/* Redirect to Special:AI, providing it with the previously added sources */
function goToSpecial() {
const title = new mw.Title( 'Special:AI' );
window.location.href = title.getUrl( {
wpPages: addedSources.join( '\n' )
} );
}

/* Handler of "Add to AI chat" link */
function addToAI() {
const $addLink = $( this ),
$res = $addLink.parents( '.mw-search-result' ),
pageLink = $res.find( 'a' )[ 0 ],
matchedSentences = $res.find( '.searchresult' ).text().trim().split( /\.\s/ );

const $loading = $( '<span>' )
.attr( 'class', 'mw-askai-search-adding' )
.append( mw.msg( 'askai-search-adding' ) );

$addLink.replaceWith( $loading );

// Download the article and find the paragraph(s) that contain "matchedText".
$.get( pageLink.href ).done( ( html ) => {
const parNumbers = [];

$( '<div>' ).append( html ).find( '.mw-parser-output > p' ).each( ( idx, p ) => {
for ( const sentence of matchedSentences ) {
if ( p.innerText.indexOf( sentence ) !== -1 ) {
parNumbers.push( idx );
return;
}
}
} );

if ( !parNumbers.length ) {
$loading.replaceWith( mw.msg( 'askai-search-add-not-found' ) );
return;
}

addedSources.push( pageLink.title + '#p' + parNumbers.join( ',' ) );

$loading.replaceWith( $( '<a>' )
.attr( 'class', 'mw-askai-search-view' )
.append( mw.msg( 'askai-search-view' ) )
.click( goToSpecial )
);
} ).fail( () => {
$loading.replaceWith( mw.msg( 'askai-search-add-failed' ) );
} );
}

// Every result should have "Add to AI chat" link
$results.each( ( idx, result ) => {
$( result ).find( '.mw-search-result-data' ).append( ' ', $( '<a>' )
.attr( 'class', 'mw-askai-search-add' )
.append( mw.msg( 'askai-search-add' ) )
.click( addToAI )
);
} );
} );

0 comments on commit b2e3eda

Please sign in to comment.