Files
CST-agent/tests/test_prompt_contract.c
WHCandCursor 814a31c9c8 feat: restore CI/release, prompt contracts, faster install (0.9.33)
Bring back Gitea CI + auto-publish; share release helpers; strengthen multi-turn
tool/job prompts with a unit contract; ccache/make help and --release bootstrap.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-29 19:56:42 +08:00

84 lines
3.2 KiB
C

#define _POSIX_C_SOURCE 200809L
/* Multi-round prompt contract: default/solo guidance must stay present so
* models stop serializing reads, re-fetching truncations, and busy-waiting
* on background jobs. */
#include "cst_agent.h"
#include "cst_tools.h"
#include "cst_test_util.h"
#include "os_compat.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int nfail;
#define EXPECT(cond, msg) \
do { \
if (!(cond)) { \
fprintf(stderr, "FAIL %s:%d: %s\n", __FILE__, __LINE__, msg); \
nfail++; \
} \
} while (0)
static void need(const char *p, const char *needle, const char *why) {
EXPECT(p && strstr(p, needle), why);
}
int main(void) {
char dir[2048], cfghome[2048];
assert(!test_tmpdir(dir, sizeof(dir), "prompt-contract"));
assert(chdir(dir) == 0);
/* Isolate settings / parliament meta so host collaboration cannot leak. */
assert(snprintf(cfghome, sizeof(cfghome), "%s/xdg", dir) < (int)sizeof(cfghome));
assert(os_mkdir_p(cfghome, 0700) == 0);
setenv("XDG_CONFIG_HOME", cfghome, 1);
setenv("CST_COLLABORATION", "legacy_workers", 1);
cst_agent_config_t cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.tool_profile = CST_TOOLS_DEFAULT;
snprintf(cfg.workspace_root, sizeof(cfg.workspace_root), "%s", dir);
char *solo = cst_agent_build_prompt(&cfg, CST_PROTO_NATIVE_EOS, NULL);
need(solo, "run in parallel", "parallel reads");
need(solo, "[truncated bytes=", "truncation protocol");
need(solo, "evidence_read", "evidence follow-up");
need(solo, "Background jobs finished", "job completion note");
need(solo, "polling job_wait", "no busy wait");
need(solo, "Across turns", "multi-turn reuse");
need(solo, "do not restart exploration from scratch", "continue context");
need(solo, "Task control:", "solo task path");
EXPECT(solo && !strstr(solo, "Parliament control:"), "solo not parliament");
free(solo);
snprintf(cfg.mode, sizeof(cfg.mode), "general");
char *gen = cst_agent_build_prompt(&cfg, CST_PROTO_NATIVE_EOS, NULL);
need(gen, "general-purpose assistant", "general intro");
need(gen, "Across turns", "general multi-turn");
free(gen);
cfg.mode[0] = 0;
setenv("CST_COLLABORATION", "parliament", 1);
char *parl = cst_agent_build_prompt(&cfg, CST_PROTO_NATIVE_EOS, NULL);
need(parl, "Parliament control:", "parliament path");
EXPECT(parl && !strstr(parl, "Task control:"), "parliament hides task ctrl");
free(parl);
setenv("CST_COLLABORATION", "legacy_workers", 1);
cfg.tool_profile = CST_TOOLS_MINIMAL;
char *min = cst_agent_build_prompt(&cfg, CST_PROTO_NATIVE_EOS, NULL);
EXPECT(min && !strstr(min, "Background jobs finished"),
"minimal omits job guidance");
free(min);
test_rmrf(dir);
if (nfail) {
fprintf(stderr, "%d prompt-contract failure(s)\n", nfail);
return 1;
}
puts("test_prompt_contract: OK");
return 0;
}