Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions doc/proposals/2025/gsoc/application_ayaan_ai_ui_designer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
### About

1. Full Name - Mohammed Ayaan
2. Contact info (email, phone, etc.) - ayaan.md.blr@gmail.com, 99025 87579
3. Discord handle
4. Home page (if any)
5. Blog (if any)
6. GitHub profile link - https://github.com/ayaan-md-blr
7. Twitter, LinkedIn, other socials - https://www.linkedin.com/in/md-ayaan-blr/
8. Time zone - UTC+05:30
9. Link to a resume - https://drive.google.com/file/d/1kICrybHZfWLkmSFGOIfv9nFpnef14DPG/view?usp=sharing

### University Info

1. University name - PES University Bangalore
2. Program you are enrolled in (Degree & Major/Minor) - BTech (AI/ML)
3. Year - 2023
4. Expected graduation date - 2027

### Motivation & Past Experience

Short answers to the following questions (Add relevant links wherever you can):

1. Have you worked on or contributed to a FOSS project before? Can you attach repo links or relevant PRs?

No. My first experience is with apidash. I have raised a PR for issue #122(https://github.com/foss42/apidash/pull/713) and
had a good learning. Fairly comfortable with the process now
and looking forward to contribute and work towards merging the PR in the apidash repo.

2. What is your one project/achievement that you are most proud of? Why?

I am proud of my self-learning journey in the AI area so far. I am equipped with considerable predictive and generative AI concepts and related tools/apis.
I started with the perception that AI is new, exciting but extremely difficult. I overcame this challenge using multiple learning resources and balancing with
my college academics and have been able to achieve much more than my peer group in terms of learning.
Looking forward to learning and contributing to the open source space and add a new level to my learning journey.

3. What kind of problems or challenges motivate you the most to solve them?

DSA related problems challenged me the most which also pushed me to solve them. I was able to solve complex problems in trees, graphs,
recursion which I found very interesting.
I am also part of the avions (college club related to aviation and aerospace) where we are building working models of airplanes. It is very challenging and at the
same time motivating to make those models from scratch and fly them.

4. Will you be working on GSoC full-time? In case not, what will you be studying or working on while working on the project?

Yes I can contribute full time. I dont have any other engagements since it will be my summer break.

5. Do you mind regularly syncing up with the project mentors?

Definitely not. This is the opportunity I am looking forward to where I can work with the bright minds and gain guidance and knowledge. I would be available for
any form of communication as required by the assignment.

6. What interests you the most about API Dash?

The simplicity of the gitrepo attracted me to this project. It is very easy to understand and very well written.

7. Can you mention some areas where the project can be improved?

Developer documentation w.r.t to the components, system design, best practices, coding standards, testing standards will increase the productivity of contributors.
Also I feel there can be improvement in the look and feel of the user interface in terms of making it appear attractive and also enhance usability.

### Project Proposal Information

1. Proposal Title - AI UI Designer for APIs (#617)
2. Abstract:
Develop an AI Agent which transforms API responses into dynamic, user-friendly UI components, enabling developers to visualize and interact with data effortlessly.
I plan to address this by building a new component ai_ui_agent which uses ollama models suitable for codegen (codellama or deepseek probably) to generate the flutter
widgets which can be plugged into apidash ui. We can use third party component fl_chart for the charts generation.
3. Detailed Description

```
To implement this we need to carry out the below tasks in order -

Task1:

Evaluate the Ollama supported LLMs with good code generation capability.

We need to attempt several prompts which give us the output as required.
We need the prompt to
- List the suitable widgets (data table/ chart/ card/ form) for the given json data.
- The prompts should be fine tuned to generate different types of widgets as chosen by user.
- The prompts should also have placeholders for customizations (Searching, sorting, custom labels in charts)
- The prompts should be fine tuned to provide the look and feel of the apidash ui.
- The prompts should give good performance as well as provide accuracy of output.
At the end of this task we should have working prompts as per the requirement.

Task2: Build the ai_ui_agent component in the lib folder of the repo which encapsulates both the back end logic and ui widgets.
At the end of this task we expect a working component with the below structure :
ai_ui_agent
- features
ai_ui_agent_codegen.dart (This will contain the fine tuned prompts for code generation)
exporter.dart (This will contain the logic to export the generated flutter widget)
- providers
ai_ui_agent_providers.dart (Will hold the generated flutter code as state/ available for download)
- services
ai_ui_agent_service.dart (Will invoke the ollama service using ollama_dart package)
- widgets
ai_ui_widget.dart (container widget for the generated code)
(any other widgets required for customizations/styles)
- utils
validate_widget.dart (This should perform some basic validation/compilation to ensure the generated component can get rendered/exported successfully)
ai_ui_agent.dart

Task3: Integrating this component with the response_pane widget
screens/home_page/editor_pane/details_card/response_pane.dart (Add a new button on click - render the ai_ui_widget in a pop up.)

Task4: Writing unit and integration tests

Task5: Perform functional testing with different apis and response formats.
This will be crucial to ensure it works with different apis with different json structures.
This task may involve fine tuning/fixing the prompts as well.

Taks6: Updating the dev guide and user guide

```

4. Weekly Timeline:

| Week | Focus | Key Deliverables & Achievements |
| -------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| **Week 1** | Community Bonding and dev env setup | Connect with mentors. Understand project expectations. Install and configure dev env. |
| **Week 2-3** | Task1: Evaluate Ollama codegen model and prompts creation | Working prompts and finalized Ollama ai model |
| **Week 4-5** | Task2: Build ai_ui_agent | Features and Services |
| **Week 6-7** | Task2,3: Build ai_ui_agent | widgets, providers and utils |
| **Week 8-9** | Task4,5: unit, integration and functional testing | Unit, integration tests, meet code coverage |
| **Week 9-10** | Task6: Documentation | Update Dev guide, User Guide, Readme, Changelog |
| **Week 10-12** | Feedback and wrapup | Implement any final feedback from mentors. Open to pick up other issue related to importers. |
3 changes: 2 additions & 1 deletion lib/consts.dart
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ enum CodegenLanguage {
enum ImportFormat {
curl("cURL"),
postman("Postman Collection v2.1"),
insomnia("Insomnia v4");
insomnia("Insomnia v4"),
har("Har v1.2");

const ImportFormat(this.label);
final String label;
Expand Down
1 change: 1 addition & 0 deletions lib/importer/importer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class Importer {
.toList(),
ImportFormat.postman => PostmanIO().getHttpRequestModelList(content),
ImportFormat.insomnia => InsomniaIO().getHttpRequestModelList(content),
ImportFormat.har => HarParserIO().getHttpRequestModelList(content),
};
}
}
Expand Down
135 changes: 135 additions & 0 deletions packages/apidash_core/lib/import_export/har_io.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import 'package:har_parser/har_parser.dart' as hp;
import 'package:seed/seed.dart';
import '../consts.dart';
import '../models/models.dart';
import '../utils/utils.dart';

class HarParserIO {
List<(String?, HttpRequestModel)>? getHttpRequestModelList(String content) {
content = content.trim();
try {
final hl = hp.harLogFromJsonStr(content);
final requests = hp.getRequestsFromHarLog(hl);
return requests
.map((req) => (req.$2.url, harRequestToHttpRequestModel(req.$2)))
.toList();
} catch (e) {
return null;
}
}

HttpRequestModel harRequestToHttpRequestModel(hp.Request request) {
HTTPVerb method;

try {
method = HTTPVerb.values.byName((request.method ?? "").toLowerCase());
} catch (e) {
method = kDefaultHttpMethod;
}
String url = stripUrlParams(request.url ?? "");
List<NameValueModel> headers = [];
List<bool> isHeaderEnabledList = [];

List<NameValueModel> params = [];
List<bool> isParamEnabledList = [];

for (var header in request.headers ?? <hp.Header>[]) {
var name = header.name ?? "";
var value = header.value;
var activeHeader = header.disabled ?? false;
headers.add(NameValueModel(name: name, value: value));
isHeaderEnabledList.add(!activeHeader);
}

for (var query in request.queryString ?? <hp.Query>[]) {
var name = query.name ?? "";
var value = query.value;
var activeQuery = query.disabled ?? false;
params.add(NameValueModel(name: name, value: value));
isParamEnabledList.add(!activeQuery);
}

ContentType bodyContentType = kDefaultContentType;
String? body;
List<FormDataModel>? formData = [];

if (request.postData?.mimeType == "application/json") {
bodyContentType = ContentType.json;
body = request.postData?.text;
}
FormDataType formDataType = FormDataType.text;
if (request.postData?.mimeType == "application/x-www-form-urlencoded") {
bodyContentType = ContentType.formdata;
var formDataStr = request.postData?.text;
Map<String, String> parsedData = parseFormData(formDataStr);
parsedData.forEach((key, value) {
formDataType = FormDataType.text;
var name = key ?? "";
var val = value ?? "";
formData.add(FormDataModel(
name: name,
value: val,
type: formDataType,
));
});
}

if (request.postData?.mimeType == "multipart/form-data") {
bodyContentType = ContentType.formdata;
var name, val;
for (var fd in request.postData?.params ?? <hp.Param>[]) {
name = fd.name;
if (fd.contentType == "text/plain") {
formDataType = FormDataType.text;
val = fd.value;
} else {
formDataType = FormDataType.file;
val = fd.fileName;
}
formData.add(FormDataModel(
name: name,
value: val,
type: formDataType,
));
}
}

return HttpRequestModel(
method: method,
url: url,
headers: headers,
params: params,
isHeaderEnabledList: isHeaderEnabledList,
isParamEnabledList: isParamEnabledList,
body: body,
bodyContentType: bodyContentType,
formData: formData);
}

Map<String, String> parseFormData(String? data) {
// Return an empty map if the input is null or empty
if (data == null || data.isEmpty) {
return {};
}
// Split the input string into individual key-value pairs
var pairs = data.split('&');

// Create a Map to store key-value pairs
Map<String, String> result = {};

// Loop through the pairs and split them into keys and values
for (var pair in pairs) {
var keyValue = pair.split('=');

// Ensure the pair contains both key and value
if (keyValue.length == 2) {
var key = Uri.decodeComponent(keyValue[0]);
var value = Uri.decodeComponent(keyValue[1]);

result[key] = value;
}
}

return result;
}
}
1 change: 1 addition & 0 deletions packages/apidash_core/lib/import_export/import_export.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'curl_io.dart';
export 'postman_io.dart';
export 'insomnia_io.dart';
export 'har_io.dart';
2 changes: 2 additions & 0 deletions packages/apidash_core/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ dependencies:
path: ../insomnia_collection
postman:
path: ../postman
har_parser:
path: ../har_parser
seed: ^0.0.3
xml: ^6.3.0

Expand Down
3 changes: 3 additions & 0 deletions packages/apidash_core/pubspec_overrides.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# melos_managed_dependency_overrides: har_parser
# melos_managed_dependency_overrides: curl_parser,insomnia_collection,postman,seed
dependency_overrides:
curl_parser:
path: ../curl_parser
har_parser:
path: ..\\har_parser
insomnia_collection:
path: ../insomnia_collection
postman:
Expand Down
31 changes: 31 additions & 0 deletions packages/har_parser/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
build/
3 changes: 3 additions & 0 deletions packages/har_parser/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## 0.0.1

* TODO: Describe initial release.
Loading