To solve this optimization problem, we need to first define the symbolic representation of the variables and the objective function. Then, we will list out all the constraints in a semi-algebraic form.

Let's denote:
- $x_0$ as the quantity of protein bars,
- $x_1$ as the number of cantaloupes.

The objective function is to minimize: $4.7x_0 + 2.79x_1$.

Now, let's list out the constraints based on the problem description:
1. Total combined umami index from protein bars and cantaloupes must be at least 29: $24x_0 + 21x_1 \geq 29$.
2. Total combined grams of carbohydrates from protein bars and cantaloupes must be at least 49: $2x_0 + 9x_1 \geq 49$.
3. Total combined healthiness rating from protein bars and cantaloupes must be at least 40: $11x_0 + 10x_1 \geq 40$.
4. The constraint $-3x_0 + 8x_1 \geq 0$.
5. Total combined umami index from protein bars and cantaloupes must be at most 55: $24x_0 + 21x_1 \leq 55$.
6. Total grams of carbohydrates from protein bars and cantaloupes must not exceed 178: $2x_0 + 9x_1 \leq 178$.
7. Total combined healthiness rating from protein bars and cantaloupes must not exceed 107: $11x_0 + 10x_1 \leq 107$.

Symbolic representation:
```json
{
    'sym_variables': [('x0', 'protein bars'), ('x1', 'cantaloupes')],
    'objective_function': '4.7*x0 + 2.79*x1',
    'constraints': [
        '24*x0 + 21*x1 >= 29',
        '2*x0 + 9*x1 >= 49',
        '11*x0 + 10*x1 >= 40',
        '-3*x0 + 8*x1 >= 0',
        '24*x0 + 21*x1 <= 55',
        '2*x0 + 9*x1 <= 178',
        '11*x0 + 10*x1 <= 107'
    ]
}
```

Now, let's write the Gurobi code to solve this optimization problem:
```python
from gurobipy import *

# Create a new model
m = Model("Optimization_Problem")

# Add variables: x0 is continuous and x1 is integer
x0 = m.addVar(lb=0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name="protein_bars")
x1 = m.addVar(lb=0, ub=GRB.INFINITY, vtype=GRB.INTEGER, name="cantaloupes")

# Set the objective function
m.setObjective(4.7*x0 + 2.79*x1, GRB.MINIMIZE)

# Add constraints
m.addConstr(24*x0 + 21*x1 >= 29, "umami_index_min")
m.addConstr(2*x0 + 9*x1 >= 49, "carbohydrates_min")
m.addConstr(11*x0 + 10*x1 >= 40, "healthiness_rating_min")
m.addConstr(-3*x0 + 8*x1 >= 0, "mix_constraint")
m.addConstr(24*x0 + 21*x1 <= 55, "umami_index_max")
m.addConstr(2*x0 + 9*x1 <= 178, "carbohydrates_max")
m.addConstr(11*x0 + 10*x1 <= 107, "healthiness_rating_max")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Protein bars: {x0.x}")
    print(f"Cantaloupes: {x1.x}")
    print(f"Objective function value: {m.objVal}")
else:
    print("No optimal solution found")
```