Skip to content

Commit 418c9dd

Browse files
authored
Merge pull request #14 from VectorCamp/patch/1.0.9
Patch/1.0.9
2 parents 2919989 + 9d7fb5b commit 418c9dd

12 files changed

Lines changed: 411 additions & 84 deletions

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ We are actively working to address these issues in an upcoming release.
115115

116116
## 1.0.8
117117
- Add intrinsics autocomplete on typing!
118+
119+
## 1.0.9
120+
- Datatype highlighting
121+
- Refactoring backend api
122+
- Select highlight style
123+
- Fix bug on first session
124+
118125
---
119126

120127

media/chat.html

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -616,9 +616,15 @@
616616
const sessionTabsContainer = document.getElementById('sessionTabs');
617617
sessionTabsContainer.innerHTML = '';
618618

619-
message.sessions.forEach(sessionId => {
620-
const tab = createSessionTab(sessionId, sessionId === message.currentSession);
621-
});
619+
if (message.sessions && message.sessions.length > 0) {
620+
message.sessions.forEach(sessionId => {
621+
createSessionTab(sessionId, sessionId === message.currentSession);
622+
});
623+
} else {
624+
// If extension returned no sessions, auto-create Chat 1
625+
createDefaultTabIfMissing();
626+
vscode.postMessage({ type: 'switchSession', sessionId: 'Chat 1' });
627+
}
622628
} else if (message.type === 'error') {
623629
removeSpinner(message.sessionId);
624630
showError(`⚠️ ${message.error}`, message.sessionId);
@@ -678,7 +684,7 @@
678684
} else {
679685
createDefaultTabIfMissing();
680686
vscode.postMessage({ type: 'switchSession', sessionId: 'Chat 1' });
681-
vscode.postMessage({ type: 'requestHistory', sessionId: 'Chat 1' });
687+
// vscode.postMessage({ type: 'requestHistory', sessionId: 'Chat 1' });
682688
}
683689
};
684690

@@ -785,6 +791,7 @@
785791
const createSessionBtn = document.getElementById('createSessionBtn');
786792
const lastSessionId = localStorage.getItem('lastActiveSession') || defaultSessionId;
787793

794+
788795
sessionNameInput.addEventListener('keydown', (e) => {
789796
if (e.key === 'Enter') {
790797
e.preventDefault();

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "code-simd-ai",
33
"displayName": "code.simd.ai",
44
"description": "VScode plugin for porting of code between different cpu architectures",
5-
"version": "1.0.8",
5+
"version": "1.0.9",
66
"publisher": "VectorCamp",
77
"engines": {
88
"vscode": "^1.100.0"
@@ -117,6 +117,10 @@
117117
{
118118
"command": "code.simd.ai.editSIMD",
119119
"title": "Edit SIMD"
120+
},
121+
{
122+
"command": "code.simd.ai.cycleHighlightMode",
123+
"title": "Cycle SIMD Syntax Highlighting Mode"
120124
}
121125
],
122126
"submenus": [

src/api/datatypeFetcher.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) 2025, VectorCamp PC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import fetch from 'node-fetch';
18+
19+
/**
20+
* Fetch datatypes grouped by architecture.
21+
*
22+
* Example response:
23+
* {
24+
* "NEON": ["uint16x8_t", "float32x8_t"],
25+
* "INTEL": ["__m128h", "__m256h"],
26+
* "POWER": ["vector signed char", "vector bool char"]
27+
* }
28+
*/
29+
30+
import { API_BASE, getApiToken } from '../config';
31+
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
32+
33+
34+
export async function fetchDatatypesByArch(): Promise<Record<string, string[]>> {
35+
const apiKey = getApiToken();
36+
if (!apiKey) {
37+
console.warn('⚠️ API key missing');
38+
return {};
39+
}
40+
41+
const endpoint = `${API_BASE}/v1/plugin-datatypes/get-datatypes-list`;
42+
43+
try {
44+
const res = await fetch(endpoint, {
45+
method: 'POST',
46+
headers: {
47+
'Content-Type': 'application/json',
48+
'Accept': 'application/json'
49+
},
50+
body: JSON.stringify({ api_key: apiKey })
51+
});
52+
53+
if (!res.ok) {
54+
throw new Error(`HTTP ${res.status} ${res.statusText}`);
55+
}
56+
57+
const data = await res.json();
58+
if (!data || typeof data !== 'object' || !data.datatypes_list) {
59+
throw new Error('Invalid JSON structure');
60+
}
61+
62+
// console.log('✅ Datatypes fetched successfully');
63+
return data.datatypes_list as Record<string, string[]>;
64+
65+
} catch (err) {
66+
console.error('❌ Failed to fetch datatypes:', err);
67+
return {};
68+
}
69+
}

src/api/simdAi.ts

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,21 @@
1616

1717
import { get } from 'http';
1818
import { getApiToken } from '../config';
19-
import { PLUGIN_DEFAULT_TOKEN } from '../config';
20-
19+
import { API_BASE, MODEL_NAME , PLUGIN_DEFAULT_TOKEN } from '../config';
2120

2221
export async function callSimdAiWithHistory(messages: { role: string; content: string }[]): Promise<string> {
2322
const apiToken = getApiToken();
2423
if (!apiToken) {return '⚠️ API token missing';}
2524

2625
try {
27-
const res = await fetch('https://simd.ai/api/chat/completions', {
26+
const res = await fetch(`${API_BASE}/chat/completions`, {
2827
method: 'POST',
2928
headers: {
3029
'Content-Type': 'application/json',
3130
'Authorization': `Bearer ${apiToken}`
3231
},
3332
body: JSON.stringify({
34-
model: 'SIMD-ai-2506.1.ai:24b',
33+
model: MODEL_NAME,
3534
messages
3635
})
3736
});
@@ -56,7 +55,7 @@ let cachedIntrinsics: string[] | null = null;
5655
export async function fetchIntrinsicNames(): Promise<string[]> {
5756
let apiToken = getApiToken();
5857

59-
// if user has not specified api token, use predifined to only see Intel intrinsics
58+
// if user has not specified api token, use predifined to only see Intel intrinsics and some Preview
6059
if (!apiToken) {
6160
apiToken = PLUGIN_DEFAULT_TOKEN;
6261
}
@@ -66,7 +65,7 @@ export async function fetchIntrinsicNames(): Promise<string[]> {
6665
}
6766

6867
try {
69-
const response = await fetch('https://simd.ai/api/v1/plugin-intrinsics-list/get-intrinsics-list', {
68+
const response = await fetch(`${API_BASE}/v1/plugin-intrinsics-list/get-intrinsics-list`, {
7069
method: 'POST',
7170
headers: {
7271
'Content-Type': 'application/json'
@@ -111,6 +110,32 @@ export async function fetchIntrinsicNames(): Promise<string[]> {
111110
}
112111
}
113112

113+
export async function sendToSimdAI(userPrompt: string) {
114+
const apiToken = getApiToken();
115+
if (!apiToken) {throw new Error('API token missing');}
116+
117+
const endpoint = `${API_BASE}/chat/completions`;
118+
119+
const response = await fetch(endpoint, {
120+
method: 'POST',
121+
headers: {
122+
'Content-Type': 'application/json',
123+
'Authorization': `Bearer ${apiToken}`
124+
},
125+
body: JSON.stringify({
126+
model: MODEL_NAME,
127+
messages: [{ role: 'user', content: userPrompt }]
128+
})
129+
});
130+
131+
if (!response.ok) {
132+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
133+
}
134+
135+
const data = await response.json();
136+
return data;
137+
}
138+
114139
interface Prototype {
115140
key: string;
116141
output?: string;
@@ -149,7 +174,7 @@ export async function fetchIntrinsicInfo(word: string): Promise<TooltipData | nu
149174
}
150175

151176
try {
152-
const response = await fetch(`https://simd.ai/api/v1/plugin-intrinsic-info/get-intrinsics-info`, {
177+
const response = await fetch(`${API_BASE}/v1/plugin-intrinsic-info/get-intrinsics-info`, {
153178
method: 'POST',
154179
headers: {
155180
'Content-Type': 'application/json'

src/api/tooltipFetcher.ts

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,10 @@ import fetch from 'node-fetch';
1919

2020
import * as vscode from 'vscode';
2121
import { fetchIntrinsicInfo } from './simdAi';
22-
23-
24-
2522
// process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // Dev only — allow self-signed certs
2623

2724
const tooltipCache: Record<string, string> = {};
2825

29-
30-
3126
export async function fetchTooltip(word: string): Promise<string> {
3227
if (tooltipCache[word]) {return tooltipCache[word];}
3328

@@ -102,3 +97,46 @@ export async function fetchTooltip(word: string): Promise<string> {
10297
return '';
10398
}
10499
}
100+
101+
102+
import { fetchDatatypesByArch } from './datatypeFetcher';
103+
104+
const datatypeTooltipCache: Record<string, string> = {};
105+
106+
export async function fetchDatatypeTooltip(name: string): Promise<string> {
107+
return ''; // Coming soon datatype tooltips
108+
if (datatypeTooltipCache[name]) {return datatypeTooltipCache[name];}
109+
110+
try {
111+
const datatypesByArch = await fetchDatatypesByArch();
112+
if (!datatypesByArch || !Object.keys(datatypesByArch).length) {
113+
console.warn('No datatypes available');
114+
return '';
115+
}
116+
117+
const md = new vscode.MarkdownString();
118+
md.isTrusted = true;
119+
md.supportHtml = true;
120+
121+
let found = false;
122+
for (const [arch, names] of Object.entries(datatypesByArch)) {
123+
if (names.includes(name)) {
124+
found = true;
125+
const link = `https://simd.info/datatype/${encodeURIComponent(name)}`;
126+
md.appendMarkdown(`### [${name}](${link}) (${arch})\n`);
127+
md.appendMarkdown(`Description for ${name} on ${arch}.\n`);
128+
}
129+
}
130+
131+
if (!found) {
132+
md.appendMarkdown(`No datatype info found for **${name}**`);
133+
}
134+
135+
const markdown = md.value;
136+
datatypeTooltipCache[name] = markdown;
137+
return markdown;
138+
} catch (error) {
139+
console.error('Failed to fetch datatype tooltip for', name, error);
140+
return '';
141+
}
142+
}

src/config.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ export function getApiToken(): string | undefined {
2424
return token;
2525
}
2626

27-
import * as dotenv from 'dotenv';
28-
import path from 'path';
27+
// import * as dotenv from 'dotenv';
28+
// import path from 'path';
2929

30-
dotenv.config({ path: path.resolve(__dirname, '../.env') });
30+
// dotenv.config({ path: path.resolve(__dirname, '../.env') });
3131

32-
export const PLUGIN_DEFAULT_TOKEN = "sk-b5204816b07e49ec8096c9e8b34f28bb";
32+
export const PLUGIN_DEFAULT_TOKEN = "sk-b5204816b07e49ec8096c9e8b34f28bb";
33+
export const API_BASE = 'https://simd.ai/api';
34+
export const MODEL_NAME = 'SIMD-ai-2506.1.ai:24b';

src/extension.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import { translationState, clearState } from './translation/state';
2323
import { registerTranslateCommand } from './translation/translator';
2424
import { registerAcceptRejectCommands, registerEditSIMDCommand } from './translation/commands';
2525
import { TranslationCodeLensProvider } from './translation/codelens';
26-
import { highlightIntrinsics, initIntrinsicHighlighting, deactivateHighlighting } from './syntaxHighlighting';
27-
import { activate as activateCompletion } from './completionProvider'; // Update to correct filename
26+
import { highlightIntrinsicsAndDatatypes, initIntrinsicHighlighting, deactivateHighlighting, cycleHighlightMode } from './syntaxHighlighting';
27+
import { activate as activateCompletion } from './completionProvider';
2828

2929
export function activate(context: vscode.ExtensionContext) {
3030

@@ -47,10 +47,14 @@ export function activate(context: vscode.ExtensionContext) {
4747
context.subscriptions.push(
4848
vscode.languages.registerCodeLensProvider({ scheme: 'file', language: '*' }, new TranslationCodeLensProvider())
4949
);
50-
50+
context.subscriptions.push(
51+
vscode.commands.registerCommand('code.simd.ai.cycleHighlightMode', () => {
52+
cycleHighlightMode(context);
53+
})
54+
);
5155
initIntrinsicHighlighting(context);
5256
vscode.window.visibleTextEditors.forEach(editor => {
53-
highlightIntrinsics(editor);
57+
highlightIntrinsicsAndDatatypes(editor);
5458
});
5559

5660
activateCompletion(context);

src/highlightConfig.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2025, VectorCamp PC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
export const HighlightConfig: Record<
18+
string,
19+
{ gradient: string; flat: string }
20+
> = {
21+
NEON: {
22+
gradient: 'linear-gradient(90deg, #00FF7F, #32CD32, #228B22)',
23+
flat: '#32CD32',
24+
},
25+
INTEL: {
26+
gradient: 'linear-gradient(90deg, #00BFFF, #1E90FF, #4169E1)',
27+
flat: '#1E90FF',
28+
},
29+
POWER: {
30+
gradient: 'linear-gradient(90deg, #7B68EE, #6A5ACD, #483D8B)',
31+
flat: '#6A5ACD',
32+
},
33+
DEFAULT: {
34+
gradient: 'linear-gradient(90deg, #ADFF2F, #7FFF00, #32CD32)',
35+
flat: '#7FFF00',
36+
},
37+
};

0 commit comments

Comments
 (0)