function cleanup() -- ast_verbose("**** Cleanup ") end function enter_queue(entry,vars) local required_skills = get_required_skills(vars) for required_skill,required_skill_level in pairs(required_skills) do ast_queue_log(entry.queuename, entry.uniqueid, "NONE", "INFO", "REQSKILL" .. "|" .. required_skill .. "|" .. required_skill_level) end end function get_topic(vars) return vars['MDC_TOPIC'] end -- returns a table of required skill_var_name/skill_level pairs function get_required_skills(vars) local skills={} local topic = get_topic(vars) if topic == nil then return skills end for skill in string.gmatch(topic, "([^,]+)") do local skill_level = vars["MDC_SKILL-" .. skill] if skill_level ~= nil and skill_level ~= '' then skills[skill] = tonumber(skill_level) end end return skills end -- returns the level of the agent's skill. -1 if agent has no skill. astdb values wins function get_agent_skill_level(vars, member, skill_var_name) -- lookup the skills table for this agent local skillset = agent_skills[member.membername] if skillset == nil then -- we require a skill but the agent does not have ANY skills, -- so skip this agent -- ast_verbose("Agent " .. member.membername .." has no skills") return -1 end -- lookup required skill local level = tonumber(skillset['MDC_SKILL-' .. skill_var_name]) if level == nil then -- Agent does not have the required skill -- so skip this agent -- ast_verbose("Agent " .. member.membername .." misses skill " .. key) return -1 end -- ast_verbose("Agent " .. member.membername .." has defaull skill " .. skill_var_name .. " " .. level) return level end function is_our_turn(entry) local available = 0 local topic = get_topic(entry.variables) -- pre-check available agent local all_agents = get_members() local all_entries = get_entries() for _,member in pairs(all_agents) do -- check if this member is available and skills would match the entries requirements local result = calc_metric_internal(member,entry,entry.variables) if result ~= -1 then available = available + 1 -- check if this member can handle some of the previous calls for pos,other in pairs(all_entries) do -- if it's not panding if other.pending == 0 then if other.channel == entry.channel then -- we reached current entry - it's our turn return 1 else -- do we have the same topic if yes we know that we should wait longer local other_topic = get_topic(other.variables) if other_topic == topic then return 0 end local other_result = calc_metric(member,other,other.variables) if other_result ~= -1 then -- other call has higher priority - we should still wait return 0 end end end end end end return 0 end function calc_metric_internal(member,entry,vars) -- not available or pending? if member.available == 0 or member.pending == 1 then return -1 end local score=0 -- find required skills levels local required_skills = get_required_skills(vars) for required_skill,required_skill_level in pairs(required_skills) do local agent_skill_level = get_agent_skill_level(vars, member, required_skill) if agent_skill_level < required_skill_level then -- Agents skill level is to low -- so skip this agent -- ast_verbose("Agent " .. member.membername .." skill " .. required_skill .. " level to low: " .. agent_skill_level .."<" ..required_skill_level) return -1 end score = score + agent_skill_level end return score end function calc_metric(member,entry,vars) -- whats my score? local my_metric = calc_metric_internal(member,entry,vars) -- we're not available, don't fit otherwise (-1) OR asterisk should choose (0)? if my_metric <= 0 then -- so we're done already... return my_metric end -- lets have a tournament with my fellow agents... local all_agents = get_members() for _,other_member in pairs(all_agents) do local other_metric = calc_metric_internal(other_member,entry,entry.variables) if other_metric > my_metric then -- somebody else is smarter then me... so i can skip -- ast_verbose("Agent " .. other_member.membername .. " has better score " .. other_metric .." than " ..member.membername .." with score " ..my_metric) return -1 end end -- nobody else had a HIGHER score. So i stay in the game... -- now let asterisk choose from all the highest ranked agents -- ast_verbose("Agent " .. member.membername .. " scores " .. my_metric) return 0; end