Hay un error en la función View()
function View( cName, hParams )
local cData
local cViewPath := "c:\temp\views\" + cName + ".view"
Hay que corregir ese path
Hay un error en la función View()
function View( cName, hParams )
local cData
local cViewPath := "c:\temp\views\" + cName + ".view"
Hay que corregir ese path
Interesante !
Antonio Linares wrote:Hay un error en la función View()
function View( cName, hParams )
local cData
local cViewPath := "c:\temp\views\" + cName + ".view"Hay que corregir ese path
👍🏻
Lo he cambiado por:
local cViewPath := ".\views\" + cName + ".view"
y calculator.prg y chesss.prg ya se muestran en pantalla; pero modpro.prg no veo donde está el error y muestra "body not found!"
No sé si sería más conveniente cambiar:
cData = "<h2>" + cName + " not found!</h2>"
por:
cData = "<h2>" + cViewPath + " not found!</h2>"
o por:
cData = "<h2>" + cName + ".view" + " not found!</h2>"
Un Saludo
Carlos G.
FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home
Carlos,
Tienes body.view en views ?
Antonio Linares wrote:Carlos,
Tienes body.view en views ?
No estoy en mi ordenador, creo que no, pero no recuerdo haberlo visto en el mensaje de ejemplos.
Un Saludo
Carlos G.
FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home
body.view
<body>
<div id="main" class="container-fluid" style="padding:0px;overflow-x:hidden">
<div class="row">
<div class="col-md-12">
{{View("menu")}}
</div>
</div>
<div id="body">
{{View("code")}}
<div id="right">
<div id="splitter"></div>
<div id="output"></div>
</div>
<div id="chat-splitter"></div>
<div id="chat-panel-container">
{{View("chat")}}
</div>
</div>
</div>
<script>
var editor_width, right_margin_left, cResult;
editor_width = sessionStorage.getItem( 'editor-width' );
if( editor_width )
$( "#editor" ).css( "width", editor_width );
right_margin_left = sessionStorage.getItem( 'right-margin-left' );
if( right_margin_left )
$( "#right" ).css( "margin-left", right_margin_left );
cResult = sessionStorage.getItem( 'result' );
if( cResult )
$('#output').html( cResult );
$('#splitter').mousedown( function(e) {
e.preventDefault();
$(document).mousemove( function(e) {
var x = e.pageX;
e.preventDefault();
if( x > 300 && x < ( $(window).width() - 300 ) )
{
$( "#editor" ).css( "width", x );
$( "#right" ).css( "margin-left", x );
sessionStorage.setItem( 'modpro_code', editor.getValue() );
sessionStorage.setItem( 'editor-width', $( "#editor" ).css( "width" ) );
sessionStorage.setItem( 'right-margin-left', $( "#right" ).css( "margin-left" ) );
}
} ) } );
$(document).mouseup( function() {
$(document).unbind('mousemove'); } );
</script>
</body>
</html>chat.view
<div id="chat-panel" style="background-color: #f0f0f0; border-left: 1px solid #ccc; display: flex; flex-direction: column; overflow: hidden; height: 100%;">
<!-- Chat Header -->
<!-- Chat Header -->
<div style="background-color: #007bff; color: white; padding: 10px; font-weight: bold; display: flex; justify-content: space-between; align-items: center;">
<span>Gemini Assistant</span>
<button onclick="NewConversation()" style="background: none; border: none; color: white; cursor: pointer;" title="New Conversation">
<i class="fas fa-redo"></i>
</button>
</div>
<!-- Chat History -->
<div id="chat-history" style="flex: 1; padding: 10px; overflow-y: auto; display: flex; flex-direction: column; gap: 10px;">
<div class="chat-bubble bot">Hello! I'm Gemini. How can I help you improve your code today?</div>
</div>
<!-- Suggestions Chips -->
<div id="suggestion-area" style="padding: 5px 10px; background-color: #e9ecef; border-top: 1px solid #ddd; display: flex; gap: 5px; overflow-x: auto; white-space: nowrap;">
<button class="suggestion-chip" onclick="SendPrompt('Enhance Code', true)">Enhance</button>
<button class="suggestion-chip" onclick="SendPrompt('Explain this code', true)">Explain Code</button>
<button class="suggestion-chip" onclick="SendPrompt('Find bugs', true)">Find Bugs</button>
<button class="suggestion-chip" onclick="SendPrompt('Optimize', true)">Optimize</button>
</div>
<!-- Input Area -->
<div style="padding: 10px; background-color: white; border-top: 1px solid #ddd; display: flex; gap: 5px;">
<input type="text" id="chat-input" class="form-control" placeholder="Ask Gemini..." onkeypress="HandleEnter(event)">
<button class="btn btn-primary" onclick="SendMessage()"><i class="fas fa-paper-plane"></i></button>
</div>
</div>
<script>
function NewConversation() {
$('#chat-history').html('<div class="chat-bubble bot">Hello! I\'m Gemini. How can I help you improve your code today?</div>');
}
function SendPrompt( text, includeCode ) {
$('#chat-input').val( text );
SendMessage( includeCode );
}
function HandleEnter( e ) {
if( e.which == 13 ) SendMessage();
}
function SendMessage( includeCode ) {
var text = $('#chat-input').val();
if( !text.trim() ) return;
var codeContent = "";
if( includeCode === true && typeof editor !== 'undefined' ) {
codeContent = editor.getValue();
}
// User Message
$('#chat-history').append('<div class="chat-bubble user">' + text + '</div>');
$('#chat-input').val('');
ScrollToBottom();
// Show loading
var loadingId = "loading-" + Date.now();
$('#chat-history').append('<div id="' + loadingId + '" class="chat-bubble bot">Thinking...</div>');
ScrollToBottom();
// Backend Call
$.post( "gemini.prg", { prompt: text, code: codeContent } )
.done( function( data ) {
$('#' + loadingId).html( data );
ScrollToBottom();
})
.fail( function() {
$('#' + loadingId).html( "Error connecting to Gemini." );
});
}
function ScrollToBottom() {
var d = $('#chat-history');
d.scrollTop(d.prop("scrollHeight"));
}
</script>
<style>
.chat-bubble {
max-width: 80%;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
line-height: 1.4;
}
.chat-bubble.user {
align-self: flex-end;
background-color: #007bff;
color: white;
border-bottom-right-radius: 5px;
}
.chat-bubble.bot {
align-self: flex-start;
background-color: #e2e2e2;
color: black;
border-bottom-left-radius: 5px;
}
.suggestion-chip {
background-color: white;
border: 1px solid #007bff;
color: #007bff;
border-radius: 15px;
padding: 4px 10px;
font-size: 12px;
cursor: pointer;
transition: background-color 0.2s;
}
.suggestion-chip:hover {
background-color: #007bff;
color: white;
}
/* Scrollbar style for history */
#chat-history::-webkit-scrollbar { width: 5px; }
#chat-history::-webkit-scrollbar-thumb { background: #bbb; border-radius: 5px; }
/* Scrollbar style for suggestions */
#suggestion-area::-webkit-scrollbar { height: 3px; }
#suggestion-area::-webkit-scrollbar-thumb { background: #bbb; border-radius: 5px; }
</style>gemini.prg
function Main()
local hPost := UPost()
local cPrompt := ""
local cCode := ""
local cResponse := ""
UAddHeader( "Access-Control-Allow-Origin", "*" )
if hb_HHasKey( hPost, "prompt" )
cPrompt := hPost[ "prompt" ]
endif
if hb_HHasKey( hPost, "code" )
cCode := hPost[ "code" ]
endif
if Empty( cPrompt )
return "Error: No prompt provided."
endif
cResponse := ChatGemini( cPrompt, cCode )
return cResponse
function ChatGemini( cPrompt, cCode )
local cKey := "Tu clave Gemini"
local cUrl := "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent"
local oHttp
local hJson := {=>}
local hContent := {=>}
local hPart := {=>}
local cJson
local cText := ""
if Empty( cKey )
return "Error: GEMINI_API_KEY environment variable not set."
endif
try
oHttp := CreateObject( "MSXML2.ServerXMLHTTP.6.0" )
catch
try
oHttp := CreateObject( "MSXML2.ServerXMLHTTP" )
catch
return "Error: Could not create MSXML2.ServerXMLHTTP object."
end
end
hPart[ "text" ] := cPrompt + IF( !Empty( cCode ), " Code: " + cCode, "" )
hContent[ "parts" ] := { hPart }
hJson[ "contents" ] := { hContent }
cJson := hb_jsonEncode( hJson )
try
oHttp:Open( "POST", cUrl, .F. )
oHttp:SetRequestHeader( "Content-Type", "application/json" )
oHttp:SetRequestHeader( "X-goog-api-key", cKey )
oHttp:Send( cJson )
catch
return "Error: Could not connect to Gemini API (Timeout or Network Error)."
end
if oHttp:Status == 200
hJson := hb_jsonDecode( oHttp:ResponseText )
if hb_HHasKey( hJson, "candidates" ) .and. Len( hJson[ "candidates" ] ) > 0
cText := hJson[ "candidates" ][ 1 ][ "content" ][ "parts" ][ 1 ][ "text" ]
// Simple formatting for chat
cText := StrTran( cText, Chr( 10 ), "<br>" )
cText := StrTran( cText, "```", "<pre>" ) // Very basic code block handling
cText := StrTran( cText, "**", "<b>" )
cText := StrTran( cText, "**", "</b>" ) // basic bold attempt, not perfect regex
else
cText := "Error parsing Gemini response: " + oHttp:ResponseText
endif
else
cText := "API Error " + AllTrim( Str( oHttp:Status ) ) + ": " + oHttp:ResponseText
endif
return cTextVoy con ello!!!
Antonio, mejor aquí https://www.fivetechsupport.com/forums/viewtopic.php?t=46183 , no?
modpro.prg ya muestra pantalla.
gemini.prg da este mensaje:
Error COMPILER/(1001) 20
Description Incomplete statement or unbalanced delimiters
Operation Line: 40
Un Saludo
Carlos G.
FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home
Si, cierto, deberia haberlo publicado ahí
Aqui tienes gemini.prg mejorado:
function Main()
local hPost := UPost()
local cPrompt := ""
local cCode := ""
local cResponse := ""
UAddHeader( "Access-Control-Allow-Origin", "*" )
if hb_HHasKey( hPost, "prompt" )
cPrompt := hPost[ "prompt" ]
endif
if hb_HHasKey( hPost, "code" )
cCode := hPost[ "code" ]
endif
if Empty( cPrompt )
return "Error: No prompt provided."
endif
cResponse := ChatGemini( cPrompt, cCode )
return cResponse
function ChatGemini( cPrompt, cCode )
local cKey := "tu clave"
local cUrl := "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent"
local oHttp
local hJson := {=>}
local hContent := {=>}
local hPart := {=>}
local cJson
local cText := ""
local bOldError
local oErr
if Empty( cKey )
return "Error: GEMINI_API_KEY environment variable not set."
endif
// Trap errors
bOldError := ErrorBlock( {|e| Break(e) } )
BEGIN SEQUENCE
oHttp := CreateObject( "MSXML2.ServerXMLHTTP.6.0" )
RECOVER
BEGIN SEQUENCE
oHttp := CreateObject( "MSXML2.ServerXMLHTTP" )
RECOVER
ErrorBlock( bOldError )
return "Error: Could not create MSXML2.ServerXMLHTTP object."
END
END
if Empty( oHttp )
ErrorBlock( bOldError )
return "Error: Could not create MSXML2.ServerXMLHTTP object (NIL)."
endif
hPart[ "text" ] := cPrompt + IIF( !Empty( cCode ), " Code: " + cCode, "" )
hContent[ "parts" ] := { hPart }
hJson[ "contents" ] := { hContent }
cJson := hb_jsonEncode( hJson )
BEGIN SEQUENCE
oHttp:Open( "POST", cUrl, .F. )
oHttp:SetRequestHeader( "Content-Type", "application/json" )
oHttp:SetRequestHeader( "X-goog-api-key", cKey )
oHttp:Send( cJson )
RECOVER USING oErr
ErrorBlock( bOldError )
return "Error: " + oErr:Description + " (Timeout/Network)"
END
ErrorBlock( bOldError ) // Restore standard error handler
if oHttp:Status == 200
hJson := hb_jsonDecode( oHttp:ResponseText )
if hb_HHasKey( hJson, "candidates" ) .and. Len( hJson[ "candidates" ] ) > 0
cText := hJson[ "candidates" ][ 1 ][ "content" ][ "parts" ][ 1 ][ "text" ]
// Simple formatting for chat
cText := StrTran( cText, Chr( 10 ), "<br>" )
cText := StrTran( cText, "```", "<pre>" )
cText := StrTran( cText, "**", "<b>" )
cText := StrTran( cText, "**", "</b>" )
else
cText := "Error parsing Gemini response: " + oHttp:ResponseText
endif
else
cText := "API Error " + AllTrim( Str( oHttp:Status ) ) + ": " + oHttp:ResponseText
endif
return cTextAntonio Linares wrote:Si, cierto, deberia haberlo publicado ahí
👍🏻 Aqui tienes gemini.prg mejorado:
function Main() local hPost := UPost() local cPrompt := "" local cCode := "" local cResponse := "" UAddHeader( "Access-Control-Allow-Origin", "*" ) if hb_HHasKey( hPost, "prompt" ) cPrompt := hPost[ "prompt" ] endif if hb_HHasKey( hPost, "code" ) cCode := hPost[ "code" ] endif if Empty( cPrompt ) return "Error: No prompt provided." endif cResponse := ChatGemini( cPrompt, cCode ) return cResponse function ChatGemini( cPrompt, cCode ) local cKey := "tu clave" local cUrl := "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent" local oHttp local hJson := {=>} local hContent := {=>} local hPart := {=>} local cJson local cText := "" local bOldError local oErr if Empty( cKey ) return "Error: GEMINI_API_KEY environment variable not set." endif // Trap errors bOldError := ErrorBlock( {|e| Break(e) } ) BEGIN SEQUENCE oHttp := CreateObject( "MSXML2.ServerXMLHTTP.6.0" ) RECOVER BEGIN SEQUENCE oHttp := CreateObject( "MSXML2.ServerXMLHTTP" ) RECOVER ErrorBlock( bOldError ) return "Error: Could not create MSXML2.ServerXMLHTTP object." END END if Empty( oHttp ) ErrorBlock( bOldError ) return "Error: Could not create MSXML2.ServerXMLHTTP object (NIL)." endif hPart[ "text" ] := cPrompt + IIF( !Empty( cCode ), " Code: " + cCode, "" ) hContent[ "parts" ] := { hPart } hJson[ "contents" ] := { hContent } cJson := hb_jsonEncode( hJson ) BEGIN SEQUENCE oHttp:Open( "POST", cUrl, .F. ) oHttp:SetRequestHeader( "Content-Type", "application/json" ) oHttp:SetRequestHeader( "X-goog-api-key", cKey ) oHttp:Send( cJson ) RECOVER USING oErr ErrorBlock( bOldError ) return "Error: " + oErr:Description + " (Timeout/Network)" END ErrorBlock( bOldError ) // Restore standard error handler if oHttp:Status == 200 hJson := hb_jsonDecode( oHttp:ResponseText ) if hb_HHasKey( hJson, "candidates" ) .and. Len( hJson[ "candidates" ] ) > 0 cText := hJson[ "candidates" ][ 1 ][ "content" ][ "parts" ][ 1 ][ "text" ] // Simple formatting for chat cText := StrTran( cText, Chr( 10 ), "<br>" ) cText := StrTran( cText, "```", "<pre>" ) cText := StrTran( cText, "**", "<b>" ) cText := StrTran( cText, "**", "</b>" ) else cText := "Error parsing Gemini response: " + oHttp:ResponseText endif else cText := "API Error " + AllTrim( Str( oHttp:Status ) ) + ": " + oHttp:ResponseText endif return cText
Ahora obtengo esto:
Error: No prompt provided.
Lo estoy llamabndo así:
localhost/gemini.prg
En el Main le he puesto Main( "Como se fríen los huevos fritos" )
Y obtengo:
Error COMPILER/(1001) 30
Description Syntax error "syntax error at 'Como se frÃen los huevos fruitos'"
Operation Line: 0
Después continuo....
Me debe faltar mi clave de gemini,
Después continuo....
Un Saludo
Carlos G.
FiveWin 25.12 + Harbour 3.2.0dev (r2502110321), BCC 7.7 Windows 11 Home
Tienes que ponerle tu clave de Gemini y además gemini.prg se usa desde modpro.prg
Habria que pedirle a AntiGravity que lo modifique para usarlo de forma independiente :wink: