There appears to be no way to author a function that causes mutations that will return a value. Consider the use case below:
@Query({ apiName: "upsertState" })
public async upsertState(
plan?: string,
forward: boolean = true,
executionId?: string,
inputs: string = '{}',
xreason: string = SupportedEngines.COMS): Promise<MachineExecutions> {
// I have to include this call or I will get an error that I am attempting to call a function not in the function registry
// This is due to the GPT_4o being tree shaked by their algorithm
// I did report the issue to Palantir but they likely will not fix
const response = GPT_4o.createChatCompletion(
{
messages: [
{ role: "SYSTEM", contents: [{ text: 'You are a helpful AI assistant' }] },
{ role: "USER", contents: [{ text: 'what is your name?' }] },
]
}
);
const solution = {
input: '', //not relevant for this
id: executionId || Uuid.random(),
plan: plan || '',
};
const result = await getState(solution, forward, JSON.parse(inputs), xreason as SupportedEngines);
await this.updateMachine(solution.id,
JSON.stringify(result.stateMachine),
result.jsonState,
result.logs
);
// IMPORTANT: there are no strong read after write gaurentees in Foundry!
// this means have to wait a bit for edits to be applied
// read this for more details: https://www.palantir.com/docs/foundry/functions/edits-overview#caveat-edits-and-object-search
// I'm told that if you search by id then you will get results immediatly, but leaving the loop here just for testing.
const machine = await new Promise<MachineExecutions>(async (resolve, reject) => {
let machine = getMachineExecution(solution);
if (machine) {
console.log(`machine with ID ${machine.id} found immediatly after write`);
return resolve(machine);
}
const interval = 1000; // 1 second interval
const iterations = 5; // Run 5 times
const timer = customTimer(interval, iterations);
// I have no idea why but I can't import timing functions from node so I wrote my own
for await (const tick of timer) {
console.log(`Tick ${tick + 1}`);
console.log(new Date().getSeconds());
machine = getMachineExecution(solution);
if (machine) {
return resolve(machine);
}
}
return reject(new Error('Machine execution could not be retrieved after 10 seconds'));
})
return machine;
}
@Edits(MachineExecutions)
@OntologyEditFunction()
public async updateMachine(id: string, stateMachine: string, state: string, logs: string | undefined): Promise<void> {
const solution = {
input: '', //not relevant for this
id: id || Uuid.random(),
plan: '', //not relevant for this
};
let machine = getMachineExecution(solution);
if (!machine) {
machine = Objects.create().machineExecutions(solution.id);
}
machine.machine = stateMachine;
machine.state = state;
machine.logs = logs;
machine.currentState = JSON.parse(state).value;
}
The upsertState
function is what my application needs to consume. But edits are only applied when functions back actions:
“To actually be used in an operational context, Ontology Edit Functions must be configured as an Action , known as a Function-backed Action. Configuring an Action in this way allows you to provide additional metadata, configure permissions, and access the Action in various operational interfaces. As noted in the documentation, running an Edit Function outside of an Action will not actually modify any object data.”
My only workaround is to use fetch to invoke the edit action via an API call or break apart the upsert function into multiple calls, which is not ideal. I am reading this right? Does anyone else have any ideas here? This is a very limiting restriction, if this is correct.