@percena/weft 0.4.0-next.4 → 0.4.0-next.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.cjs +7 -883
- package/dist/chat.d.cts +13 -13
- package/dist/chat.d.ts +13 -13
- package/dist/chat.js +7 -883
- package/dist/index.cjs +96 -103
- package/dist/index.js +96 -103
- package/dist/providers-flitro.cjs +2 -276
- package/dist/providers-flitro.d.cts +2 -1
- package/dist/providers-flitro.d.ts +2 -1
- package/dist/providers-flitro.js +1 -260
- package/dist/styles/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/package.json +1 -1
package/dist/chat.cjs
CHANGED
|
@@ -7119,27 +7119,6 @@ var import_react18 = require("react");
|
|
|
7119
7119
|
var import_react19 = require("react");
|
|
7120
7120
|
|
|
7121
7121
|
// ../packages/timeline/dist/index.js
|
|
7122
|
-
function createTimelineCursor(cursor) {
|
|
7123
|
-
return {
|
|
7124
|
-
epoch: cursor.epoch,
|
|
7125
|
-
afterSeq: cursor.afterSeq
|
|
7126
|
-
};
|
|
7127
|
-
}
|
|
7128
|
-
function fetchTimeline(timeline, request = {}) {
|
|
7129
|
-
const ordered = sortTimeline(timeline);
|
|
7130
|
-
const cursor = request.cursor ?? cursorFromTimelineStart(ordered);
|
|
7131
|
-
const items = ordered.filter((item) => item.epoch === cursor.epoch && item.seq > cursor.afterSeq).slice(0, request.limit);
|
|
7132
|
-
const lastSeq = items.at(-1)?.seq ?? cursor.afterSeq;
|
|
7133
|
-
const firstSeq = items[0]?.seq;
|
|
7134
|
-
return {
|
|
7135
|
-
items,
|
|
7136
|
-
nextCursor: {
|
|
7137
|
-
epoch: cursor.epoch,
|
|
7138
|
-
afterSeq: lastSeq
|
|
7139
|
-
},
|
|
7140
|
-
hasGap: firstSeq !== void 0 && firstSeq > cursor.afterSeq + 1
|
|
7141
|
-
};
|
|
7142
|
-
}
|
|
7143
7122
|
function mergeTimeline(existing, incoming) {
|
|
7144
7123
|
const byKey = /* @__PURE__ */ new Map();
|
|
7145
7124
|
for (const item of [...existing, ...incoming]) {
|
|
@@ -7147,12 +7126,6 @@ function mergeTimeline(existing, incoming) {
|
|
|
7147
7126
|
}
|
|
7148
7127
|
return sortTimeline([...byKey.values()]);
|
|
7149
7128
|
}
|
|
7150
|
-
function cursorFromTimelineStart(timeline) {
|
|
7151
|
-
return {
|
|
7152
|
-
epoch: timeline[0]?.epoch ?? "default",
|
|
7153
|
-
afterSeq: 0
|
|
7154
|
-
};
|
|
7155
|
-
}
|
|
7156
7129
|
function sortTimeline(timeline) {
|
|
7157
7130
|
return [...timeline].sort((left, right) => {
|
|
7158
7131
|
if (left.epoch !== right.epoch) return left.epoch.localeCompare(right.epoch);
|
|
@@ -7930,879 +7903,30 @@ function TimelineAgentChatPanel({
|
|
|
7930
7903
|
var import_react21 = require("react");
|
|
7931
7904
|
|
|
7932
7905
|
// ../packages/runtime-core/dist/index.js
|
|
7933
|
-
var RUNTIME_KINDS = ["native-sdk", "app-server", "compatible-sdk", "cli-fallback"];
|
|
7934
7906
|
var initialRuntimeState = {
|
|
7935
7907
|
status: "idle",
|
|
7936
7908
|
acceptedMessages: [],
|
|
7937
7909
|
queuedMessages: []
|
|
7938
7910
|
};
|
|
7939
|
-
function reduceRuntimeState(state = initialRuntimeState, action) {
|
|
7940
|
-
switch (action.type) {
|
|
7941
|
-
case "preflight_start":
|
|
7942
|
-
return { ...state, status: "preflighting", lastError: void 0 };
|
|
7943
|
-
case "preflight_ok":
|
|
7944
|
-
return { ...state, status: "ready", lastError: void 0 };
|
|
7945
|
-
case "preflight_error":
|
|
7946
|
-
return { ...state, status: "failed", lastError: action.error };
|
|
7947
|
-
case "starting":
|
|
7948
|
-
if (state.status === "ready" || state.status === "idle") {
|
|
7949
|
-
return { ...state, status: "starting" };
|
|
7950
|
-
}
|
|
7951
|
-
return state;
|
|
7952
|
-
case "send_message":
|
|
7953
|
-
if (state.status === "running" || state.status === "waiting_for_permission") {
|
|
7954
|
-
return {
|
|
7955
|
-
...state,
|
|
7956
|
-
queuedMessages: [...state.queuedMessages, action.message]
|
|
7957
|
-
};
|
|
7958
|
-
}
|
|
7959
|
-
return {
|
|
7960
|
-
...state,
|
|
7961
|
-
status: "running",
|
|
7962
|
-
acceptedMessages: [...state.acceptedMessages, action.message]
|
|
7963
|
-
};
|
|
7964
|
-
case "permission_request":
|
|
7965
|
-
return {
|
|
7966
|
-
...state,
|
|
7967
|
-
status: "waiting_for_permission",
|
|
7968
|
-
waitingPermissionRequestId: action.requestId
|
|
7969
|
-
};
|
|
7970
|
-
case "permission_response":
|
|
7971
|
-
return {
|
|
7972
|
-
...state,
|
|
7973
|
-
status: "running",
|
|
7974
|
-
waitingPermissionRequestId: void 0
|
|
7975
|
-
};
|
|
7976
|
-
case "turn_completed":
|
|
7977
|
-
if (state.status === "running") {
|
|
7978
|
-
return { ...state, status: "turn_completed" };
|
|
7979
|
-
}
|
|
7980
|
-
return state;
|
|
7981
|
-
case "complete": {
|
|
7982
|
-
if (state.status === "turn_completed") {
|
|
7983
|
-
const [nextMessage2, ...remaining2] = state.queuedMessages;
|
|
7984
|
-
if (nextMessage2) {
|
|
7985
|
-
return {
|
|
7986
|
-
...state,
|
|
7987
|
-
status: "running",
|
|
7988
|
-
acceptedMessages: [...state.acceptedMessages, nextMessage2],
|
|
7989
|
-
queuedMessages: remaining2
|
|
7990
|
-
};
|
|
7991
|
-
}
|
|
7992
|
-
return { ...state, status: "ready" };
|
|
7993
|
-
}
|
|
7994
|
-
const [nextMessage, ...remaining] = state.queuedMessages;
|
|
7995
|
-
if (nextMessage) {
|
|
7996
|
-
return {
|
|
7997
|
-
...state,
|
|
7998
|
-
status: "running",
|
|
7999
|
-
acceptedMessages: [...state.acceptedMessages, nextMessage],
|
|
8000
|
-
queuedMessages: remaining
|
|
8001
|
-
};
|
|
8002
|
-
}
|
|
8003
|
-
return { ...state, status: "ready" };
|
|
8004
|
-
}
|
|
8005
|
-
case "abort":
|
|
8006
|
-
return {
|
|
8007
|
-
...state,
|
|
8008
|
-
status: "ready",
|
|
8009
|
-
lastError: action.reason,
|
|
8010
|
-
queuedMessages: [],
|
|
8011
|
-
waitingPermissionRequestId: void 0
|
|
8012
|
-
};
|
|
8013
|
-
case "error":
|
|
8014
|
-
return { ...state, status: "failed", lastError: action.error };
|
|
8015
|
-
case "dispose":
|
|
8016
|
-
return {
|
|
8017
|
-
...state,
|
|
8018
|
-
status: "disposed",
|
|
8019
|
-
queuedMessages: [],
|
|
8020
|
-
waitingPermissionRequestId: void 0
|
|
8021
|
-
};
|
|
8022
|
-
}
|
|
8023
|
-
}
|
|
8024
|
-
function createRuntimeExtensionContext(context = {}) {
|
|
8025
|
-
return {
|
|
8026
|
-
policy: context.policy,
|
|
8027
|
-
sources: context.sources ? { enabledSourceSlugs: unique(context.sources.enabledSourceSlugs) } : void 0,
|
|
8028
|
-
skills: context.skills ? { activeSkillSlugs: unique(context.skills.activeSkillSlugs) } : void 0,
|
|
8029
|
-
commandOrigin: context.commandOrigin,
|
|
8030
|
-
hostServices: context.hostServices
|
|
8031
|
-
};
|
|
8032
|
-
}
|
|
8033
|
-
function unique(values) {
|
|
8034
|
-
return [...new Set(values)];
|
|
8035
|
-
}
|
|
8036
|
-
function findCandidate(candidates, kind) {
|
|
8037
|
-
return candidates.find((candidate) => candidate.kind === kind);
|
|
8038
|
-
}
|
|
8039
|
-
function defaultRuntimeKindOrder(provider) {
|
|
8040
|
-
if (provider === "codex") {
|
|
8041
|
-
return ["app-server", "native-sdk", "compatible-sdk", "cli-fallback"];
|
|
8042
|
-
}
|
|
8043
|
-
return RUNTIME_KINDS;
|
|
8044
|
-
}
|
|
8045
|
-
function firstAvailableCandidate(candidates, provider) {
|
|
8046
|
-
for (const kind of defaultRuntimeKindOrder(provider)) {
|
|
8047
|
-
const candidate = findCandidate(candidates, kind);
|
|
8048
|
-
if (candidate?.available) return candidate;
|
|
8049
|
-
}
|
|
8050
|
-
return void 0;
|
|
8051
|
-
}
|
|
8052
|
-
function selectRuntimeCandidate(options) {
|
|
8053
|
-
const preferred = options.preferredRuntime ? findCandidate(options.candidates, options.preferredRuntime) : void 0;
|
|
8054
|
-
if (preferred?.available) {
|
|
8055
|
-
return { selected: preferred.kind, fallback: false };
|
|
8056
|
-
}
|
|
8057
|
-
if (preferred && options.allowFallback !== true) {
|
|
8058
|
-
return {
|
|
8059
|
-
fallback: false,
|
|
8060
|
-
error: preferred.reason ?? `${preferred.kind} runtime is unavailable`
|
|
8061
|
-
};
|
|
8062
|
-
}
|
|
8063
|
-
const selected = firstAvailableCandidate(options.candidates, options.provider);
|
|
8064
|
-
if (!selected) {
|
|
8065
|
-
return {
|
|
8066
|
-
fallback: false,
|
|
8067
|
-
error: options.candidates.map((candidate) => candidate.reason).filter(Boolean).join("; ") || "No runtime candidates are available"
|
|
8068
|
-
};
|
|
8069
|
-
}
|
|
8070
|
-
const fallback = Boolean(preferred && selected.kind !== preferred.kind);
|
|
8071
|
-
return {
|
|
8072
|
-
selected: selected.kind,
|
|
8073
|
-
fallback,
|
|
8074
|
-
fallbackReason: fallback ? preferred?.reason ?? `${preferred?.kind ?? "preferred"} runtime is unavailable` : void 0
|
|
8075
|
-
};
|
|
8076
|
-
}
|
|
8077
|
-
function createRuntimeCapabilityReport(options) {
|
|
8078
|
-
const selection = selectRuntimeCandidate(options);
|
|
8079
|
-
const extensionCapabilities = normalizeExtensionCapabilities(options.extensionCapabilities);
|
|
8080
|
-
return {
|
|
8081
|
-
provider: options.provider,
|
|
8082
|
-
candidates: options.candidates,
|
|
8083
|
-
preferredRuntime: options.preferredRuntime,
|
|
8084
|
-
allowFallback: options.allowFallback === true,
|
|
8085
|
-
auth: options.auth,
|
|
8086
|
-
...extensionCapabilities,
|
|
8087
|
-
...selection
|
|
8088
|
-
};
|
|
8089
|
-
}
|
|
8090
|
-
function normalizeExtensionCapabilities(capabilities = {}) {
|
|
8091
|
-
return {
|
|
8092
|
-
policyCapabilities: capabilities.policy ?? {
|
|
8093
|
-
supported: false,
|
|
8094
|
-
modes: [],
|
|
8095
|
-
approvals: false,
|
|
8096
|
-
toolPolicy: false
|
|
8097
|
-
},
|
|
8098
|
-
sourceCapabilities: capabilities.sources ?? {
|
|
8099
|
-
supported: false
|
|
8100
|
-
},
|
|
8101
|
-
skillCapabilities: capabilities.skills ?? {
|
|
8102
|
-
supported: false
|
|
8103
|
-
},
|
|
8104
|
-
automationCapabilities: capabilities.automations ?? {
|
|
8105
|
-
supported: false,
|
|
8106
|
-
eventBus: false,
|
|
8107
|
-
schedulerHost: false,
|
|
8108
|
-
promptAction: false,
|
|
8109
|
-
webhookAction: false
|
|
8110
|
-
},
|
|
8111
|
-
hostToolCapabilities: capabilities.hostTools ?? {
|
|
8112
|
-
supported: false,
|
|
8113
|
-
sessionTools: false,
|
|
8114
|
-
workflowTransitions: false,
|
|
8115
|
-
browserActions: false,
|
|
8116
|
-
metadataWrites: false
|
|
8117
|
-
}
|
|
8118
|
-
};
|
|
8119
|
-
}
|
|
8120
|
-
|
|
8121
|
-
// ../packages/client/dist/index.js
|
|
8122
|
-
var FlitroHttpClient = class {
|
|
8123
|
-
baseUrl;
|
|
8124
|
-
timeout;
|
|
8125
|
-
apiKey;
|
|
8126
|
-
tenantId;
|
|
8127
|
-
onTokenExpired;
|
|
8128
|
-
token;
|
|
8129
|
-
constructor(options) {
|
|
8130
|
-
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
8131
|
-
this.timeout = options.timeout ?? 3e4;
|
|
8132
|
-
this.apiKey = options.apiKey ?? "";
|
|
8133
|
-
this.tenantId = options.tenantId ?? "";
|
|
8134
|
-
this.token = options.token ?? "";
|
|
8135
|
-
this.onTokenExpired = options.onTokenExpired;
|
|
8136
|
-
}
|
|
8137
|
-
/** Current Authorization bearer (scoped token wins over apiKey). */
|
|
8138
|
-
getBearerToken() {
|
|
8139
|
-
return this.token || this.apiKey;
|
|
8140
|
-
}
|
|
8141
|
-
/** Replace the scoped token (e.g. after a host-backend refresh). */
|
|
8142
|
-
setToken(token) {
|
|
8143
|
-
this.token = token;
|
|
8144
|
-
}
|
|
8145
|
-
buildHeaders() {
|
|
8146
|
-
const headers = { "Content-Type": "application/json" };
|
|
8147
|
-
const bearer = this.getBearerToken();
|
|
8148
|
-
if (bearer) headers["Authorization"] = `Bearer ${bearer}`;
|
|
8149
|
-
if (!this.token && this.tenantId) headers["X-Tenant-ID"] = this.tenantId;
|
|
8150
|
-
return headers;
|
|
8151
|
-
}
|
|
8152
|
-
async preflight() {
|
|
8153
|
-
return this.get("/v1/capabilities");
|
|
8154
|
-
}
|
|
8155
|
-
async health() {
|
|
8156
|
-
return this.get("/v1/health");
|
|
8157
|
-
}
|
|
8158
|
-
async createSession(options) {
|
|
8159
|
-
return this.post("/v1/sessions", {
|
|
8160
|
-
title: options?.title ?? "Weft session",
|
|
8161
|
-
model: options?.model,
|
|
8162
|
-
skill_names: options?.skillNames,
|
|
8163
|
-
mcp_server_names: options?.mcpServerNames
|
|
8164
|
-
});
|
|
8165
|
-
}
|
|
8166
|
-
async getSession(sessionId) {
|
|
8167
|
-
return this.get(`/v1/sessions/${encodeURIComponent(sessionId)}`);
|
|
8168
|
-
}
|
|
8169
|
-
async sendMessage(sessionId, message, options) {
|
|
8170
|
-
const budget = options?.budget ? {
|
|
8171
|
-
max_steps: options.budget.maxSteps,
|
|
8172
|
-
max_tokens: options.budget.maxTokens,
|
|
8173
|
-
max_wall_time_sec: options.budget.maxWallTimeSec
|
|
8174
|
-
} : void 0;
|
|
8175
|
-
return this.post(`/v1/sessions/${encodeURIComponent(sessionId)}/runs`, {
|
|
8176
|
-
message,
|
|
8177
|
-
model: options?.model,
|
|
8178
|
-
skill_names: options?.skillNames,
|
|
8179
|
-
mcp_server_names: options?.mcpServerNames,
|
|
8180
|
-
tool_names: options?.toolNames,
|
|
8181
|
-
approval_policy: options?.approvalPolicy,
|
|
8182
|
-
execution_mode: options?.executionMode,
|
|
8183
|
-
workspace_id: options?.workspaceId,
|
|
8184
|
-
budget
|
|
8185
|
-
});
|
|
8186
|
-
}
|
|
8187
|
-
async cancelRun(runId) {
|
|
8188
|
-
return this.post(`/v1/runs/${encodeURIComponent(runId)}/cancel`, {});
|
|
8189
|
-
}
|
|
8190
|
-
async resumeTool(runId, resumeData) {
|
|
8191
|
-
return this.post(
|
|
8192
|
-
`/v1/runs/${encodeURIComponent(runId)}/resume-tool`,
|
|
8193
|
-
{ resume_data: resumeData }
|
|
8194
|
-
);
|
|
8195
|
-
}
|
|
8196
|
-
async respondToPermission(sessionId, requestId, allowed, options) {
|
|
8197
|
-
return this.post(
|
|
8198
|
-
`/v1/sessions/${encodeURIComponent(sessionId)}/permission-response`,
|
|
8199
|
-
{ requestId, allowed, remember: options?.remember, text: options?.text, answer: options?.answer }
|
|
8200
|
-
);
|
|
8201
|
-
}
|
|
8202
|
-
async patchSession(sessionId, patch) {
|
|
8203
|
-
return this.patch(
|
|
8204
|
-
`/v1/sessions/${encodeURIComponent(sessionId)}`,
|
|
8205
|
-
patch
|
|
8206
|
-
);
|
|
8207
|
-
}
|
|
8208
|
-
async listModels() {
|
|
8209
|
-
return this.get("/v1/models");
|
|
8210
|
-
}
|
|
8211
|
-
async fetchTimeline(sessionId, afterSeq, limit) {
|
|
8212
|
-
const params = new URLSearchParams();
|
|
8213
|
-
if (afterSeq !== void 0) params.set("after_seq", String(afterSeq));
|
|
8214
|
-
if (limit !== void 0) params.set("limit", String(limit));
|
|
8215
|
-
const qs = params.toString();
|
|
8216
|
-
const url = `/v1/sessions/${encodeURIComponent(sessionId)}/timeline/fetch${qs ? `?${qs}` : ""}`;
|
|
8217
|
-
return this.get(url);
|
|
8218
|
-
}
|
|
8219
|
-
/** Returns the SSE stream URL for a session's canonical timeline. */
|
|
8220
|
-
sessionTimelineUrl(sessionId) {
|
|
8221
|
-
return `${this.baseUrl}/v1/sessions/${encodeURIComponent(sessionId)}/timeline`;
|
|
8222
|
-
}
|
|
8223
|
-
async get(path) {
|
|
8224
|
-
return this.request("GET", path, void 0);
|
|
8225
|
-
}
|
|
8226
|
-
async post(path, body) {
|
|
8227
|
-
return this.request("POST", path, body);
|
|
8228
|
-
}
|
|
8229
|
-
async patch(path, body) {
|
|
8230
|
-
return this.request("PATCH", path, body);
|
|
8231
|
-
}
|
|
8232
|
-
async request(method, path, body, isRetry = false) {
|
|
8233
|
-
const url = `${this.baseUrl}${path}`;
|
|
8234
|
-
const controller = new AbortController();
|
|
8235
|
-
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
8236
|
-
try {
|
|
8237
|
-
const response = await fetch(url, {
|
|
8238
|
-
method,
|
|
8239
|
-
headers: this.buildHeaders(),
|
|
8240
|
-
body: body !== void 0 ? JSON.stringify(body) : void 0,
|
|
8241
|
-
signal: controller.signal
|
|
8242
|
-
});
|
|
8243
|
-
if (response.status === 401 && this.token && this.onTokenExpired && !isRetry) {
|
|
8244
|
-
const fresh = await this.onTokenExpired();
|
|
8245
|
-
if (fresh) {
|
|
8246
|
-
this.token = fresh;
|
|
8247
|
-
return this.request(method, path, body, true);
|
|
8248
|
-
}
|
|
8249
|
-
}
|
|
8250
|
-
if (!response.ok) {
|
|
8251
|
-
let errorMsg = `Flitro HTTP ${response.status}`;
|
|
8252
|
-
try {
|
|
8253
|
-
const errBody = await response.json();
|
|
8254
|
-
if (errBody.error) errorMsg = `${errorMsg}: ${errBody.error}`;
|
|
8255
|
-
} catch {
|
|
8256
|
-
}
|
|
8257
|
-
throw new Error(errorMsg);
|
|
8258
|
-
}
|
|
8259
|
-
return response.json();
|
|
8260
|
-
} finally {
|
|
8261
|
-
clearTimeout(timer);
|
|
8262
|
-
}
|
|
8263
|
-
}
|
|
8264
|
-
};
|
|
8265
|
-
var FlitroFetchSseTimelineStream = class {
|
|
8266
|
-
listeners = /* @__PURE__ */ new Set();
|
|
8267
|
-
abortController = null;
|
|
8268
|
-
connected = false;
|
|
8269
|
-
disposed = false;
|
|
8270
|
-
afterSeq;
|
|
8271
|
-
reconnectAttempts = 0;
|
|
8272
|
-
tokenOverride = "";
|
|
8273
|
-
getBearerToken;
|
|
8274
|
-
onTokenExpired;
|
|
8275
|
-
options;
|
|
8276
|
-
constructor(options) {
|
|
8277
|
-
this.afterSeq = options.initialAfterSeq ?? 0;
|
|
8278
|
-
this.getBearerToken = options.getBearerToken;
|
|
8279
|
-
this.onTokenExpired = options.onTokenExpired;
|
|
8280
|
-
this.options = {
|
|
8281
|
-
url: options.url,
|
|
8282
|
-
apiKey: options.apiKey ?? "",
|
|
8283
|
-
tenantId: options.tenantId ?? "",
|
|
8284
|
-
reconnectDelayMs: options.reconnectDelayMs ?? 1500,
|
|
8285
|
-
maxReconnectAttempts: options.maxReconnectAttempts ?? 20,
|
|
8286
|
-
initialAfterSeq: this.afterSeq,
|
|
8287
|
-
now: options.now ?? (() => Date.now())
|
|
8288
|
-
};
|
|
8289
|
-
}
|
|
8290
|
-
connect(onEvent, onError, onClose) {
|
|
8291
|
-
this.disposed = false;
|
|
8292
|
-
this.listeners.add({ onEvent, onError, onClose });
|
|
8293
|
-
if (!this.connected) {
|
|
8294
|
-
this.connected = true;
|
|
8295
|
-
this.reconnectAttempts = 0;
|
|
8296
|
-
this.startFetch();
|
|
8297
|
-
}
|
|
8298
|
-
}
|
|
8299
|
-
disconnect() {
|
|
8300
|
-
this.disposed = true;
|
|
8301
|
-
this.connected = false;
|
|
8302
|
-
this.abortController?.abort();
|
|
8303
|
-
for (const listener of this.listeners) {
|
|
8304
|
-
listener.onClose?.();
|
|
8305
|
-
}
|
|
8306
|
-
this.listeners.clear();
|
|
8307
|
-
}
|
|
8308
|
-
isConnected() {
|
|
8309
|
-
return this.connected && !this.disposed;
|
|
8310
|
-
}
|
|
8311
|
-
buildUrl() {
|
|
8312
|
-
let url = this.options.url;
|
|
8313
|
-
if (this.afterSeq > 0) {
|
|
8314
|
-
url += (url.includes("?") ? "&" : "?") + `after_seq=${this.afterSeq}`;
|
|
8315
|
-
}
|
|
8316
|
-
return url;
|
|
8317
|
-
}
|
|
8318
|
-
buildHeaders() {
|
|
8319
|
-
const h = { Accept: "text/event-stream" };
|
|
8320
|
-
const bearer = this.tokenOverride || this.getBearerToken?.() || this.options.apiKey;
|
|
8321
|
-
if (bearer) h["Authorization"] = `Bearer ${bearer}`;
|
|
8322
|
-
if (this.options.tenantId) h["X-Tenant-ID"] = this.options.tenantId;
|
|
8323
|
-
return h;
|
|
8324
|
-
}
|
|
8325
|
-
async startFetch() {
|
|
8326
|
-
if (this.disposed) return;
|
|
8327
|
-
this.abortController = new AbortController();
|
|
8328
|
-
try {
|
|
8329
|
-
const response = await fetch(this.buildUrl(), {
|
|
8330
|
-
headers: this.buildHeaders(),
|
|
8331
|
-
signal: this.abortController.signal
|
|
8332
|
-
});
|
|
8333
|
-
if (response.status === 401 && this.onTokenExpired) {
|
|
8334
|
-
const fresh = await this.onTokenExpired();
|
|
8335
|
-
if (fresh) this.tokenOverride = fresh;
|
|
8336
|
-
}
|
|
8337
|
-
if (!response.ok || !response.body) {
|
|
8338
|
-
throw new Error(`Flitro SSE: HTTP ${response.status}`);
|
|
8339
|
-
}
|
|
8340
|
-
this.reconnectAttempts = 0;
|
|
8341
|
-
const reader = response.body.getReader();
|
|
8342
|
-
const decoder = new TextDecoder();
|
|
8343
|
-
let buffer = "";
|
|
8344
|
-
while (true) {
|
|
8345
|
-
const { done, value } = await reader.read();
|
|
8346
|
-
if (done) break;
|
|
8347
|
-
buffer += decoder.decode(value, { stream: true });
|
|
8348
|
-
const envelopes = parseSseBuffer(buffer);
|
|
8349
|
-
buffer = envelopes.remainder;
|
|
8350
|
-
for (const envelope of envelopes.items) {
|
|
8351
|
-
if (envelope.seq > this.afterSeq) {
|
|
8352
|
-
this.afterSeq = envelope.seq;
|
|
8353
|
-
}
|
|
8354
|
-
for (const listener of this.listeners) {
|
|
8355
|
-
listener.onEvent(envelope);
|
|
8356
|
-
}
|
|
8357
|
-
}
|
|
8358
|
-
}
|
|
8359
|
-
if (!this.disposed) {
|
|
8360
|
-
this.connected = false;
|
|
8361
|
-
this.scheduleReconnect();
|
|
8362
|
-
}
|
|
8363
|
-
} catch (err) {
|
|
8364
|
-
if (this.disposed) return;
|
|
8365
|
-
if (err instanceof Error && err.name === "AbortError") return;
|
|
8366
|
-
this.connected = false;
|
|
8367
|
-
this.scheduleReconnect();
|
|
8368
|
-
}
|
|
8369
|
-
}
|
|
8370
|
-
scheduleReconnect() {
|
|
8371
|
-
if (this.disposed) return;
|
|
8372
|
-
if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
|
|
8373
|
-
this.emitError(new Error(`Flitro SSE: max reconnect attempts reached`));
|
|
8374
|
-
return;
|
|
8375
|
-
}
|
|
8376
|
-
this.reconnectAttempts++;
|
|
8377
|
-
const delay = Math.min(this.options.reconnectDelayMs * this.reconnectAttempts, 3e4);
|
|
8378
|
-
setTimeout(() => {
|
|
8379
|
-
this.connected = true;
|
|
8380
|
-
this.startFetch();
|
|
8381
|
-
}, delay);
|
|
8382
|
-
}
|
|
8383
|
-
emitError(err) {
|
|
8384
|
-
for (const listener of this.listeners) listener.onError?.(err);
|
|
8385
|
-
}
|
|
8386
|
-
};
|
|
8387
|
-
function parseSseBuffer(buffer) {
|
|
8388
|
-
const items = [];
|
|
8389
|
-
const blocks = buffer.split("\n\n");
|
|
8390
|
-
const remainder = blocks.pop() ?? "";
|
|
8391
|
-
for (const block of blocks) {
|
|
8392
|
-
let eventType = "";
|
|
8393
|
-
let data = "";
|
|
8394
|
-
for (const line of block.split("\n")) {
|
|
8395
|
-
if (line.startsWith("event: ")) {
|
|
8396
|
-
eventType = line.slice(7).trim();
|
|
8397
|
-
} else if (line.startsWith("data: ")) {
|
|
8398
|
-
data = line.slice(6).trim();
|
|
8399
|
-
}
|
|
8400
|
-
}
|
|
8401
|
-
if (eventType === "timeline" && data) {
|
|
8402
|
-
try {
|
|
8403
|
-
items.push(JSON.parse(data));
|
|
8404
|
-
} catch {
|
|
8405
|
-
}
|
|
8406
|
-
}
|
|
8407
|
-
}
|
|
8408
|
-
return { items, remainder };
|
|
8409
|
-
}
|
|
8410
|
-
function createFlitroTimelineStream(options) {
|
|
8411
|
-
return new FlitroFetchSseTimelineStream(options);
|
|
8412
|
-
}
|
|
8413
|
-
|
|
8414
|
-
// ../packages/provider-flitro/dist/index.js
|
|
8415
|
-
function mapPermissionModeToApprovalPolicy(mode) {
|
|
8416
|
-
if (mode === "allow-all") return "auto";
|
|
8417
|
-
if (mode === "safe") return "never";
|
|
8418
|
-
if (mode === "ask") return "on-request";
|
|
8419
|
-
return void 0;
|
|
8420
|
-
}
|
|
8421
|
-
function createFlitroDriver(options) {
|
|
8422
|
-
let activeRunId;
|
|
8423
|
-
return {
|
|
8424
|
-
async sendMessage(input, _sequencer) {
|
|
8425
|
-
const run = await options.client.sendMessage(
|
|
8426
|
-
options.sessionId,
|
|
8427
|
-
input.message,
|
|
8428
|
-
{
|
|
8429
|
-
model: input.options?.model ?? options.model,
|
|
8430
|
-
skillNames: options.skillNames,
|
|
8431
|
-
mcpServerNames: options.mcpServerNames,
|
|
8432
|
-
// Per-message permission choice (from the chat panel selector) wins
|
|
8433
|
-
// over the runtime's creation-time default.
|
|
8434
|
-
approvalPolicy: mapPermissionModeToApprovalPolicy(input.options?.permissionMode) ?? options.approvalPolicy
|
|
8435
|
-
}
|
|
8436
|
-
);
|
|
8437
|
-
activeRunId = run.run_id;
|
|
8438
|
-
},
|
|
8439
|
-
async abort(reason) {
|
|
8440
|
-
if (activeRunId) {
|
|
8441
|
-
await options.client.cancelRun(activeRunId).catch(() => {
|
|
8442
|
-
});
|
|
8443
|
-
activeRunId = void 0;
|
|
8444
|
-
}
|
|
8445
|
-
},
|
|
8446
|
-
async respondToPermission(requestId, allowed, remember) {
|
|
8447
|
-
await options.client.respondToPermission(options.sessionId, requestId, allowed, {
|
|
8448
|
-
remember
|
|
8449
|
-
});
|
|
8450
|
-
},
|
|
8451
|
-
async resumeTool(runId, resumeData) {
|
|
8452
|
-
await options.client.resumeTool(runId, resumeData);
|
|
8453
|
-
},
|
|
8454
|
-
async dispose() {
|
|
8455
|
-
if (activeRunId) {
|
|
8456
|
-
await options.client.cancelRun(activeRunId).catch(() => {
|
|
8457
|
-
});
|
|
8458
|
-
activeRunId = void 0;
|
|
8459
|
-
}
|
|
8460
|
-
}
|
|
8461
|
-
};
|
|
8462
|
-
}
|
|
8463
|
-
function createFlitroRuntimeCapabilityReport(options) {
|
|
8464
|
-
const appServerAvailable = options.candidates.some((c) => c.kind === "app-server" && c.available);
|
|
8465
|
-
return createRuntimeCapabilityReport({
|
|
8466
|
-
provider: "flitro",
|
|
8467
|
-
candidates: options.candidates,
|
|
8468
|
-
preferredRuntime: "app-server",
|
|
8469
|
-
allowFallback: options.allowFallback,
|
|
8470
|
-
auth: options.auth,
|
|
8471
|
-
extensionCapabilities: {
|
|
8472
|
-
policy: {
|
|
8473
|
-
supported: true,
|
|
8474
|
-
degraded: !appServerAvailable || void 0,
|
|
8475
|
-
modes: ["safe", "ask", "allow-all"],
|
|
8476
|
-
approvals: appServerAvailable,
|
|
8477
|
-
toolPolicy: appServerAvailable,
|
|
8478
|
-
reason: appServerAvailable ? void 0 : "Flitro server is unavailable"
|
|
8479
|
-
},
|
|
8480
|
-
sources: {
|
|
8481
|
-
supported: appServerAvailable,
|
|
8482
|
-
registry: appServerAvailable,
|
|
8483
|
-
mcpTools: appServerAvailable,
|
|
8484
|
-
credentialGateway: false,
|
|
8485
|
-
reason: appServerAvailable ? void 0 : "Source tools require a running Flitro server"
|
|
8486
|
-
},
|
|
8487
|
-
skills: {
|
|
8488
|
-
supported: appServerAvailable,
|
|
8489
|
-
registry: appServerAvailable,
|
|
8490
|
-
activationPlan: appServerAvailable,
|
|
8491
|
-
scopedPolicy: appServerAvailable,
|
|
8492
|
-
reason: appServerAvailable ? void 0 : "Skill activation requires a running Flitro server"
|
|
8493
|
-
},
|
|
8494
|
-
automations: {
|
|
8495
|
-
supported: appServerAvailable,
|
|
8496
|
-
degraded: !appServerAvailable || void 0,
|
|
8497
|
-
eventBus: appServerAvailable,
|
|
8498
|
-
schedulerHost: appServerAvailable,
|
|
8499
|
-
promptAction: appServerAvailable,
|
|
8500
|
-
webhookAction: false,
|
|
8501
|
-
reason: appServerAvailable ? void 0 : "Automations require a running Flitro server"
|
|
8502
|
-
},
|
|
8503
|
-
hostTools: {
|
|
8504
|
-
supported: appServerAvailable,
|
|
8505
|
-
sessionTools: false,
|
|
8506
|
-
workflowTransitions: false,
|
|
8507
|
-
browserActions: false,
|
|
8508
|
-
metadataWrites: appServerAvailable
|
|
8509
|
-
}
|
|
8510
|
-
}
|
|
8511
|
-
});
|
|
8512
|
-
}
|
|
8513
|
-
function createFlitroProviderRuntime(options) {
|
|
8514
|
-
const report = createFlitroRuntimeCapabilityReport(options);
|
|
8515
|
-
const extensions = createRuntimeExtensionContext(options.extensions);
|
|
8516
|
-
const client = new FlitroHttpClient(options.server);
|
|
8517
|
-
let resolvedSessionId = options.sessionId ?? "";
|
|
8518
|
-
let epoch = options.epoch ?? (resolvedSessionId ? `flitro-${resolvedSessionId}` : "flitro-pending");
|
|
8519
|
-
const now = options.now ?? (() => Date.now());
|
|
8520
|
-
const timeline = [];
|
|
8521
|
-
const seenTimelineKeys = /* @__PURE__ */ new Set();
|
|
8522
|
-
const stream = new PushTimelineStream();
|
|
8523
|
-
let state = initialRuntimeState;
|
|
8524
|
-
let runtimeDriver = options.driver;
|
|
8525
|
-
let sseStream;
|
|
8526
|
-
const pendingMessages = [];
|
|
8527
|
-
function dispatch(action) {
|
|
8528
|
-
state = reduceRuntimeState(state, action);
|
|
8529
|
-
}
|
|
8530
|
-
function syncStateFromEnvelope(envelope) {
|
|
8531
|
-
const item = envelope.item;
|
|
8532
|
-
if (item.type === "permission_requested") {
|
|
8533
|
-
dispatch({ type: "permission_request", requestId: item.request.requestId });
|
|
8534
|
-
} else if (item.type === "permission_resolved") {
|
|
8535
|
-
dispatch({ type: "permission_response" });
|
|
8536
|
-
} else if (item.type === "turn_completed") {
|
|
8537
|
-
dispatch({ type: "turn_completed" });
|
|
8538
|
-
dispatch({ type: "complete" });
|
|
8539
|
-
void sendNextPendingMessage();
|
|
8540
|
-
} else if (item.type === "turn_failed") {
|
|
8541
|
-
const err = item.error;
|
|
8542
|
-
dispatch({ type: "error", error: err?.message ?? "turn failed" });
|
|
8543
|
-
} else if (item.type === "tool_suspended") {
|
|
8544
|
-
dispatch({ type: "permission_request", requestId: `tool-suspend:${item.callId}` });
|
|
8545
|
-
} else if (item.type === "tool_resumed") {
|
|
8546
|
-
dispatch({ type: "permission_response" });
|
|
8547
|
-
} else if (item.type === "session_status") {
|
|
8548
|
-
if (item.status === "running") {
|
|
8549
|
-
dispatch({ type: "starting" });
|
|
8550
|
-
} else if (item.status === "ended") {
|
|
8551
|
-
dispatch({ type: "abort" });
|
|
8552
|
-
}
|
|
8553
|
-
}
|
|
8554
|
-
}
|
|
8555
|
-
function appendEnvelope(envelope) {
|
|
8556
|
-
if (envelope.seq > 0) {
|
|
8557
|
-
const key = `${envelope.epoch || envelope.sessionId || "unknown"}:${envelope.seq}`;
|
|
8558
|
-
if (seenTimelineKeys.has(key)) return;
|
|
8559
|
-
seenTimelineKeys.add(key);
|
|
8560
|
-
}
|
|
8561
|
-
syncStateFromEnvelope(envelope);
|
|
8562
|
-
timeline.push(envelope);
|
|
8563
|
-
stream.emit(envelope);
|
|
8564
|
-
}
|
|
8565
|
-
function appendFailure(message) {
|
|
8566
|
-
const item = { type: "turn_failed", turnId: "provider-runtime", error: { message } };
|
|
8567
|
-
const envelope = {
|
|
8568
|
-
sessionId: resolvedSessionId,
|
|
8569
|
-
provider: "flitro",
|
|
8570
|
-
seq: timeline.length + 1,
|
|
8571
|
-
epoch,
|
|
8572
|
-
timestamp: now(),
|
|
8573
|
-
item
|
|
8574
|
-
};
|
|
8575
|
-
appendEnvelope(envelope);
|
|
8576
|
-
}
|
|
8577
|
-
function getDriver() {
|
|
8578
|
-
if (runtimeDriver) return runtimeDriver;
|
|
8579
|
-
runtimeDriver = createFlitroDriver({
|
|
8580
|
-
client,
|
|
8581
|
-
sessionId: resolvedSessionId,
|
|
8582
|
-
model: options.model,
|
|
8583
|
-
skillNames: options.skillNames,
|
|
8584
|
-
mcpServerNames: options.mcpServerNames,
|
|
8585
|
-
approvalPolicy: options.approvalPolicy
|
|
8586
|
-
});
|
|
8587
|
-
return runtimeDriver;
|
|
8588
|
-
}
|
|
8589
|
-
async function sendToFlitro(message, sendOptions) {
|
|
8590
|
-
const driver = getDriver();
|
|
8591
|
-
try {
|
|
8592
|
-
await driver.sendMessage({ message, options: sendOptions }, {
|
|
8593
|
-
append: (item, rawRef) => {
|
|
8594
|
-
const envelope = {
|
|
8595
|
-
sessionId: resolvedSessionId,
|
|
8596
|
-
provider: "flitro",
|
|
8597
|
-
seq: timeline.length + 1,
|
|
8598
|
-
epoch,
|
|
8599
|
-
timestamp: now(),
|
|
8600
|
-
item,
|
|
8601
|
-
rawRef
|
|
8602
|
-
};
|
|
8603
|
-
appendEnvelope(envelope);
|
|
8604
|
-
return envelope;
|
|
8605
|
-
}
|
|
8606
|
-
});
|
|
8607
|
-
} catch (err) {
|
|
8608
|
-
const error = err instanceof Error ? err.message : String(err);
|
|
8609
|
-
dispatch({ type: "error", error });
|
|
8610
|
-
appendFailure(error);
|
|
8611
|
-
throw err;
|
|
8612
|
-
}
|
|
8613
|
-
}
|
|
8614
|
-
async function sendNextPendingMessage() {
|
|
8615
|
-
const next = pendingMessages.shift();
|
|
8616
|
-
if (!next) return;
|
|
8617
|
-
try {
|
|
8618
|
-
await sendToFlitro(next.message, next.options);
|
|
8619
|
-
} catch {
|
|
8620
|
-
}
|
|
8621
|
-
}
|
|
8622
|
-
async function ensureSession() {
|
|
8623
|
-
if (resolvedSessionId) return;
|
|
8624
|
-
const session = await client.createSession({
|
|
8625
|
-
model: options.model,
|
|
8626
|
-
skillNames: options.skillNames,
|
|
8627
|
-
mcpServerNames: options.mcpServerNames
|
|
8628
|
-
});
|
|
8629
|
-
resolvedSessionId = session.session_id;
|
|
8630
|
-
if (!options.epoch) {
|
|
8631
|
-
epoch = `flitro-${resolvedSessionId}`;
|
|
8632
|
-
}
|
|
8633
|
-
connectSse();
|
|
8634
|
-
}
|
|
8635
|
-
function connectSse() {
|
|
8636
|
-
if (!resolvedSessionId || sseStream) return;
|
|
8637
|
-
sseStream = createFlitroTimelineStream({
|
|
8638
|
-
url: client.sessionTimelineUrl(resolvedSessionId),
|
|
8639
|
-
apiKey: options.server.apiKey,
|
|
8640
|
-
tenantId: options.server.tenantId,
|
|
8641
|
-
// Scoped embed tokens rotate; always read the client's current bearer
|
|
8642
|
-
// and propagate refreshed tokens back to it.
|
|
8643
|
-
getBearerToken: () => client.getBearerToken(),
|
|
8644
|
-
onTokenExpired: options.server.onTokenExpired ? async () => {
|
|
8645
|
-
const fresh = await options.server.onTokenExpired?.();
|
|
8646
|
-
if (fresh) client.setToken(fresh);
|
|
8647
|
-
return fresh;
|
|
8648
|
-
} : void 0
|
|
8649
|
-
});
|
|
8650
|
-
sseStream.connect(
|
|
8651
|
-
// The client package types `item` as unknown; the server emits the
|
|
8652
|
-
// canonical Weft envelope, so this is the narrowing point.
|
|
8653
|
-
(envelope) => appendEnvelope(envelope),
|
|
8654
|
-
(_err) => {
|
|
8655
|
-
}
|
|
8656
|
-
);
|
|
8657
|
-
}
|
|
8658
|
-
if (resolvedSessionId) {
|
|
8659
|
-
connectSse();
|
|
8660
|
-
}
|
|
8661
|
-
return {
|
|
8662
|
-
get sessionId() {
|
|
8663
|
-
return resolvedSessionId;
|
|
8664
|
-
},
|
|
8665
|
-
provider: "flitro",
|
|
8666
|
-
runtimeKind: report.selected ?? "app-server",
|
|
8667
|
-
events: stream,
|
|
8668
|
-
commands: {
|
|
8669
|
-
async sendMessage(message, sendOptions) {
|
|
8670
|
-
await ensureSession();
|
|
8671
|
-
const shouldQueue = state.status === "running" || state.status === "waiting_for_permission";
|
|
8672
|
-
dispatch({ type: "send_message", message });
|
|
8673
|
-
if (shouldQueue) {
|
|
8674
|
-
pendingMessages.push({ message, options: sendOptions });
|
|
8675
|
-
return;
|
|
8676
|
-
}
|
|
8677
|
-
await sendToFlitro(message, sendOptions);
|
|
8678
|
-
},
|
|
8679
|
-
async abort(reason) {
|
|
8680
|
-
dispatch({ type: "abort", reason });
|
|
8681
|
-
pendingMessages.length = 0;
|
|
8682
|
-
await runtimeDriver?.abort?.(reason);
|
|
8683
|
-
},
|
|
8684
|
-
async respondToPermission(requestId, allowed, remember) {
|
|
8685
|
-
await getDriver().respondToPermission?.(requestId, allowed, remember);
|
|
8686
|
-
dispatch({ type: "permission_response" });
|
|
8687
|
-
},
|
|
8688
|
-
async resumeTool(runId, resumeData) {
|
|
8689
|
-
await getDriver().resumeTool?.(runId, resumeData);
|
|
8690
|
-
},
|
|
8691
|
-
async dispose() {
|
|
8692
|
-
dispatch({ type: "dispose" });
|
|
8693
|
-
pendingMessages.length = 0;
|
|
8694
|
-
sseStream?.disconnect();
|
|
8695
|
-
sseStream = void 0;
|
|
8696
|
-
await runtimeDriver?.dispose?.();
|
|
8697
|
-
}
|
|
8698
|
-
},
|
|
8699
|
-
async preflight() {
|
|
8700
|
-
dispatch({ type: "preflight_start" });
|
|
8701
|
-
if (!report.selected) {
|
|
8702
|
-
dispatch({ type: "preflight_error", error: report.error ?? "No runtime selected" });
|
|
8703
|
-
} else {
|
|
8704
|
-
dispatch({ type: "preflight_ok" });
|
|
8705
|
-
}
|
|
8706
|
-
const capItem = { type: "runtime_capability_report", report };
|
|
8707
|
-
const capEnvelope = {
|
|
8708
|
-
sessionId: resolvedSessionId,
|
|
8709
|
-
provider: "flitro",
|
|
8710
|
-
seq: timeline.length + 1,
|
|
8711
|
-
epoch,
|
|
8712
|
-
timestamp: now(),
|
|
8713
|
-
item: capItem
|
|
8714
|
-
};
|
|
8715
|
-
appendEnvelope(capEnvelope);
|
|
8716
|
-
return report;
|
|
8717
|
-
},
|
|
8718
|
-
async fetchTimeline(request = {}) {
|
|
8719
|
-
if (request.cursor?.epoch === epoch || !request.cursor) {
|
|
8720
|
-
const localResult = fetchTimeline(timeline, request);
|
|
8721
|
-
if (localResult.items.length > 0) return localResult;
|
|
8722
|
-
}
|
|
8723
|
-
if (resolvedSessionId) {
|
|
8724
|
-
try {
|
|
8725
|
-
const afterSeq = request.cursor?.afterSeq ?? 0;
|
|
8726
|
-
const result = await client.fetchTimeline(resolvedSessionId, afterSeq, request.limit);
|
|
8727
|
-
return {
|
|
8728
|
-
items: result.items,
|
|
8729
|
-
nextCursor: createTimelineCursor({
|
|
8730
|
-
epoch: result.nextCursor.epoch,
|
|
8731
|
-
afterSeq: result.nextCursor.afterSeq
|
|
8732
|
-
}),
|
|
8733
|
-
hasGap: result.hasGap
|
|
8734
|
-
};
|
|
8735
|
-
} catch {
|
|
8736
|
-
}
|
|
8737
|
-
}
|
|
8738
|
-
return {
|
|
8739
|
-
items: [],
|
|
8740
|
-
nextCursor: createTimelineCursor({ epoch, afterSeq: 0 }),
|
|
8741
|
-
hasGap: false
|
|
8742
|
-
};
|
|
8743
|
-
},
|
|
8744
|
-
getState() {
|
|
8745
|
-
return state;
|
|
8746
|
-
}
|
|
8747
|
-
};
|
|
8748
|
-
}
|
|
8749
|
-
function createFlitroEmbedRuntime(options) {
|
|
8750
|
-
return createFlitroProviderRuntime({
|
|
8751
|
-
server: {
|
|
8752
|
-
baseUrl: options.baseUrl,
|
|
8753
|
-
token: options.token,
|
|
8754
|
-
onTokenExpired: options.onTokenExpired
|
|
8755
|
-
},
|
|
8756
|
-
sessionId: options.sessionId,
|
|
8757
|
-
epoch: options.epoch,
|
|
8758
|
-
now: options.now,
|
|
8759
|
-
extensions: options.extensions,
|
|
8760
|
-
candidates: [{ kind: "app-server", available: true }],
|
|
8761
|
-
auth: { mode: "provider-owned", configured: true, source: "flitro-embed" }
|
|
8762
|
-
});
|
|
8763
|
-
}
|
|
8764
|
-
var PushTimelineStream = class {
|
|
8765
|
-
listeners = /* @__PURE__ */ new Set();
|
|
8766
|
-
connect(onEvent, onError, onClose) {
|
|
8767
|
-
this.listeners.add({ onEvent, onError, onClose });
|
|
8768
|
-
}
|
|
8769
|
-
disconnect() {
|
|
8770
|
-
for (const l of this.listeners) l.onClose?.();
|
|
8771
|
-
this.listeners.clear();
|
|
8772
|
-
}
|
|
8773
|
-
isConnected() {
|
|
8774
|
-
return this.listeners.size > 0;
|
|
8775
|
-
}
|
|
8776
|
-
emit(event) {
|
|
8777
|
-
for (const l of this.listeners) l.onEvent(event);
|
|
8778
|
-
}
|
|
8779
|
-
};
|
|
8780
7911
|
|
|
8781
7912
|
// ../packages/react/src/use-agent-session.ts
|
|
8782
7913
|
function useAgentSession(options) {
|
|
8783
|
-
const
|
|
8784
|
-
|
|
8785
|
-
const tokenRef = (0, import_react21.useRef)(options.token);
|
|
8786
|
-
tokenRef.current = options.token;
|
|
7914
|
+
const createRuntimeRef = (0, import_react21.useRef)(options.createRuntime);
|
|
7915
|
+
createRuntimeRef.current = options.createRuntime;
|
|
8787
7916
|
const runtime = (0, import_react21.useMemo)(() => {
|
|
8788
7917
|
return createDeferredAgentRuntime({
|
|
8789
|
-
provider: "
|
|
8790
|
-
runtimeKind: "app-server",
|
|
7918
|
+
provider: options.provider ?? "agent",
|
|
7919
|
+
runtimeKind: options.runtimeKind ?? "app-server",
|
|
8791
7920
|
sessionId: options.sessionId,
|
|
8792
|
-
createRuntime: () =>
|
|
8793
|
-
baseUrl: options.server,
|
|
8794
|
-
token: tokenRef.current,
|
|
8795
|
-
sessionId: options.sessionId,
|
|
8796
|
-
onTokenExpired: () => onTokenExpiredRef.current?.()
|
|
8797
|
-
})
|
|
7921
|
+
createRuntime: () => createRuntimeRef.current()
|
|
8798
7922
|
});
|
|
8799
|
-
}, [options.
|
|
7923
|
+
}, [options.sessionId]);
|
|
8800
7924
|
(0, import_react21.useEffect)(() => {
|
|
8801
7925
|
return () => {
|
|
8802
7926
|
void runtime.disposeIfCreated();
|
|
8803
7927
|
};
|
|
8804
7928
|
}, [runtime]);
|
|
8805
|
-
return { runtime, sessionId: options.sessionId
|
|
7929
|
+
return { runtime, sessionId: options.sessionId };
|
|
8806
7930
|
}
|
|
8807
7931
|
function createDeferredAgentRuntime(options) {
|
|
8808
7932
|
let runtime = null;
|