-
Notifications
You must be signed in to change notification settings - Fork 6
Fix sse size mismatch 15094702859884413816 #216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
de42cb7
3cfd09d
1f66a51
a260929
ec9623a
19d1200
84a6f0f
52f8b3d
59f66bf
2769e81
7aec98d
39a1e98
1395e00
54478fe
16dac02
a5e667b
24aa502
98012b7
53a4462
1eef9b5
50b144d
d88f1ec
a262182
83b256a
0349b85
e219be1
e1f990c
f7c85cd
517963d
ca97b51
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,7 +60,7 @@ | |
|
|
||
| // todo: app_api is always available now (composer update) | ||
| try { | ||
| $appApiFunctions = \OCP\Server::get(\OCA\AppAPI\PublicFunctions::class); | ||
| $appApiFunctions = $this->getAppApiFunctions(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need for this change, the method |
||
| } catch (ContainerExceptionInterface|NotFoundExceptionInterface $e) { | ||
| throw new RuntimeException('Could not get AppAPI public functions'); | ||
| } | ||
|
|
@@ -287,10 +287,24 @@ | |
| } | ||
|
|
||
| $params = array_map(function (Source $source) { | ||
| $contents = $source->content; | ||
| if ($source->size !== null) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this check would not be required after the size is always available in the Source class |
||
| if (class_exists('\GuzzleHttp\Psr7\Utils')) { | ||
| $stream = \GuzzleHttp\Psr7\Utils::streamFor($source->content); | ||
|
Check failure on line 293 in lib/Service/LangRopeService.php
|
||
| } else { | ||
| $stream = \GuzzleHttp\Psr7\stream_for($source->content); | ||
| } | ||
| $contents = \GuzzleHttp\Psr7\FnStream::decorate($stream, [ | ||
| 'getSize' => function () use ($source) { | ||
| return $source->size; | ||
| }, | ||
| ]); | ||
| } | ||
|
|
||
| return [ | ||
| 'name' => 'sources', | ||
| 'filename' => $source->reference, // eg. 'files__default: 555' | ||
| 'contents' => $source->content, | ||
| 'contents' => $contents, | ||
| 'headers' => [ | ||
| 'userIds' => implode(',', $source->userIds), | ||
| 'title' => $source->title, | ||
|
|
@@ -424,4 +438,8 @@ | |
|
|
||
| return $llmResponse . $output; | ||
| } | ||
|
|
||
| protected function getAppApiFunctions() { | ||
| return \OCP\Server::get(\OCA\AppAPI\PublicFunctions::class); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,6 +39,15 @@ public function scanUserFiles(string $userId, array $mimeTypeFilter, ?string $di | |
| $userFolder = $this->root->getUserFolder($userId)->get($directory); | ||
| } | ||
|
|
||
| if ($userFolder instanceof File) { | ||
| $source = $this->getSourceFromFile($mimeTypeFilter, $userFolder); | ||
| if ($source !== null) { | ||
| $this->langRopeService->indexSources([$source]); | ||
| yield $source; | ||
| } | ||
| return []; | ||
| } | ||
|
|
||
|
Comment on lines
+42
to
+50
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be in a separate PR |
||
| yield from ($this->scanDirectory($mimeTypeFilter, $userFolder)); | ||
| return []; | ||
| } | ||
|
|
@@ -123,6 +132,7 @@ public function getSourceFromFile(array $mimeTypeFilter, File $node): ?Source { | |
| $node->getMTime(), | ||
| $node->getMimeType(), | ||
| $providerKey, | ||
| (int)$node->getSize(), | ||
| ); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -16,6 +16,7 @@ public function __construct( | |||||
| public int|string $modified, | ||||||
| public string $type, | ||||||
| public string $provider, | ||||||
| public ?int $size = null, | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| ) { | ||||||
| } | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| * Serving Flask app 'mock_server' | ||
| * Debug mode: off | ||
| [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m | ||
| * Running on all addresses (0.0.0.0) | ||
| * Running on http://127.0.0.1:23000 | ||
| * Running on http://192.168.0.2:23000 | ||
| [33mPress CTRL+C to quit[0m | ||
| 127.0.0.1 - - [05/Feb/2026 19:24:49] "PUT /loadSources HTTP/1.1" 200 - | ||
| 127.0.0.1 - - [05/Feb/2026 19:31:28] "[31m[1mPUT /loadSources HTTP/1.1[0m" 400 - | ||
| 127.0.0.1 - - [05/Feb/2026 19:32:18] "PUT /loadSources HTTP/1.1" 200 - | ||
| 127.0.0.1 - - [05/Feb/2026 19:32:20] "[31m[1mPUT /loadSources HTTP/1.1[0m" 400 - |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <?php | ||
| define('NC_CLI_MODE', true); | ||
| require_once '/var/www/html/lib/base.php'; | ||
|
|
||
| use OCP\Server; | ||
| use OCP\Files\IRootFolder; | ||
|
|
||
| try { | ||
| $rootFolder = Server::get(IRootFolder::class); | ||
| $userFolder = $rootFolder->getUserFolder('admin'); | ||
|
|
||
| if ($userFolder->nodeExists('test.txt')) { | ||
| $file = $userFolder->get('test.txt'); | ||
| $file->delete(); | ||
| } | ||
|
|
||
| $file = $userFolder->newFile('test.txt'); | ||
| // Write 1MB of data | ||
| $file->putContent(str_repeat('A', 1024 * 1024)); | ||
|
|
||
| echo "Created encrypted test.txt successfully.\n"; | ||
|
|
||
| } catch (\Exception $e) { | ||
| echo "Error creating file: " . $e->getMessage() . "\n"; | ||
| exit(1); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| <?php | ||
| define('NC_CLI_MODE', true); | ||
| require_once '/var/www/html/lib/base.php'; | ||
|
|
||
| use OCP\Server; | ||
| use OCP\Files\IRootFolder; | ||
|
|
||
| function checkFile($path) { | ||
| try { | ||
| $rootFolder = Server::get(IRootFolder::class); | ||
| $userFolder = $rootFolder->getUserFolder('admin'); | ||
| if (!$userFolder->nodeExists($path)) { | ||
| echo "File $path not found.\n"; | ||
| return; | ||
| } | ||
| $file = $userFolder->get($path); | ||
|
|
||
| $reportedSize = $file->getSize(); | ||
| echo "File::getSize() for $path: " . $reportedSize . "\n"; | ||
|
|
||
| $handle = $file->fopen('rb'); | ||
| $stat = fstat($handle); | ||
| echo "fstat()['size'] for $path: " . $stat['size'] . "\n"; | ||
|
|
||
| $contents = stream_get_contents($handle); | ||
| $actualReadSize = strlen($contents); | ||
| echo "Actual Read Size for $path: " . $actualReadSize . "\n"; | ||
|
|
||
| echo "Mismatch for $path: " . ($reportedSize - $actualReadSize) . "\n"; | ||
| } catch (\Exception $e) { | ||
| echo "Error checking $path: " . $e->getMessage() . "\n"; | ||
| } | ||
| } | ||
|
|
||
| checkFile('test.txt'); | ||
| checkFile('Nextcloud Manual.pdf'); // Check the default file too |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| services: | ||
| nextcloud: | ||
| image: nextcloud:latest | ||
| environment: | ||
| - NEXTCLOUD_ADMIN_USER=admin | ||
| - NEXTCLOUD_ADMIN_PASSWORD=password | ||
| volumes: | ||
| - ../../:/var/www/html/custom_apps/context_chat | ||
| ports: | ||
| - "8080:80" | ||
|
|
||
| context_chat_backend: | ||
| image: python:3.9-slim | ||
| command: sh -c "pip install flask && python /mock_server.py" | ||
| volumes: | ||
| - ./mock_server.py:/mock_server.py | ||
| networks: | ||
| default: | ||
| aliases: | ||
| - context_chat_backend |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| from flask import Flask, request, jsonify | ||
| import sys | ||
|
|
||
| app = Flask(__name__) | ||
|
|
||
| @app.route('/heartbeat', methods=['GET']) | ||
| def heartbeat(): | ||
| return jsonify({"status": "ok"}), 200 | ||
|
|
||
| @app.route('/loadSources', methods=['PUT']) | ||
| def load_sources(): | ||
| content_length = request.headers.get('Content-Length') | ||
| if content_length: | ||
| content_length = int(content_length) | ||
|
|
||
| body = request.get_data() | ||
| actual_length = len(body) | ||
|
|
||
| print(f"Header Content-Length: {content_length}") | ||
| print(f"Actual Body Length: {actual_length}") | ||
|
|
||
| if content_length is not None and content_length != actual_length: | ||
| print("FAIL: Size Mismatch") | ||
| return jsonify({"error": "Size Mismatch"}), 400 | ||
|
|
||
| print("SUCCESS") | ||
| return jsonify({ | ||
| "loaded_sources": ["test_source"], | ||
| "sources_to_retry": [] | ||
| }), 200 | ||
|
|
||
| if __name__ == '__main__': | ||
| app.run(host='0.0.0.0', port=23000) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| <?php | ||
| define('NC_CLI_MODE', true); | ||
| require_once '/var/www/html/console.php'; | ||
|
|
||
| use OCP\Server; | ||
| use OCA\AppAPI\Db\ExApp; | ||
| use OCA\AppAPI\Db\ExAppMapper; | ||
|
|
||
| try { | ||
| if (!class_exists(ExAppMapper::class)) { | ||
| echo "AppAPI classes not found.\n"; | ||
| exit(1); | ||
| } | ||
|
|
||
| $mapper = Server::get(ExAppMapper::class); | ||
|
|
||
| // Try to find existing | ||
| try { | ||
| $existing = $mapper->find('context_chat_backend'); | ||
| $mapper->delete($existing); | ||
| echo "Deleted existing registration.\n"; | ||
| } catch (\Exception $e) { | ||
| // Not found, ignore | ||
| } | ||
|
|
||
| $exApp = new ExApp(); | ||
| $exApp->setAppId('context_chat_backend'); | ||
| $exApp->setName('Context Chat Backend'); | ||
| $exApp->setDeployMethod('manual_install'); | ||
| $exApp->setVersion('1.0.0'); | ||
| $exApp->setEnabled(1); | ||
| $exApp->setHost('context_chat_backend'); | ||
| $exApp->setPort(23000); | ||
| $exApp->setProtocol('http'); | ||
| $exApp->setSecret('secret'); | ||
| $exApp->setHash('hash'); | ||
| $exApp->setLastUpdated(time()); | ||
|
|
||
| // Set other required fields if any (based on standard ExApp entity) | ||
| // Some versions require 'scopes' or 'daemon_config_name' | ||
| if (method_exists($exApp, 'setDaemonConfigName')) { | ||
| $exApp->setDaemonConfigName('manual_install'); | ||
| } | ||
|
|
||
| $mapper->insert($exApp); | ||
|
|
||
| echo "Registered context_chat_backend successfully via Mapper.\n"; | ||
|
|
||
| } catch (\Exception $e) { | ||
| echo "Error registering app: " . $e->getMessage() . "\n"; | ||
| exit(1); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| #!/bin/bash | ||
| set -e | ||
|
|
||
| # Start containers | ||
| docker-compose up -d | ||
|
|
||
| echo "Waiting for container to accept commands..." | ||
| sleep 10 | ||
|
|
||
| # Check if Nextcloud is installed | ||
| echo "Checking Nextcloud status..." | ||
| if docker-compose exec -u 33 nextcloud php occ status | grep -q "installed: true"; then | ||
| echo "Nextcloud is already installed." | ||
| else | ||
| echo "Nextcloud is not installed. Installing..." | ||
| docker-compose exec -u 33 nextcloud php occ maintenance:install \ | ||
| --database "sqlite" \ | ||
| --admin-user "admin" \ | ||
| --admin-pass "password" | ||
| fi | ||
|
|
||
| echo "Waiting for Nextcloud to be fully ready..." | ||
| max_retries=10 | ||
| count=0 | ||
| while [ $count -lt $max_retries ]; do | ||
| if docker-compose exec -u 33 nextcloud php occ status | grep -q "installed: true"; then | ||
| echo "Nextcloud is ready." | ||
| break | ||
| fi | ||
| echo "Waiting for status update... (Attempt $((count+1))/$max_retries)" | ||
| sleep 5 | ||
| count=$((count+1)) | ||
| done | ||
|
|
||
| if [ $count -eq $max_retries ]; then | ||
| echo "Timeout waiting for Nextcloud to be ready." | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "Configuring Nextcloud..." | ||
|
|
||
| # Enable encryption | ||
| docker-compose exec -u 33 nextcloud php occ app:enable encryption | ||
| docker-compose exec -u 33 nextcloud php occ encryption:enable | ||
| docker-compose exec -u 33 nextcloud php occ encryption:enable-master-key | ||
|
|
||
| # Enable apps | ||
| docker-compose exec -u 33 nextcloud php occ app:enable context_chat | ||
| docker-compose exec -u 33 nextcloud php occ app:enable app_api | ||
|
|
||
| # Register Mock Backend via OCC | ||
| echo "Cleaning up previous registrations..." | ||
| docker-compose exec -u 33 nextcloud php occ app_api:app:unregister context_chat_backend --force --no-interaction || true | ||
| docker-compose exec -u 33 nextcloud php occ app_api:daemon:unregister manual_install --no-interaction || true | ||
|
|
||
| echo "Registering Mock Backend..." | ||
|
|
||
| # Register daemon config | ||
| # Using just hostname for daemon, allowing app port to be appended correctly | ||
| docker-compose exec -u 33 nextcloud php occ app_api:daemon:register manual_install "Manual Install" manual-install http context_chat_backend http://localhost --no-interaction || true | ||
|
|
||
| # Register the app | ||
| # We use --force-scopes to avoid interactive prompts | ||
| docker-compose exec -u 33 nextcloud php occ app_api:app:register context_chat_backend manual_install --json-info '{"id":"context_chat_backend","name":"Context Chat Backend","deploy_method":"manual_install","version":"1.0.0","secret":"secret","host":"context_chat_backend","port":23000,"scopes":[],"protocol":"http","system_app":0}' --force-scopes --no-interaction || true | ||
|
|
||
| # Enable the app (it was listed as disabled) | ||
| echo "Enabling Context Chat Backend..." | ||
| docker-compose exec -u 33 nextcloud php occ app_api:app:enable context_chat_backend --no-interaction || true | ||
|
|
||
| # Debug: List registered apps | ||
| echo "Listing AppAPI apps..." | ||
| docker-compose exec -u 33 nextcloud php occ app_api:app:list | ||
|
|
||
| # Configure context_chat | ||
| docker-compose exec -u 33 nextcloud php occ config:app:set context_chat backend_init --value true | ||
|
|
||
| # Create test file | ||
| echo "Creating test file via VFS (Encrypted)..." | ||
| docker-compose cp create_test_file.php nextcloud:/var/www/html/create_test_file.php | ||
| docker-compose exec -u 33 nextcloud php /var/www/html/create_test_file.php | ||
|
|
||
| # Verify file existence via PHP | ||
| echo "Verifying file existence in Nextcloud VFS..." | ||
| if docker-compose exec -u 33 nextcloud php -r 'define("NC_CLI_MODE", true); require_once "/var/www/html/lib/base.php"; echo \OCP\Server::get(\OCP\Files\IRootFolder::class)->getUserFolder("admin")->nodeExists("test.txt") ? "YES" : "NO";' | grep -q "YES"; then | ||
| echo "SUCCESS: test.txt found in Nextcloud VFS." | ||
| else | ||
| echo "FAILURE: test.txt NOT found in Nextcloud VFS." | ||
| exit 1 | ||
| fi | ||
|
|
||
| # DEBUG: Check Sizes | ||
| echo "DEBUG: Checking file sizes..." | ||
| docker-compose cp debug_sizes.php nextcloud:/var/www/html/debug_sizes.php | ||
| docker-compose exec -u 33 nextcloud php /var/www/html/debug_sizes.php | ||
|
|
||
| # Run Indexer on the specific file | ||
| echo "Running Scan (Direct Indexing) on test.txt..." | ||
| docker-compose exec -u 33 nextcloud php occ context_chat:scan admin --directory test.txt | ||
|
|
||
| # Check logs | ||
| echo "Checking backend logs..." | ||
| docker-compose logs --no-log-prefix context_chat_backend | ||
|
|
||
| echo "Test completed successfully." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this change should be done in
lib/BackgroundJobs/SubmitContentJob.phptoo