{"model":"gpt-oss:20b","messages":[{"role":"system","content":"# Reglas flat para IR semántico\n\nInterpreta INSTRUCCION_USUARIO sobre el estado literal recibido. Devuelve únicamente operaciones soportadas, conserva lo no solicitado y no inventes tipos, propiedades, IDs, campos, fórmulas, relaciones u operaciones.\n\n## Entidades\n\nCada bloque bajo # Objetos visuales es un objeto independiente. Un objeto raíz y uno con Ubicación: tabla/... se modifican igual cuando la propiedad pertenece al objeto. La ubicación solo limita el ámbito.\n\nTTable es una entidad estructural. Sus líneas se identifican por tableId + section + line; sus celdas por tableId + section + line + cell. Los objetos de celda ya aparecen como objetos visuales independientes.\n\n## Contrato de modificación\n\n`changes` solo admite `{\"targetId\":\"id_real\",\"path\":\"/propiedad\",\"value\":valor}` y se usa para un cambio escalar cuando el ID real ya es conocido inequívocamente. Nunca contiene `target`, `type`, `location`, `where`, `set` ni `transform`.\n\n`intents` expresa una operación declarativa cuando PHP debe resolver el objetivo o calcularla. Usa `target` y la operación soportada; sus propiedades no llevan `/`.\n\nRegla: ID conocido → `changes`; ID o conjunto por resolver → `intents`. La decisión no depende de singular o plural.\n\nEjemplos: `{\"changes\":[{\"targetId\":\"id_123\",\"path\":\"/lFontBold\",\"value\":true}],\"intents\":[]}` · `{\"changes\":[],\"intents\":[{\"intent\":\"change\",\"target\":{\"type\":\"TText\"},\"where\":{\"property\":\"cTextColor\",\"equals\":\"#rrggbb\"},\"set\":{\"property\":\"cTextColor\",\"value\":\"#rrggbb\"}}]}`.\n\n## Target de intents CORE\n\nPara cálculos sobre objetos seleccionados usa `target.ids`. Para resolver un conjunto sencillo usa `target.type`, `target.location` y, si hay filtro literal, `where`. No construyas consultas complejas.\n\n## Selección\n\n- El ámbito indicado limita los objetos participantes.\n- Comprueba tipo, ubicación, propiedad y valor literal actual.\n- En peticiones plurales modifica todos los compatibles.\n- Un filtro por valor exige coincidencia literal y excluye el resto.\n- Una petición singular ambigua no produce operaciones.\n- No uses defaults o apariencia para sustituir un valor ausente.\n- Copia IDs y nombres de propiedades exactamente como aparecen.\n\n## Propietario y operación\n\n- Un intent puede usar set como lista para varias propiedades del mismo conjunto; where es opcional cuando no hay filtro por valor.\n- Una transformación relativa usa `transform:[{property,op,value}]` sobre propiedades numéricas; `op` admite `multiply`, `add` y `subtract`. `target.ids` limita explícitamente el conjunto a esos IDs reales seleccionados; no se buscan otros.\n- `set` y `transform` pueden coexistir solo si afectan a propiedades distintas. Una misma propiedad en ambos, una transformación duplicada o un ID inexistente hace que la intención sea inválida.\n- Propiedad escalar de TTable: changes.\n- Propiedad de línea: structure con setTableLine.\n- Propiedad de sección, grupo, columna o línea estructural: operación declarada.\n- No conviertas una propiedad de un nivel en otra de nivel distinto.\n\n## Creación y eliminación\n\ncreate requiere tipo real, parentId (null para raíz o ID de tabla para celda), propiedades requeridas y ubicación exacta cuando sea anidado. En una celda usa cTableSectionKey, nTableLineIndex y nTableCellIndex en properties según el contrato. No crea implícitamente líneas o celdas. delete usa el cId real, único y no bloqueado.\n\n## Seguridad\n\nNo cambies cId, cType ni referencias protegidas. No reemplaces arrays, objetos o relaciones mediante changes. Conserva tipos JSON, dominios, fórmulas y propiedades no solicitadas. Si la capacidad, campo, propiedad o path no existe, devuelve las cuatro listas vacías.\n\n## Respuesta\n\nDevuelve solo JSON válido con exactamente:\n\n{\"create\":[],\"changes\":[],\"delete\":[{\"targetId\":\"id_real\"}],\"structure\":[],\"intents\":[]}\n\n# Operaciones estructurales reales\n\nCuando existe OBJETOS_SELECCIONADOS y no se pide explicitamente todo el documento, limita la operación a esos IDs: cambios absolutos escalares usan `changes`; cálculos declarativos usan `target.ids`. No busques objetos adicionales.\n\nCada entrada de structure usa exactamente las claves declaradas. No inventes operaciones.\n\n`\"structure\":[{\"op\":\"setTableLine\",\"tableId\":\"id_tabla\",\"section\":\"header\",\"lineIndex\":0,\"path\":\"/hBackground/cColor\",\"value\":\"#rrggbb\"}]`\n\n`\"structure\":[{\"op\":\"moveTableColumn\",\"tableId\":\"id_tabla\",\"fromIndex\":2,\"toIndex\":0}]`\n\nLas intenciones pueden expresar transformaciones deterministas antes de generar `changes`: `{\"intent\":\"change\",\"target\":{\"ids\":[\"id_real\"]},\"transform\":[{\"property\":\"nFontSize\",\"op\":\"multiply\",\"value\":2}]}`. Solo se admiten propiedades numéricas y las operaciones `multiply`, `add` y `subtract`; PHP calcula el valor absoluto.\n\n| op | claves | uso |\n|---|---|---|\n| setDocument | op,path,value | propiedades reales del documento |\n| setLabelLayout | op,path,value | propiedades reales de layout de etiqueta |\n| setTableSection | op,tableId,section,path,value | lConcatNextDataLine, lAlsoOnEmptyGroup |\n| setTableGroup | op,tableId,path,value | cBreakExpression, aBreakExpressions, lSkipEmptyValues |\n| clearTableGroup | op,tableId | limpia grupo y líneas de grupo |\n| addTableColumn | op,tableId,index,width | añade celda vacía; width>0 |\n| deleteTableColumn | op,tableId,index | no elimina la única columna |\n| duplicateTableColumn | op,tableId,index,toIndex | clona columna |\n| insertTableLine | op,tableId,section,index,height,columnWidths | altura y anchos positivos |\n| deleteTableLine | op,tableId,section,index | línea existente |\n| moveTableLine | op,tableId,section,fromIndex,toIndex | mueve dentro de sección |\n| upsertAccumulator | op,name,definition | definición con tipo y formula |\n| deleteAccumulator | op,name | elimina acumulador existente |\n\nSecciones válidas: header, groupHeader, detail, groupFooter, footer. setTableLine admite los paths reales de línea: cName, nHeight, cConditionFormula, hBackground/*, hBorder/*, hZebraPattern/*, flags y paths declarados por el contrato PHP. Las columnas se identifican por contenido y posición lógica.\n\n# Propiedades comunes reales\n\nTodos los objetos visuales usan unidades milimétricas y comparten estas propiedades cuando aparecen:\n\n## Interpretación visual\n\n| Orden visual | Propiedad real | Valor o efecto |\n|---|---|---|\n| alineación horizontal del texto | cTextAlign | left, center, right o justify; no mueve nLeft |\n| alineación vertical del texto | cTextVerticalAlign | top, middle o bottom; no mueve nTop |\n| redondeo | nRounded | porcentaje numérico literal solicitado |\n| relleno degradado | cFillStyle | gradient |\n| tamaño relativo de un objeto | nWidth y nHeight | a la mitad divide ambas; al doble multiplica ambas; no cambia nLeft ni nTop |\n\n## Colores canónicos\n\nCuando el usuario use uno de estos nombres de color, usa su HEX canónico: `rojo:#ff0000` · `verde:#008000` · `verde oscuro:#006400` · `azul:#0000ff` · `azul oscuro:#00008b` · `amarillo:#ffff00` · `gris claro:#d3d3d3`.\n\n| Propiedad | Tipo | Restricción |\n|---|---|---|\n| cId | S | identidad literal; protegida |\n| cType | S | tipo literal; protegido |\n| cName | S | nombre descriptivo |\n| nLeft, nTop | N | posición no negativa |\n| nWidth, nHeight | N | tamaño positivo |\n| lVisible, lLocked | B | visibilidad y bloqueo |\n| nLayerId, nZIndex | N | capa y orden |\n| nRotation, nOpacity | N | rotación; opacidad 0..1 |\n| cCondition | S | fórmula de aparición, no evaluada |\n| cBorderColor, cBorderColorFormula | S | borde fijo y fórmula |\n| nBorderWidth | N | grosor no negativo |\n| lBorderTop, lBorderRight, lBorderBottom, lBorderLeft | B | lados del borde |\n| cBackgroundColor, cBackgroundColorFormula | S | fondo propio y fórmula |\n| cFillStyle, cFillColor2, cFillColor3 | S | relleno |\n| nFillOpacity, nRounded, nShadowSize, nShadowTransparency | N | valores visuales |\n| cShadowColor, cShadowColorFormula | S | sombra fija y fórmula |\n| nPaddingTop, nPaddingRight, nPaddingBottom, nPaddingLeft | N | padding propio no negativo |\n\nAl crear son obligatorias nLeft, nTop, nWidth, nHeight y las propiedades requeridas por el tipo. cId, cType y referencias de tabla no se crean ni se cambian mediante changes. Las fórmulas permanecen literales.\n\nDefaults comunes relevantes: lVisible=true, lLocked=false, nLayerId=0, nZIndex=1, nRotation=0, nOpacity=1, nBorderWidth=0.1, nPaddingTop/Right/Bottom/Left=0. El tipo puede sustituir estos defaults.\n\n# TBarcode\n\nObjeto visual de código, raíz o contenido de celda. Propiedades: cContent, cBarcodeType, lShowText, lTrimSpaces, cColor, cColorFormula, fuente y estilos del texto legible. Crear requiere cContent y geometría. Cambios usan paths reales con changes.\n\nDefaults de creación: cName=Código de barras, cBarcodeType=EAN13, lShowText=true, lTrimSpaces=false, cColor=#000000, cFontFamily=Arial, nFontSize=12.\n\n# TChart\n\nObjeto visual de gráfico raíz. Propiedades propias: cChartKind y hChartSpec; usa COMMON para geometría y apariencia. Crear requiere geometría y especificación compatible.\n\n# TDocument\n\nDocumento raíz. Propiedades reales: cType, cFormatVersion, cTemplateId, cTemplateName, cDocumentKind, cPaperFormat, cPaperOrientation, nPaperWidth, nPaperHeight, nDesignHeight, cPaperHeightMode y nContinuousBottomMargin. Los cambios documentales usan setDocument; el layout de etiqueta usa setLabelLayout.\n\n# TEllipse\n\nForma elíptica raíz. Usa COMMON y nRounded cuando aparezca. No contiene objetos ni adquiere relaciones por solapamiento. Crear usa parentId:null.\n\n# TFormattedText\n\nObjeto visual con aRichTextRuns. Puede ser raíz o contenido de celda. Crear requiere aRichTextRuns y geometría. Sus propiedades escalares se modifican con changes.\n\n# TImage\n\nObjeto visual de imagen, raíz o contenido de celda. Propiedades: cSource, cSourceType, lKeepRatio y cFit. cSource y geometría son obligatorios al crear. El origen y sus fórmulas se conservan literalmente. Cambios escalares usan changes; eliminación usa delete.\n\nDefaults de creación: cName=Imagen, cSourceType=auto, lKeepRatio=true, cFit=contain.\n\n# TLine\n\nLínea gráfica raíz, distinta de una línea estructural de TTable. Propiedades propias: cOrientation y cLineStyle. Nunca usa setTableLine.\n\n# TRectangle\n\nForma rectangular raíz. No contiene objetos. Usa COMMON para geometría, fondo, relleno, borde, redondeo, sombra y opacidad. Crear usa parentId:null.\n\n# TTable\n\nEntidad estructural raíz. Propiedades propias: cName, geometría, cBackgroundColor, cPageBreakCondition, lFixedSeparators, lFooterOnBottom, cHeightMode y hGroup cuando aparezcan.\n\nDefaults relevantes: cName=Tabla, cPageBreakCondition=\"\", lFixedSeparators=false, lFooterOnBottom=true, cHeightMode=fixed.\n\nLíneas se identifican por tableId + section + line; sus propiedades reales se modifican con setTableLine. Celdas se identifican por tableId + section + line + cell, tienen nWidth y objectId o están vacías. Los objetos contenidos ya aparecen una sola vez en Objetos visuales con ubicación directa y se modifican como cualquier objeto visual.\n\nOperaciones estructurales disponibles: líneas, secciones, grupo, columnas y acumuladores según OPERATIONS. No es necesario conocer la representación interna de almacenamiento.\n\n# TText\n\n`nLeft` y `nTop` son obligatorios al crear; si el usuario no indica posicion, usa los defaults reales `nLeft: 0` y `nTop: 0`, sin omitirlos.\n\nAl crear, cada elemento de `create` solo tiene `type`, `parentId` y `properties`; `properties` debe contener siempre `cText`, `nLeft`, `nTop`, `nWidth` y `nHeight`, además de las propiedades solicitadas. Para un objeto raiz se usa `parentId: null`.\n\nRegla de `cText`: es una expresión; en JSON un texto fijo se envía como `{\"cText\":\"\\\"HOLA\\\"\"}` para que el valor real conserve las comillas. Las referencias y fórmulas van sin comillas artificiales, y las expresiones mixtas se conservan completas.\n\nObjeto visual de texto. Puede estar en documento o en una celda; Ubicación expresa el ámbito y no cambia sus paths.\n\nPropiedades propias: cText, cTextColor, cTextColorFormula, nTextOpacity, cTextAlign, cTextVerticalAlign, cFontFamily, nFontSize, lFontBold, lFontItalic, lFontUnderline, lFontStrikeout, lTextWrap, lAllowPageBreak, nLineSpacing, nParagraphSpacing, lKeepEmptyParagraphs, lTextAdjusted, lTrimSpaces, cTextFlowGroup, nTextFlowOrder, nTextFlowLineHeight, nTextDecimalPosition y fórmulas de estilo.\n\ncText y fórmulas se conservan literalmente. Crear requiere cText y geometría. Cambiar usa changes; eliminar usa delete.\n\nDefaults de creación relevantes: cName=Texto, cText=\"\", cFontFamily=Arial, nFontSize=12, lTextWrap=true, lKeepEmptyParagraphs=true, cTextColor=#000000, nTextOpacity=1, cTextAlign=left, cTextVerticalAlign=top.\n\n# richText\n\nObjeto de contenido HTML enriquecido, raíz o contenido de celda. Propiedades: cContent, cVerticalAlign y cOverflow. Crear requiere cContent y geometría. Conservar HTML y fórmulas; cambios escalares usan changes.\n\nDefaults de creación: cName=Texto enriquecido, cVerticalAlign=top, cOverflow=hidden.\n\n# Contrato experimental de intención\n\nUna intención expresa una modificación declarativa sin enumerar IDs:\n\n```json\n{\"intent\":\"change\",\"target\":{\"type\":\"TText\",\"location\":{\"kind\":\"table\",\"tableId\":\"id_tabla\",\"sections\":[\"header\",\"footer\"]}},\"where\":{\"property\":\"cBackgroundColor\",\"equals\":\"#rrggbb\"},\"set\":{\"property\":\"cBackgroundColor\",\"value\":\"#rrggbb\"}}\n```\n\n- `target` limita tipo, ID o ubicación plana (`kind`, `tableId`, `sections`, `lines`, `cells`).\n- `where` es opcional; si existe, contiene condiciones literales `equals` o `notEquals` que deben cumplirse.\n- Las claves opcionales no utilizadas se omiten; nunca se envían como `null`.\n- `set` usa una propiedad o una lista de propiedades reales con valores absolutos sobre el mismo conjunto.\n- La propiedad es semántica y no usa JSON Pointer; PHP genera el path técnico con `/`.\n- El resolver devuelve el contrato actual `{create,changes,delete,structure}` y no interpreta lenguaje natural.\n"},{"role":"user","content":"CAMPOS_Y_VARIABLES_MARKDOWN\n# Campos, variables y acumuladores disponibles\n\nTipos: `C`=texto, `N`=número, `D`=fecha, `I`=imagen, `M`=memo, `L`=booleano.\n\n## UserVar — Variables de usuario\n\n| Nombre | Referencia exacta | Tipo | Definición actual |\n|---|---|---|---|\n| — | — | — | Sin definiciones disponibles |\n\n## AcumVar — Acumuladores\n\n| Nombre | Referencia exacta | Tipo | Definición actual |\n|---|---|---|---|\n| — | — | — | Sin definiciones disponibles |\nFIN_CAMPOS_Y_VARIABLES_MARKDOWN\n\nDOCUMENTO_IR_V5\n# Documento\n\ncType: TDocument\n\n# Tablas\n\n# Objetos visuales\n\nFIN_DOCUMENTO_IR_V5\n\nINSTRUCCION_USUARIO\náéíóú ÁÉÍÓÚ ñÑ º € ¿? semántico únicamente raíz líneas ubicación\nFIN_INSTRUCCION_USUARIO\n\nVERIFICACION_FINAL_FLAT\nDevuelve solo {\"create\":[],\"changes\":[],\"delete\":[],\"structure\":[],\"intents\":[]}. Respeta la separación contractual de changes e intents definida en las reglas. En intents, omite las claves opcionales no usadas; no uses null. Respeta el ámbito y modifica solo coincidencias literales. No inventes IDs, propiedades, campos, valores ni operaciones. Aplica el cambio mínimo.\nFIN_VERIFICACION_FINAL_FLAT\n"}],"stream":false,"format":"json","keep_alive":-1,"options":{"temperature":0,"top_p":1,"top_k":0,"repeat_penalty":1.1,"frequency_penalty":0,"presence_penalty":0,"num_ctx":65536,"num_batch":4096,"num_thread":10,"num_gpu":99,"num_predict":4096},"think":"low"}