Skip to content

PTC with MicroVMs generate the same clientToken #59

Description

@snapydziuba

Programmatic Tool Calling replay reuses one CodeAPI executionId across multiple stateless MicroVM iterations. The stateless MicroVM client token was derived only from the execution ID and launch configuration.

After LibreChat returned an MCP result, CodeAPI persisted it to Redis and launched the next replay iteration with an updated sandbox payload containing _ptc_history.json. Because the launch configuration was unchanged, the worker reused the prior AWS clientToken.

AWS rejected the second launch with:

The provided clientToken was used with different request parameters.

This caused LibreChat to report the generic Bash programmatic execution failed: Code execution failed.

I made a change that includes the sandbox request body in the stateless client-token fingerprint. Each replay iteration now receives a distinct token when its replay payload changes, while identical requests remain deterministic for idempotency.

I added to lamda-microvm.ts and calling it in the VM launch of executeStateless:

function statelessLaunchClientToken(
  executionId: string,
  config: LambdaMicrovmBackendConfig,
  maxDurationSeconds: number,
  request: SandboxTransportRequest,
): string {
  const requestFingerprint = JSON.stringify({
    imageArn: config.imageArn,
    imageVersion: config.imageVersion,
    executionRoleArn: config.executionRoleArn,
    logGroup: config.logGroup,
    ingressConnectorArns: config.ingressConnectorArns,
    egressConnectorArns: config.egressConnectorArns,
    maximumDurationSeconds: maxDurationSeconds,
    body: request.body,
  });
  const suffix = createHash('sha256').update(requestFingerprint, 'utf8').digest('hex').slice(0, 16);
  return `exec-${executionId}-${suffix}`;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions